Seven-sided dice from five-sided dice

From Rosetta Code
Revision as of 05:28, 8 August 2009 by rosettacode>Paddy3118 (New task and Python solution)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Seven-sided dice from five-sided dice
You are encouraged to solve this task according to the task description, using any language you may know.

Given an equal-probability generator of one of the integers 1 to 5 as dice5; create dice7 that generates a pseudo-random integer from 1 to 7 in equal probability using only dice5 as a source of random numbers, and check the distribution for at least 1000000 calls using the function created in Random Distribution Checker.

dice7 might call dice5 twice, re-call if four of the 25 combinations are given, otherwise split the other 21 combinations into 7 groups of three, and return the group index from the rolls.

(Task adapted from an answer here)

Python

Follows the method suggested in the task description for creating dice7, and uses a function creator for dice7, to calculate the binning of the two calls to dice5. <lang python>import re, random

onetofive = (1,2,3,4,5)

def dice5():

   return random.choice(onetofive)

def dice7generator():

   rolls2answer = {}
   n=0
   for roll1 in onetofive:
       for roll2 in onetofive:
           rolls2answer[(roll1,roll2)] = (n // 3) + 1
           n += 1
   def dice7():
       'Generates 1 to 7 randomly, with equal prob. from dice5'
       trial = rolls2answer[(dice5(), dice5())]
       return trial if trial <=7 else dice7()
   return dice7

dice7 = dice7generator()</lang> Distribution check using Random Distribution Checker#python

>>> distcheck(dice5, 1000000, 1)
{1: 200244, 2: 199831, 3: 199548, 4: 199853, 5: 200524}
>>> distcheck(dice7, 1000000, 1)
{1: 142853, 2: 142576, 3: 143067, 4: 142149, 5: 143189, 6: 143285, 7: 142881}