Given a mapping between items and their required probability of occurrence, generate a million items randomly subject to the given probabilities and compare the target probability of occurrence versus the generated values.

The total of all the probabilities should equal one. (Because floating point arithmetic is involved, this is subject to rounding errors).

aleph   1/5.0
beth    1/6.0
gimel   1/7.0
daleth  1/8.0
he      1/9.0
waw     1/10.0
zayin   1/11.0
heth    1759/27720 # adjusted so that probabilities add to 1
Related task

 Random number generator (device)


 
trials:=1000000;
 
Array probs[8];                         {store the probabilities}
[probs]:=[<i=1,8> 1/(i+4)];
probs[8]:=1-Sigma<i=1,7>[probs[i,1]];
 
Func Round( a, b ) = (2*a+b)\(2*b).;    {rounds a fraction with numerator a and denominator b}
                                   ;    {to the nearest integer (positive fractions only)}
 
Func Sel =                              {select a number from 1 to 8 according to the}
    r:=Rand|27720;                      {specified probabilities}
    if r < probs[1]*27720 then Return(1) fi;
    if r < Sigma<i=1,2>[probs[i]]*27720 then Return(2) fi;
    if r < Sigma<i=1,3>[probs[i]]*27720 then Return(3) fi;
    if r < Sigma<i=1,4>[probs[i]]*27720 then Return(4) fi;
    if r < Sigma<i=1,5>[probs[i]]*27720 then Return(5) fi;
    if r < Sigma<i=1,6>[probs[i]]*27720 then Return(6) fi;
    if r < Sigma<i=1,7>[probs[i]]*27720 then Return(7) fi;
    Return(8);
.;
 
Array label[10];                        {strings are not Fermat's strong suit}
Func Letter(n) =                        {assign a Hebrew letter to the numbers 1-8}
                  [label]:='heth     ';
    if n = 1 then [label]:='aleph    '  fi;
    if n = 2 then [label]:='beth     '  fi;
    if n = 3 then [label]:='gimel    '  fi;
    if n = 4 then [label]:='daleth   '  fi;
    if n = 5 then [label]:='he       '  fi;
    if n = 6 then [label]:='waw      '  fi;
    if n = 7 then [label]:='zayin    '  fi;
.;
 
Array count[8];                         {pick a bunch of random numbers}
for i = 1 to trials do
    s:=Sel;
    count[s]:=count[s]+1;
od;
 
for i = 1 to 8 do                       {now display some diagnostics}
    Letter(i);
    ctp:=count[i]/trials-probs[i];
    !([label:char, count[i]/trials,' differs from ',probs[i]);
    !(' by ',ctp, ' or about one part in ', Round(Denom(ctp),|Numer(ctp)|));
    !!;
od;
 
!!('The various probabilities add up to ',Sigma<i=1,8>[count[i]/trials]);   {check if our trials add to 1}
 