Tuesday, February 21, 2012

#mathishard


So my Codeacademy lesson has a Dice Game project, which means random number generation. Apparently the common way to generate random numbers is a function call that returns a random number between 0 (inclusive) and 1(exclusive). . So to get a d6:

// pick a random number between 1 and 6 for our roll of the die
var die = Math.floor(Math.random()*6 + 1);

Random() is returning 0.0000000000000000 to 0.9999999999999999

floor() is rounding down to the nearest integer. And the +1 is so we get 1-6 and not 0-5.

I suppose I don't understand why this gives an even chance to get 1 through 6. I made a list using just one significant digit and got the following distribution. Maybe the short cut is causing an illusion that it is not equally random? Though I would think there would be an equal number for each 16 digit number leading with like 0.0... and 0.1...

0.9 * 6 + 1 = 6.4
0.8 * 6 + 1 = 5.8
0.7 * 6 + 1 = 5.2
0.6 * 6 + 1 = 4.6
0.5 * 6 + 1 = 4
0.4 * 6 + 1 = 3.4
0.3 * 6 + 1 = 2.8
0.2 * 6 + 1 = 2.2
0.1 * 6 + 1 = 1.6
0.0 * 6 + 1 = 1

If I numbered a 10 sided die like that, I would expect to see more 5's, 4's, 2's and 1's over 6 and 3, right?

It is 2am at the moment, maybe it will make sense tomorrow.

**update realized I could just run a series in javascript. For a series of 100,000 rolls I am getting results like:
Total 1's = 16749
Total 2's = 16493
Total 3's = 16829
Total 4's = 16599
Total 5's = 16574
Total 6's = 16756

So had some late night confusion. Code below:

//loop to gather some data

// var die = Math.floor(Math.random()*6 + 1);
// that gives 1-6, remove the +1 for 0-5,
// our array positions

var diceArray = [0,0,0,0,0,0];
for (i = 1; i <= 100000; i++) {
    var die = Math.floor(Math.random()*6);
    diceArray[die] = diceArray[die] +1;
}
//print results
for (i = 0; i < 6; i++) {
    var dieFace = i +1;
    console.log("Total " + dieFace + "'s = " + diceArray[i]);
}
// Yes they really add up to 100,000
console.log(diceArray[0] + diceArray[1] + diceArray[2] + diceArray[3] + diceArray[4] + diceArray[5] );
console.log("=================");

** edit #2
After some thought and discussion today I realized my error was assuming I could abstract the float using those 10 cases. They were like 10 slits into the entire range of results, and if I picked 10 points using say two digits I could have gotten a different set of results that also would have appeared lumpy in distribution.

I think the good part of this late night exploration into random() was I was wondering about the results, created a model that didn't match line up with what was supposed to happen, then went and gathered some empirical data. From that data I went back and talked to some programmer friends until I understood how I got confused in the first place.