Verify distribution uniformity/Naive: Difference between revisions

Update Factor implementation: some functions were simplified thanks to John Benediktsson.
(Add Factor implementation.)
(Update Factor implementation: some functions were simplified thanks to John Benediktsson.)
Line 459:
 
=={{header|Factor}}==
<lang factor>USING: kernel random mathsequences math.functionsassocs math.vectorslocals sequences localssorting prettyprint ;
math math.functions math.statistics math.vectors math.ranges ;
IN: rosetta-code.dice7
 
! Output a random numberinteger 1..5.
: dice5 ( -- x )
5 [1,b] random
random-unit 5 * floor 1 + >integer
;
 
! Output a random numberinteger 1..7 using dice5 as randomness source.
: dice7 ( -- x )
0 [ dup 21 < ] [ drop dice5 5 * dice5 + 6 - ] do until
7 rem 1 + >integer
;
 
! Roll dicethe usingdie theby passedcalling wordthe quotation the given number of times and produce anreturn
! an array with roll results.
! Sample call: \1000 [ dice7 1000] roll
: roll ( wordtimes quot: ( -- x ) times -- array )
iota [ drop dup executecall( -- x ) ] mapcurry replicate
nip
;
 
Line 486:
! there is the number of ones in the input array, in the second position
! of the result there is the number of twos in the input array, etc.
: count-diceXdice-outcomes ( array X array -- array )
histogram
iota [ 1 + dupd [ = ] curry count ] map
swap [1,b] [ over [ 0 or ] change-at ] each
swap length
sort-keys values
over sum
assert=
;
 
! Verify distribution uniformity/Naive. Delta is the acceptable deviation
! from the ideal number of items in each bucket, expressed as a fraction of
! the total count. Sides is the number of die sides. RndDie-func is a word that
! produces a random number on stack in the range [1..sides], times is the
! number of times to call it.
! Sample call: 0.02 7 \[ dice7 ] 100000 verify
:: verify ( delta sides rnddie-func: ( -- random ) times -- )
sides
rndtimes die-func times roll
sides count-diceXdice-outcomes
dup .
times sides / :> ideal-count
ideal-count v-n vabs
times v/n
delta [ < ] curry mapall?
vall? [ "Random enough" . ] [ "Not random enough" . ] if
;
 
Line 514:
: verify-all ( -- )
{ 1 10 100 1000 10000 100000 1000000 }
[| times | 0.02 7 \[ dice7 ] times verify ] each
;</lang>
 
Output:
<pre>USE: rosetta-code.dice7 verify-all
{ 0 1 0 0 1 0 0 0 }
"Not random enough"
{ 30 2 3 1 1 1 1 02 }
"Not random enough"
{ 1117 12 1815 2211 1213 13 1219 }
"Not random enough"
{ 151140 130 172141 138148 145143 141155 123143 }
"Not randomRandom enough"
{ 14041457 14461373 13711427 14601433 14311443 14401382 14481485 }
"Random enough"
{ 1431114225 1413914320 1438814216 1434614326 1415014415 1440514084 1426114414 }
"Random enough"
{ 142599 141910 142524 143029 143353 142696 143889 }
{ 142877 143514 142441 142380 143141 143203 142444 }
"Random enough"</pre>
 
Anonymous user