That seems to be a uniform-enough distribution, though I’m a bit less likely to get a 0 or a 9.
My next idea comes from the diehard tests.
Statistician trigger alert! This juxtaposition is painful. The hand-wavy language above e.g. “uniform-enough” and “a bit less likely” is far from statistical reasoning. It would be better if the article at least gave mention to the Chi-Square Goodness-of-Fit Test.
for the ×6 case, for 0..99, any number under 59, if its 59 you will end up getting 5 + 54 = 59, for anything above, they drop back to under-59. I think that is the case for the other 1-orbits, as long as you pick a seed under the period length, it will be fine.
I love that technique. I learned it from this blog post over a decade ago and have used it to some mild success ever since. I tried for a little while to use the alternative method, but computing either x_{i+1} = 101 - \frac{x_i}{2} or x_{i+1} = 50 - \frac{x_i-1}{2} is too much for me to do without pen and paper.
I was once trying to extend this to four-digit numbers to get a much longer period. I think “multiply the last two digits by 30 and add the first two digits” gave an optimal period while being easy to calculate, but I’m not sure. Can someone check it?
This analysis makes me wonder about how the algorithm could be adapted to a d6 outcome and if some of combination of numbers would be easier or better tuned to that output…
Use the original algorithm to generate a two-digit number, then multiply by 6, take the hundreds digit, and add one.
How it works:
We have an okay random number generator from 0-9. It only generates discrete integers, though, and getting an even distribution for 1-6 from only 10 discrete values isn’t going to work well: you can’t evenly map such a small set into 6 without having some numbers get way overrepresented. So, we generate a two-digit number to smooth out the differences and get a more even distribution.
How do we turn 0-99 into a d6? Well, we could do some math (actually, that’s how I first did this), but you end up with annoying fractions and trying to find reasonable approximations etc etc. An easier way to think about this is that if we had a random number generator for 0-599, it would be really easy to map that to d6 rolls! You just take the hundreds digit, add one, and call it a day. We can give ourselves almost a 0-599 generator by generating 0-99 and multiplying by 6: that’s a 0-594 generator. So let’s just treat it as if it’s a 0-599 generator.
The annoying math:
0-99/6 = 16.5, so to get a range of 0-6.0 you’d divide by 16.5; this is a basically-even distribution between 1-6 inclusive if you round up. So, we could generate 0-99 and then divide by 16.5, but wow that’s a much more annoying bit of mental math. Is there anything that approximates it with whole numbers? Well, 10 * 6 / 10 = 16.66… which is as close as you’re going to get with small-ish integers, so if we divide RNG_NUM / 10 * 6 / 10 and round up, we get an approximately-even distribution from 1-6. We can simplify that to RNG_NUM * 6 / 100 and rounding up for less mental math, and dividing an up-to-three-digit number by 100 and rounding up is equivalent to just taking the hundreds digit and adding one.
Ohhh, I got confused by precedence. I saw sum(something, 1) and assumed that “something” was an expression on its own and that sum() had an extra argument for some reason.
Statistician trigger alert! This juxtaposition is painful. The hand-wavy language above e.g. “uniform-enough” and “a bit less likely” is far from statistical reasoning. It would be better if the article at least gave mention to the Chi-Square Goodness-of-Fit Test.
Blog post! Blog post!
it is (tied for) the best possible distribution for a generator with that period.
Now I can win a rock paper scissors tournament, or at least have a chance.
The chance is higher when you use a strategy. https://youtube.com/watch?v=rudzYPHuewc
Very cool!
How do we pick a good seed?
Look at your phone’s clock and use the current minute as the seed (unless it’s 0 or 59).
for the
×6case, for0..99, any number under 59, if its 59 you will end up getting5 + 54 = 59, for anything above, they drop back to under-59. I think that is the case for the other 1-orbits, as long as you pick a seed under the period length, it will be fine.I love that technique. I learned it from this blog post over a decade ago and have used it to some mild success ever since. I tried for a little while to use the alternative method, but computing either
x_{i+1} = 101 - \frac{x_i}{2}orx_{i+1} = 50 - \frac{x_i-1}{2}is too much for me to do without pen and paper.I was once trying to extend this to four-digit numbers to get a much longer period. I think “multiply the last two digits by 30 and add the first two digits” gave an optimal period while being easy to calculate, but I’m not sure. Can someone check it?
From a quick check, you generally get 1498-1500 distinct numbers.
2999, 5998, 8997 all lead to trivial short collapses.
This analysis makes me wonder about how the algorithm could be adapted to a d6 outcome and if some of combination of numbers would be easier or better tuned to that output…
You can just skip the values out of range.
Use the original algorithm to generate a two-digit number, then multiply by 6, take the hundreds digit, and add one.
How it works:
We have an okay random number generator from 0-9. It only generates discrete integers, though, and getting an even distribution for 1-6 from only 10 discrete values isn’t going to work well: you can’t evenly map such a small set into 6 without having some numbers get way overrepresented. So, we generate a two-digit number to smooth out the differences and get a more even distribution.
How do we turn 0-99 into a d6? Well, we could do some math (actually, that’s how I first did this), but you end up with annoying fractions and trying to find reasonable approximations etc etc. An easier way to think about this is that if we had a random number generator for 0-599, it would be really easy to map that to d6 rolls! You just take the hundreds digit, add one, and call it a day. We can give ourselves almost a 0-599 generator by generating 0-99 and multiplying by 6: that’s a 0-594 generator. So let’s just treat it as if it’s a 0-599 generator.
The annoying math:
0-99/6 = 16.5, so to get a range of 0-6.0 you’d divide by 16.5; this is a basically-even distribution between 1-6 inclusive if you round up. So, we could generate 0-99 and then divide by 16.5, but wow that’s a much more annoying bit of mental math. Is there anything that approximates it with whole numbers? Well, 10 * 6 / 10 = 16.66… which is as close as you’re going to get with small-ish integers, so if we divide RNG_NUM / 10 * 6 / 10 and round up, we get an approximately-even distribution from 1-6. We can simplify that to RNG_NUM * 6 / 100 and rounding up for less mental math, and dividing an up-to-three-digit number by 100 and rounding up is equivalent to just taking the hundreds digit and adding one.
Isn’t this “6 times the 10’s digit plus 6 times the units digit”?
The order is a bit confusing, its mod div, not div mod.
Ohhh, I got confused by precedence. I saw
sum(something, 1)and assumed that “something” was an expression on its own and thatsum()had an extra argument for some reason.