(11C) Roll "Four" Dice at Random

10132018, 03:32 AM
(This post was last modified: 10182019 01:29 AM by Gamo.)
Post: #1




(11C) Roll "Four" Dice at Random
Roll 4 dice at random program without using any store registers.
Procedure: f [USER] FIX 0 [D] display face 1st dice > 2nd dice > 3th dice > 4th dice and display Total Code:
Gamo 

10132018, 10:21 AM
(This post was last modified: 10142018 03:43 AM by Gamo.)
Post: #2




RE: (11C) Roll "Four" Dice at Random
This version used [LBL] D to identify both the beginning of the program and
subroutine within the program. So I adapted this program from the "Subroutines Section" on Page 125 of the HP11C Owner's Handbook. In the handbook state that *While it is generally best to avoid the use of identical labels to reduce the possibility of confusion or programming error, the following program illustrates one way identical labels might be used, if necessary. Procedure: f [USER] FIX 0 [D] display face 1st Dice > 2nd > 3th > 4th and display Total Program: Roll 4 Dice at Random Code:
Gamo 

10132018, 09:43 PM
Post: #3




RE: (11C) Roll "Four" Dice at Random
(10132018 10:21 AM)Gamo Wrote: Program: Roll 4 Dice at Random You can delete the 3 steps I highlighted in red in your code above, the first two because the second LBL D is right after them so merely falling through will achieve the same effect, and the third one because addition ("'+") is conmutative so no need to swap the two numbers being added. V. . Find All My HPrelated Materials here: Valentin Albillo's HP Collection 

10142018, 03:48 AM
Post: #4




RE: (11C) Roll "Four" Dice at Random
Thanks Valentin
Now updated. Gamo 

10142018, 05:37 AM
Post: #5




RE: (11C) Roll "Four" Dice at Random
This version cheat a bit
by using Direct Exchange Storage Register as a Counter. Code:
Gamo 

10142018, 09:55 PM
Post: #6




RE: (11C) Roll "Four" Dice at Random
(10142018 05:37 AM)Gamo Wrote: This version cheat a bit This will only work if register I happens to be zero on program start. Otherwise its value is added to the result. Try it: 777 STO I, then run the program. Also the RCL I and R↑ are no required. Just do it as simple as can be: Code: LBL D Dieter 

10152018, 07:48 AM
Post: #7




RE: (11C) Roll "Four" Dice at Random
(10142018 09:55 PM)Dieter Wrote: Also the RCL I and R↑ are no required. Just do it as simple as can be: If only the sum of the dice is needed we can follow your suggestion from an older post: (05022018 08:03 PM)Dieter Wrote: I just noticed you can save even two more steps if you remove both the CLX and the RCL+1. ;) Code: LBL D However if you want to use RAN# only once as suggested by (05022018 05:06 AM)Joe Horn Wrote: THE QUESTION: Is there a direct way to return the sum of a roll of N dice without generating N random numbers and adding them together? … you can use this translation of my program for the HP42S: Code: 001▸LBL D Just be aware that you have to enter the number of dice (here 4) prior to running the program: 4 GSB D Cheers Thomas 

10152018, 04:29 PM
(This post was last modified: 10152018 06:16 PM by Albert Chan.)
Post: #8




RE: (11C) Roll "Four" Dice at Random
If tried to pull multiple dice rolls from a single RAN#, the bias might be too high.
For example, my Casio RAN# can produce between 0.000 to 0.999 (hopefully, unbiased) For 1 dice roll, dice distribution = 167 + 167 + 166 + 167 + 167 + 166 (3 or 6 is less likely) Ideally, we wanted even distribution, but 167/166 = 1.006 may be good enough. For 3 dice rolls, dice distribution = 80*4 + 136*5. 5/4 = 1.25 is unacceptably bad. To produce unbiased multiple dice roll, remove random below a threshold. For my casio, remove RAN# below 0.136 should do it. >>> total = 1000 # Casio RAN# 0.000 to 0.999 >>> dice3 = 6**3 # treble dice rolls >>> unbiased = [ i % dice3 for i in range(total % dice3, total) ] >>> [ unbiased.count(i) for i in range(dice3) ] [4, 4, 4, 4, 4 ... ] 

10152018, 06:33 PM
Post: #9




RE: (11C) Roll "Four" Dice at Random
(10152018 04:29 PM)Albert Chan Wrote: For 3 dice rolls, dice distribution = 80*4 + 136*5. 5/4 = 1.25 is unacceptably bad. How did you come up with this distribution? Because I get the following result: >>> dice_dist(1000, 1) {0: 167, 1: 167, 2: 166, 3: 167, 4: 167, 5: 166} >>> dice_dist(1000, 2) {0: 335, 1: 333, 2: 332, 3: 335, 4: 333, 5: 332} >>> dice_dist(1000, 3) {0: 503, 1: 501, 2: 496, 3: 503, 4: 501, 5: 496} While this isn't an exact equal distribution I wouldn't say it's biased. However when we roll more dice the imbalance increases: >>> dice_dist(1000, 4) {0: 671, 1: 669, 2: 664, 3: 671, 4: 669, 5: 656} >>> dice_dist(1000, 5) {0: 839, 1: 837, 2: 832, 3: 839, 4: 837, 5: 816} >>> dice_dist(1000, 6) {0: 1007, 1: 1005, 2: 1000, 3: 1007, 4: 1005, 5: 976} This is not a big surprise. There are now gaps between consecutive numbers and thus some of the values aren't hit as last digit. Thus as a rule of thumb we should use it only if \(6^k < n\). Therefore \(6^3 = 216 < 1000\) is still okay while \(6^4 = 1296 > 1000\) starts getting problematic. This is the Python function I used to calculate the distribution of the dice: Code: def base6(n, k): Quote:To produce unbiased multiple dice roll, remove random below a threshold. That means 0 (i.e. [1, 1, 1]) can never happen? How is that not biased? Kind regards Thomas 

10162018, 12:17 AM
Post: #10




RE: (11C) Roll "Four" Dice at Random
(10152018 06:33 PM)Thomas Klemm Wrote:(10152018 04:29 PM)Albert Chan Wrote: For 3 dice rolls, dice distribution = 80*4 + 136*5. 5/4 = 1.25 is unacceptably bad. My mistake. I was assuming a dice with 216 faces. When the numbers are split back into 3 dice rolls, the distribution is not as bad. 1000 = 216 * 4 + 136 = (216136) * 4 + 136*5 = 80*4 + 136*5 Doing sum of 3 dice rolls in Mathematica (again, assume RAN# = 0.000 to 0.999): Code: dice3[n_] := 3 + Plus @@ IntegerDigits[Mod[n, 216], 6] ratio = {1.08, 1.08, 1.08, 1.08, 1.07, 1.05, 1.04, 1.03, 1., 0.98, 0.96, 0.92, 0.89, 0.86, 0.86, 0.86} Biased distribution is skew to the small side, as expected. Also, roll sum of 16,17,18 is much less likely ... So, bet small Quote:That means 0 (i.e. [1, 1, 1]) can never happen? To get random integers from RAN#, I do not use INT(216 RAN#); I use (1000 RAN#) % 216 instead. If generated random range is divisible by 216, all are equally likely. That was the reason to drop 1000 % 216 = 136 small cases. Had I done above biased simulation with INT(216 RAN#), distribution is better (relative to unbiased) It seems INT(...) produce enough randomness to compensate ... ratio = {1.08, 1.08, 0.97, 0.95, 1.07, 0.99, 0.97, 1.03, 1.02, 0.97, 1.00, 1.05, 0.93, 0.97, 1.08, 0.86} 

10162018, 08:37 AM
Post: #11




RE: (11C) Roll "Four" Dice at Random
(10152018 07:48 AM)Thomas Klemm Wrote: However if you want to use RAN# only once (…) you can use this translation of my program for the HP42SIt turns out that multiplying the random number by 6^{4} and then translating the integer part to base 6 is the same as multiplying it continuously by 6, chopping off the integer part and continue with the remainder. Thus just forget about that program and use this instead: Code: 001▸LBL D But then it's slightly longer and a bit biased so rather don't use it at all. Cheers Thomas 

10162018, 04:20 PM
(This post was last modified: 10162018 06:13 PM by Albert Chan.)
Post: #12




RE: (11C) Roll "Four" Dice at Random
(10152018 06:33 PM)Thomas Klemm Wrote: >>> dice_dist(1000, 1) I noticed that for decimal random numbers, (i.e n = 10^k, k positive), dice of 3 and 6 is biased down. (assumed generated dice = INT(6 RAN#) + 1, so below 0 meant dice face of 1) >>> dice_dist(10000, 1) {0: 1667, 1: 1667, 2: 1666, 3: 1667, 4: 1667, 5: 1666} >>> dice_dist(100000, 1) {0: 16667, 1: 16667, 2: 16666, 3: 16667, 4: 16667, 5: 16666} >>> dice_dist(1000000, 1) {0: 166667, 1: 166667, 2: 166666, 3: 166667, 4: 166667, 5: 166666} Is this always true ? (10162018 08:37 AM)Thomas Klemm Wrote: It turns out that multiplying the random number by 6^{4} and then translating the integer part to base 6 is the same as Comparing against unbiased distribution, I was unable to measure a bias difference. This is my reference unbiased distribution (first number for sum of 4, last for 24) unbiased = [ 1 4 10 20 35 56 80 104 125 140 146 140 125 104 80 56 35 20 10 4 1 ] this pattern look familiar ... Update: above match coefficient of expanded (x^5 + x^4 + x^3 + x^2 + x + 1)^4 

10162018, 09:17 PM
(This post was last modified: 10172018 09:38 PM by Albert Chan.)
Post: #13




RE: (11C) Roll "Four" Dice at Random
Prove: For RAN# = 0, 1/10^n, 2/10^n, ... (10^n1)/10^n, evenly distributed,
and Dice = INT(6 RAN#) + 1, then dice face 3,6 will appear slightly less often. 10^n  1 sum of digits = 0, thus divisible by 9, thus divisible by 3 10^n  1 is odd => 10^n  1 (mod 6) = 3, so 10^n = 6 k + 4 = 6(k + 2/3), for some integer k Below, use Python definition of range(a,b), i.e. a <= integer value < b: Dice face 1: range(0, k+2/3) = range(0, k+1), total k+1 cases Dice face 2: range(k+1, 2k+4/3) = range(k+1, 2k+2), total k+1 cases Dice face 3: range(2k+2, 3k+6/3) = range(2k+2, 3k+2), total k cases Dice face 4: range(3k+2, 4k+8/3) = range(3k+2, 4k+3), total k+1 cases Dice face 5: range(4k+3, 5k+10/3) = range(4k+3, 5k+4), total k+1 cases Dice face 6: range(5k+4, 6k+12/3) = range(5k+4, 6k+4), total k cases QED Edit: above assumed calculation had enough precision to avoid rounding issue. If calculation is also carried to n digits precision, dice face 2,4 will appear less often. Upper range limit reduced a bit due to possible halfroundup Dice face 1: range(0, k+2/30.5/6) = range(0, k+1), total k+1 cases Dice face 2: range(k+1, 2k+4/35/6) = range(k+1, 2k+1), total k cases Dice face 3: range(2k+1, 3k+6/35/6) = range(2k+1, 3k+2), total k+1 cases Dice face 4: range(3k+2, 4k+8/35/6) = range(3k+2, 4k+2), total k cases Dice face 5: range(4k+2, 5k+10/35/6) = range(4k+2, 5k+3), total k+1 cases Dice face 6: range(5k+3, 6k+12/35/6) = range(5k+3, 6k+4), total k+1 cases Example, k=166, (2k+1)/(6k+4) = 0.333, 0.333 * 6 = 1.998, roundedup to 2.00 (dice face 3) 

« Next Oldest  Next Newest »

User(s) browsing this thread: 1 Guest(s)