Hello again!

  I'm learning Factor little by little. Currently I'm trying to contribute a 
solution to Rosetta Code for the following pair of problems:

  http://rosettacode.org/wiki/Seven-sided_dice_from_five-sided_dice
  http://rosettacode.org/wiki/Simple_Random_Distribution_Checker

  The code that I've got so far can be seen below. Please, comment and 
criticize:

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
;


---=====---
 Александр

------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF
_______________________________________________
Factor-talk mailing list
Factor-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to