Verify distribution uniformity/Naive: Difference between revisions

Content added Content deleted
(Updated D entry)
(Add Factor implementation.)
Line 457: Line 457:
0
0
</lang>
</lang>

=={{header|Factor}}==
<lang factor>USING: kernel random math math.functions math.vectors sequences locals prettyprint ;
IN: dice7

! Output a random number 1..5.
: dice5 ( -- x )
random-unit 5 * floor 1 + >integer
;

! Output a random number 1..7 using dice5 as randomness source.
: dice7 ( -- x )
0 [ dup 21 < ] [ drop dice5 5 * dice5 + 6 - ] do until
7 rem 1 + >integer
;

! Roll dice using the passed word the given number of times and produce an
! array with roll results.
! Sample call: \ dice7 1000 roll
: roll ( word: ( -- x ) times -- array )
iota [ drop dup execute( -- x ) ] map
nip
;

! Input array contains outcomes of a number of die throws. Each die result is
! an integer in the range 1..X. Calculate and return the number of each
! of the results in the array so that in the first position of the result
! 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-diceX-outcomes ( array X -- array )
iota [ 1 + dupd [ = ] curry count ] map
swap length
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. Rnd-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 rnd-func: ( -- random ) times -- )
rnd-func times roll
sides count-diceX-outcomes
dup .
times sides / :> ideal-count
ideal-count v-n vabs
times v/n
delta [ < ] curry map
vall? [ "Random enough" . ] [ "Not random enough" . ] if
;


! Call verify with 1, 10, 100, ... 1000000 rolls of 7-sided die.
: verify-all ( -- )
{ 1 10 100 1000 10000 100000 1000000 }
[| times | 0.02 7 \ dice7 times verify ] each
;</lang>

Output:
<pre>USE: dice7 verify-all
{ 0 1 0 0 0 0 0 }
"Not random enough"
{ 3 3 1 1 1 1 0 }
"Not random enough"
{ 11 12 18 22 12 13 12 }
"Not random enough"
{ 151 130 172 138 145 141 123 }
"Not random enough"
{ 1404 1446 1371 1460 1431 1440 1448 }
"Random enough"
{ 14311 14139 14388 14346 14150 14405 14261 }
"Random enough"
{ 142877 143514 142441 142380 143141 143203 142444 }
"Random enough"</pre>


=={{header|Fortran}}==
=={{header|Fortran}}==