Pepys.java


Below is the syntax highlighted version of Pepys.java from §1.3 Conditionals and Loops.


/******************************************************************************
 *  Compilation:  javac Pepys.java
 *  Execution:    java Pepys k trials
 *  
 *  Which is more likely: at least one 1 in 6 rolls of a fair die,
 *  or at least two 1s in 12 rolls of a fair die?
 *
 *  This program takes two integer command-line arguments k and trials,
 *  and repeats the following experiment trials times:
 *      - roll 6k dice
 *      - count number of 1s
 *      - success = at least k 1s
 *
 *  % java Pepys 1 10000000
 *  0.6651856
 *
 *  % java Pepys 2 10000000
 *  0.6186818
 *
 *  % java Pepys 1000 100000
 *  0.50647
 *
 *  The exact answer is 1 - (5/6)^6 = 31031/46656 for k = 1,
 *  1346704211/2176782336 for k = 2, and
 *  1/2 as k approaches infinity.
 *
 *  Reference: https://en.wikipedia.org/wiki/Newton–Pepys_problem
 *
 *  Use for live coding.
 *    - forget to type command line arguments
 *    - to start: do experiment assuming k = 1
 *    - declare and initialize ones outside loop
 *      (so that it never gets reset to 0)
 *    - Put in extra ; after if statement.
 *    - Integer division (r < 1/6)
 *    - Insert System.out.println() in loop for debugging
 *    - forget to recompile
 *    - add command-line argument k (but use Integer.parseInt(args[0]) again)
 *    - named constant for number of sides of dice
 *    - forget curly braces around outer for loop
 *
 ******************************************************************************/

public class Pepys { 
    public static void main(String[] args) {
        int SIDES = 6;    // number of sides on a die

        // roll a fair die 6k times, seeking k 6s
        int k = Integer.parseInt(args[0]);

        // number of times to repeat each experiment
        int trials = Integer.parseInt(args[1]);

        // repeat experiment and count successes
        int count = 0;
        for (int t = 1; t <= trials; t++) {

            // number of 1s in 6k rolls
            int ones = 0;
            for (int i = 0; i < k * SIDES; i++) {
                double r = Math.random();
                if (r < 1.0 / SIDES)
                    ones++;
            }
            if (ones >= k) count++;
        }

        // print fraction of successes
        System.out.println(1.0 * count / trials);
    }

}


Copyright © 2000–2017, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Oct 20 14:12:12 EDT 2017.