Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - import java.io.IOException;
 - import java.nio.file.Files;
 - import java.nio.file.Path;
 - import java.nio.file.Paths;
 - import java.nio.file.StandardOpenOption;
 - import java.text.SimpleDateFormat;
 - import java.util.Date;
 - import java.util.Map;
 - import java.util.Random;
 - import java.util.TreeMap;
 - /**
 - * <p>
 - * Endlessly flip a coin and report on how long it took to get the same result
 - * 10, 20, 30, 40 etc times in a row.
 - * </p>
 - *
 - * <p>
 - * Compiled and run in JDK 7.
 - * </p>
 - *
 - * <p>
 - * Discuss this code:
 - * http://robertmarkbramprogrammer.blogspot.com.au/2014/09/flip
 - * -and-coin-and-get-same-results-100.html or http://bit.ly/1p1zRtM.
 - * </p>
 - *
 - * <p>
 - * See this code in pastebin: http://pastebin.com/7PAGyQcU.
 - * </p>
 - *
 - * <p>
 - * See results so far from one continuous run: http://pastebin.com/MG50TYED.
 - * </p>
 - *
 - * <p>
 - * Updates.
 - * </p>
 - * <ol>
 - * <li>Tuesday 09 September 2014, 12:33:53 PM. Replaced ints with longs for
 - * numbers that are getting long. Allow path to be set for where to write log.
 - * Changed time format.</li>
 - * <li>Wednesday 10 September 2014, 04:31:31 PM. Added a bit more time
 - * information when reporting new counts.</li>
 - * </ol>
 - *
 - * @author Robert Mark Bram
 - */
 - public final class RandomInARow implements Runnable {
 - /** File we write the log to. */
 - private Path file;
 - /** Where to put logs. */
 - private String pathToLogs = "";
 - /** Time we started this run. */
 - private long start;
 - /** How many milliseconds in a second. */
 - final static int TIME_MILLISECONDS_IN_A_SECOND = 1000;
 - /** How many milliseconds in a minute. */
 - final static int TIME_SECONDS_IN_A_MINUTE = TIME_MILLISECONDS_IN_A_SECOND * 60;
 - /** How many milliseconds in an hour. */
 - final static int TIME_MINUTES_IN_AN_HOUR = TIME_SECONDS_IN_A_MINUTE * 60;
 - /** How many milliseconds in a day. */
 - final static int TIME_HOURS_IN_A_DAY = TIME_MINUTES_IN_AN_HOUR * 24;
 - /** Timestamp format for the log when I wish to report on events. */
 - public static final ThreadLocal<SimpleDateFormat> FORMAT_TIMESTAMP = new ThreadLocal<SimpleDateFormat>() {
 - @Override
 - protected synchronized SimpleDateFormat initialValue() {
 - return new SimpleDateFormat("dd MMM yyyy, hh:mm:ss.SSS a");
 - }
 - };
 - /** Timestamp format for the log file name. */
 - public static final ThreadLocal<SimpleDateFormat> FORMAT_FILE = new ThreadLocal<SimpleDateFormat>() {
 - @Override
 - protected synchronized SimpleDateFormat initialValue() {
 - return new SimpleDateFormat("yyyyMMddHHmmssSSS");
 - }
 - };
 - /**
 - * Run the simulation.
 - *
 - * @param args
 - * 0 - path to put logs file, can be null/empty.
 - */
 - public static void main(String[] args) {
 - String path = null;
 - if (args.length > 0) {
 - path = args[0];
 - }
 - new RandomInARow(path).run();
 - }
 - /**
 - * @param thePathToLogs
 - * - where to store logs. May be null or empty.
 - */
 - public RandomInARow(final String thePathToLogs) {
 - if (thePathToLogs != null && thePathToLogs.length() > 0) {
 - pathToLogs = thePathToLogs;
 - }
 - }
 - /* Endlessly run the simulation, starting at 10 tosses in a row and
 - * incrementing by 10 each time. */
 - public void run() {
 - int target = 10;
 - while (true) {
 - repeatUntilWeGetCount(target);
 - target += 10;
 - }
 - }
 - /**
 - * @param target
 - * keep going until we get this number of repetitions of the same
 - * flip result
 - */
 - public void repeatUntilWeGetCount(final int target) {
 - start = reportPhase(true);
 - final TreeMap<Integer, Long> counts = new TreeMap<Integer, Long>();
 - final Random random = new Random();
 - while (true) {
 - rememberCountOfContiguousOccurences(random, counts);
 - if (counts.lastKey() >= target) {
 - break;
 - }
 - }
 - long finish = reportPhase(false);
 - message("-----\nIt took " + reportTime(finish - start) + " to get ["
 - + target + "] results in a row.\n");
 - outputResult(counts);
 - }
 - /**
 - * Return a string such as
 - * "hours, [0], minutes [0], seconds [0], milliseconds [59]" based on a
 - * millisecond timestamp.
 - *
 - * @param millisecondsTotal
 - * milliseconds taken to perform task
 - * @return stringing saying how many hours, minutes, seconds and
 - * milliseconds were taken by <code>millisecondsTotal</code>
 - */
 - private String reportTime(final long millisecondsTotal) {
 - long left = 0;
 - // Milliseconds.
 - long milliseconds = millisecondsTotal % TIME_MILLISECONDS_IN_A_SECOND;
 - left = millisecondsTotal - milliseconds;
 - // Seconds.
 - long seconds = (left % TIME_SECONDS_IN_A_MINUTE)
 - / TIME_MILLISECONDS_IN_A_SECOND;
 - left = left - (TIME_MILLISECONDS_IN_A_SECOND * seconds);
 - // Minutes.
 - long minutes = (left % TIME_MINUTES_IN_AN_HOUR)
 - / TIME_SECONDS_IN_A_MINUTE;
 - left = left - (TIME_SECONDS_IN_A_MINUTE * minutes);
 - // Hours.
 - long hours = (left % TIME_HOURS_IN_A_DAY) / TIME_MINUTES_IN_AN_HOUR;
 - left = left - (TIME_MINUTES_IN_AN_HOUR * hours);
 - // Days
 - long days = left / TIME_HOURS_IN_A_DAY;
 - left = left - (TIME_HOURS_IN_A_DAY * days);
 - // Formulate time string.
 - StringBuilder sb = new StringBuilder();
 - if (days > 0) {
 - sb.append(days).append(" days, ");
 - }
 - if (hours > 0 || days > 0) {
 - sb.append(hours).append(" hours, ");
 - }
 - if (minutes > 0 || hours > 0 || days > 0) {
 - sb.append(minutes).append(" minutes, ");
 - }
 - if (seconds > 0 || minutes > 0 || hours > 0 || days > 0) {
 - sb.append(seconds).append(" seconds and ");
 - }
 - sb.append(milliseconds).append(" milliseconds");
 - return sb.toString();
 - }
 - /**
 - * Report start or finish.
 - *
 - * @param start
 - * true if this is reporting the start, false to report the end
 - * @return new Date().getTime() - millsecond time stamp.
 - */
 - private long reportPhase(final boolean start) {
 - Date date = new Date();
 - long millis = date.getTime();
 - String prefix = start ? "\nStarted" : "Finished";
 - String suffix = start ? "\n" : "\n";
 - message(prefix + " at [" + FORMAT_TIMESTAMP.get().format(date) + "]"
 - + suffix);
 - return millis;
 - }
 - /**
 - * Output results.
 - *
 - * @param counts
 - * map of (count, occurrences of count). Count = number of times
 - * we got same result in a row. Occurrences of count = number of
 - * times we kept flipping and got that count.
 - */
 - private void outputResult(final Map<Integer, Long> counts) {
 - for (Integer count : counts.keySet()) {
 - message(String.format("How often we flipped the same result [%4d] "
 - + "times in a row: %d.\n", count, counts.get(count)));
 - }
 - }
 - /**
 - * Flip a coin and count how many times we got the same result. Increment
 - * the count for that number.
 - *
 - * @param random
 - * random number generator
 - * @param counts
 - * map of (count, occurrences of count). Count = number of times
 - * we got same result in a row. Occurrences of count = number of
 - * times we kept flipping and got that count.
 - */
 - private void rememberCountOfContiguousOccurences(final Random random,
 - final Map<Integer, Long> counts) {
 - Integer count = countContiguousOccurences(random);
 - if (counts.containsKey(count)) {
 - Long countOccurences = counts.get(count);
 - countOccurences++;
 - counts.put(count, countOccurences);
 - } else {
 - counts.put(count, 1l);
 - Date currentTime = new Date();
 - message(String.format("New count [%3d] at [" //
 - + FORMAT_TIMESTAMP.get().format(currentTime)
 - + "] after %s.\n", count, reportTime(currentTime.getTime()
 - - start)));
 - }
 - }
 - /**
 - * Flip a coin repeatedly until we get a different result to the first toss
 - *
 - * @param random
 - * random number generator
 - * @return number of times we tossed and got the same result
 - */
 - private int countContiguousOccurences(final Random random) {
 - int count = 1;
 - final int first = random.nextInt(2);
 - while (random.nextInt(2) == first) {
 - count++;
 - }
 - return count;
 - }
 - /**
 - * Output message to file and standard out.
 - *
 - * @param message
 - * message to output
 - * @throws IOException
 - * if there is a problem writing to log
 - */
 - private void message(final String message) {
 - if (file == null) {
 - file = Paths.get(pathToLogs,
 - "results_" + FORMAT_FILE.get().format(new Date()) + ".txt");
 - }
 - System.out.print(message);
 - try {
 - Files.write(file, message.getBytes(), StandardOpenOption.CREATE,
 - StandardOpenOption.APPEND);
 - } catch (IOException ioe) {
 - System.err.println("Failed to write message [" + message + "].");
 - throw new RuntimeException(ioe);
 - }
 - }
 - }
 
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment