Skip to content

Instantly share code, notes, and snippets.

@RP-3
Created August 28, 2020 08:36
Show Gist options
  • Save RP-3/04a3c0737d0b66b459c85a454e5518cf to your computer and use it in GitHub Desktop.
Save RP-3/04a3c0737d0b66b459c85a454e5518cf to your computer and use it in GitHub Desktop.
/**
* The rand7() API is already defined for you.
* var rand7 = function() {}
* @return {number} a random integer in the range 1 to 7
*/
/*
IDEA: Make two calls to rand7 to get a value from this table:
(each value is the sum of the two calls to rand7())
1. 2 3. 4. 5. 6. 7.
1. 2 3 4 5 6 7 8
2. 3 4 5 6 7 8 9
3. 4 5 6 7 8 9 10
4. 5 6 7 8 9 10 11
5. 6 7 8 9 10 11 12
6. 7 8 9 10 11 12 13
7. 8 9 10 11 12 13 14
So the values we can get from 2 calls range from 2 - 14, and there
are 49 of them. To get a value between 1-10, we just need 40, so
we'll end up ignoring nine of them.
Let's split the 40 outcomes evenly 10 ways, so that there's a 1/10
chance of getting each outcome.
It doesn't actually matter *how* we do it. Any mapping should
work. Here's the first thing I came up with...
v. n. m. rules
2 1 4 x
3 2 3 x
4 3 4 x
5 4 1 x
6 5 6 and c1 not 5 x
7 6 8 and c1 <= 4 x
8 7 9 and c1 <= 4 x
9 6 10 and <=5
10 5 7 and c1 <= 6 x
11 4 2 x
12 3 5 x
13 2 3 x
14 1 5 x
v = value in the table (2 - 14)
n = number of times it appears in the table
m = mapping. This value maps to this number (1-10)
rules = when this mapping applies. This is important
because some values occur more or less than four times.
If they occur more than four times, you have to discard
some outcomes so that there are only four you're counting.
If they occer less than four times, you need two values to
map to one output so they still have a 4/40 chance of
being selected.
*/
var rand10 = function() {
while(true){
let [c1, c2] = [rand7(), rand7()];
let sum = c1 + c2;
if(sum === 5) return 1;
if(sum === 11) return 2;
if(sum === 3 || sum === 13) return 3;
if(sum === 2 || sum === 4 ) return 4;
if(sum === 12 || sum === 14) return 5;
if(sum === 6 && c1 !== 5) return 6;
if(sum === 10 && c1 !== 6) return 7;
if(sum === 7 && c1 <= 4 ) return 8;
if(sum === 8 && c1 <= 4 ) return 9;
if(sum === 9 && c1 <= 5 ) return 10;
}
};
// three hours, one shower, two glasses of wine
// and a game of scrabble later...
var rand10 = function() {
while(true){
let [c1, c2] = [rand7(), rand7()];
let score = c1 + (c2-1)*7;
if(score <= 40) return 1 + ((score - 1) % 10)
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment