Programming and Computer Science in Java:
Homework #10:  Random Numbers
    David Kosbie, 2002-2003
See Course Home Page

Due Date:  Fri, Mar 21, 2003

For each of the following questions, anything which your programs compute must be computed within a new method, and not directly inside your main method.

Topic:  Random Numbers

The following code demonstrates how to generate random integers or doubles in the ranges [0,hi] or [lo,hi]:

class RandomsDemo
{
	// This method returns a random *double* in [0,hi]
	public static double random(double hi)
	{
		return hi * Math.random();
	}
	
	// This method returns a random *integer* in [0,hi]
	public static int random(int hi)
	{
		return ((int)((hi+1)*Math.random()) % (hi+1));
	}
	
	// This method returns a random *double* in [lo,hi]
	public static double random(double lo, double hi)
	{
		double range = hi - lo;
		return lo + random(range);
	}
	// This method returns a random *integer* in [lo,hi]
	public static int random(int lo, int hi)
	{
		int range = hi - lo;
		return lo + random(range);
	}
	
	// test the integer randoms
	public static void testRandomIntegers()
	{
		int i, intLo, intHi;
		System.out.println("**********************");
		System.out.println("Testing Random Integers");
		System.out.println();
		while (true)
		{
			System.out.print("Enter integers for lo and hi [0's to quit]: ");
			intLo = readInt();
			intHi = readInt();
			if ((intLo == 0) && (intHi == 0))
				break;
			System.out.println("Here are 20 randoms in [" + intLo + "," + intHi + "]:");
			for (i=0;i<20;i++)
			{
				System.out.print(random(intLo,intHi) + "  ");
				// add a newline every third number printed out
				if (i % 3 == 2)
					System.out.println();
			}
			System.out.println();
			System.out.println("Here are 20 randoms in [0," + Math.abs(intHi) + "]:");
			for (i=0;i<20;i++)
			{
				System.out.print(random(Math.abs(intHi)) + "  ");
				// add a newline every third number printed out
				if (i % 3 == 2)
					System.out.println();
			}
			System.out.println();
		}
	}
	// test the double randoms
	public static void testRandomDoubles()
	{
		int i;
		double doubleLo, doubleHi;
		System.out.println("**********************");
		System.out.println("Testing Random Doubles");
		System.out.println();
		while (true)
		{
			System.out.print("Enter doubles for lo and hi [0's to quit]: ");
			doubleLo = readDouble();
			doubleHi = readDouble();
			if ((doubleLo == 0) && (doubleHi == 0))
				break;
			System.out.println("Here are 20 randoms in [" + doubleLo + "," + doubleHi + "]:");
			for (i=0;i<20;i++)
			{
				System.out.print(random(doubleLo,doubleHi) + "  ");
				// add a newline every third number printed out
				if (i % 3 == 2)
					System.out.println();
			}
			System.out.println();
			System.out.println("Here are 20 randoms in [0," + Math.abs(doubleHi) + "]:");
			for (i=0;i<20;i++)
			{
				System.out.print(random(Math.abs(doubleHi)) + "  ");
				// add a newline every third number printed out
				if (i % 3 == 2)
					System.out.println();
			}
			System.out.println();
		}
	}
	public static void main(String[] args)
	{
		testRandomIntegers();
		testRandomDoubles();
	}
    // readString(), readInt(), and readDouble()
}

What you must understand here:

  1. Math.random() returns a random double in [0.0,1.0].
  2. We can have several methods all named random but with different signatures -- in particular, with different parameters.  This is called overloading.  This is covered in the book in section 5.4 which is coincidentally on page 54 (please go read it now!).
  3. You can use Math.random() to return a double in [0.0,hi].
  4. Returning an integer in [0,hi] is more complicated, because you have to make sure that "hi" is just as likely as the other values in that range.  To do this, we extend the range to "hi+1", but then we have the very tiny chance that we will in fact return "hi+1" as our result.  Thus, we take that value mod (hi+1), thus guaranteeing a result in [0,hi].  Be sure you understand this point very clearly!
  5. You can also use that method -- double random(double hi) -- to return a double in [lo,hi], by using a "range" variable.
  6. You can do the same for integers, using the integer method -- int random(int  hi) -- to return an integer in [lo,hi], also by using a "range" variable.
  7. You now have all you need to return integers or doubles in a range [lo,hi].
  8. You now can attack so-called "Monte Carlo" problems, which use random numbers and approximations to solve very real and non-random problems.  Wahoo!!!

Problems:  Random Numbers

Question 1:  Simple Coin Flips
Write a Java program which reads in a positive integer n and prints out the result of n coin flips (as a series of H or T characters).  To do this, write a method with the following signature:
     public static boolean coinFlip()
This method returns true if the flip is a heads, and false if it is a tails.

Question 2:  Equal numbers of Heads and Tails
Write a Java program which reads in a positive integer n flips a coin n times, counting the number of heads and tails which occur.  Print out the result, as well as the ratio of heads/tails.  We would expect this ratio to be very near 1, and the larger n is, the closer the result would be to 1.

Question 3:  Longest runs
Write a Java program which reads in a positive integer n and prints out the result of each of n coin flips (as a series of H or T characters) (as in Question 1).  Here, though, print out the length of the longest runs of heads and tails afterwards.  So, if your output were HHTTTHTHHHHTT, you would output that the longest run of heads was 4 and the longest run of tails was 3. 

Question 4:  How likely is a run 4 or more Heads?
Write a Java program which uses Monte Carlo techniques to determine how likely it is to have a run of  4 or more Heads when flipping a coin 20 times.  To do this, you must run the whole experiment (flipping a coin 20 times) many times, say 100k times (thus, there would be 2 million total coin flips), keeping a count of how many times the conjecture was true (that is, that there was a run of 4 or more heads in the 20 flips).  The odds, then, are the successful experiments divided by the total number of experiments, multiplied by 100 to give a percentage.

Question 5:  Simple Roll of the Die
Write a Java program which reads in a positive integer n and prints out the result of n rolls of a 6-sided die (as a series of numbers from 1 to 6).  To do this, write a method with the following signature:
     public static int rollDie()
This method returns the result of rolling a 6-sided die one time.

Question 6:  Odds of different rolls
Write a Java program which prints out the odds of different results when rolling two dice, where the result is the sum of the two dice.  To do this, run a counter from 2 to 12 (the range of possible outcomes), and for each value, you must run 100k experiments rolling two dice and verifying whether the outcome equals the current value of the counter.  Print a table of odds as you go (first column is the sum of the dice, second column is the odds of getting that sum).
Note:  it seems inefficient to require new experiments for each new value of the counter, right?  Yes!  But in order to use a single experiment for multiple values of the counter, we need to use arrays, which we've not yet covered.  Soon, soon.... 

Good luck!

DK


See Course Home Page