3 ms·
I've never heard of this method before! That's a _really_ nifty trick, thanks for putting it here!
by mhink 9y ago
I've never heard of this method before! That's a _really_ nifty trick, thanks for putting it here!
- tzs 9y agoHere's another approach you might enjoy. We wish to simulate a dN with a dM. I'll use simulating a d10 (N=10) with a d6 (M=6). 1. let L = a common multiple of N and M. The least common multiple of N and M is a good choice here, so for our example we'll use L = 30. 2. Make a list of the values you are trying to choose from. Repeat each value L/N times, so that the length of the list is L. For our example, L is 30, N is 10, and L/N is three, so our list consists of the values 1 through 10 each repeated 3 times: [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10]. 3. Viewing this list as M chunks of length L/M, select one of the chunks at random via a roll of our dM. For our example that is 6 chunks of length 5. Here is the list again with parenthesis drawn around the 6 chunks: [(1 1 1 2 2) (2 3 3 3 4) (4 4 5 5 5) (6 6 6 7 7) (7 8 8 8 9) (9 9 10 10 10)] 4. Take the chunk selected by the roll of the dM. If all L/M numbers in the chunk are the same, that is the value of our simulated dN roll and we are done. Let's say we've picked the second chunk, (2 3 3 3 4). That contains more than one distinct value, so we go on to step #5. 5. Replace the list with the items from that chunk, each repeated M times. In our example, our new list is [2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4]. 6. Go to step #3. Note that the second time through this is how we chunk the list: [(2 2 2 2 2) (2 3 3 3 3) (3 3 3 3 3) (3 3 3 3 3) (3 3 3 3 4) (4 4 4 4 4)]. 4 of the 6 chunks contain only one distinct value now, so there is a 2/3 chance that we find our d10 value on the second iteration. If you actually implement this, you don't need to actually make the lists like I did above. You just need a count of how many times each thing appears. So instead of [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10] you would have [3 3 3 3 3 3 3 3 3 3], meaning you have three '1', three '2', and so on. To pick the second chunk, you skip 5 items and then take 5. That means we skip all 3 '1's, and 2 of the '2's, and take 1 '2', then all 3 '3's, and 1 '4'. That gives us [0 1 3 1 0 0 0 0 0 0]. BTW, note that this also works for simulating a smaller die with a larger die. For example, simulating a d6 with a d10. There is a really simple way to do that, of course: roll the d10 and discard anything above 6. With that method, you get a d6 output on 6 out of 10 rolls. Let's call this method the trivial method. If we use the list method as described above, we get a higher output rate. Here is a little table: 1 1 1 (1) 1 1 2 111 111 111 111 111 111 112 222 222 222 2 2 2 (2) 2 3 3 222 222 222 233 333 333 333 333 333 333 3 3 3 (3) 4 4 4 (4) 4 4 5 444 444 444 444 444 444 445 555 555 555 5 5 5 (5) 5 6 6 555 555 555 566 666 666 666 666 666 666 6 6 6 (6) On the left, the first 3 columns just show the initial [1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6] list (N distinct values each repeated L/N times) broken down into groups of L/M, which is 3 in this case. If our d10 roll is 1, 3, 5, 6, 8, or 10 we count that as a successful d6 roll of 1, 2, 3, 4, 5, or 6, respectively, because those chunks all have only one distinct value. I've marked those in the table with the resulting d6 value in parenthesis. So, on the first d10 roll we get a d6 value 6 out of 10 times, just like with the trivial method. Where we beat it is on the next roll. For each chunk that does not yield a d6 value on the first row, I've added the resulting list, grouped into chunks. Note that in all 4 of the possible lists, 9 out of the 10 chunks have only one distinct value, and so 9 out of 10 times the second roll yields a d6 value. If the second roll fails too, the trivial method will again only succeed 6/10 times on the third roll. Again we beat it, with a 9/10 success rate, and so on.