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)


$ include "seed7_05.s7i";
  include "float.s7i";
 
const type: letter is new enum
    aleph, beth, gimel, daleth, he, waw, zayin, heth
  end enum;
 
const func string: str (in letter: aLetter) is
    return [] ("aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth") [succ(ord(aLetter))];
 
enable_output(letter);
 
const array [letter] integer: table is [letter] (
    5544, 4620, 3960, 3465, 3080, 2772, 2520, 1759);
 
const func letter: randomLetter is func
  result
    var letter: resultLetter is aleph;
  local
    var integer: number is 0;
  begin
    number := rand(1, 27720);
    while number > table[resultLetter] do
      number -:= table[resultLetter];
      incr(resultLetter);
    end while;
  end func;
 
const proc: main is func
  local
    var integer: count is 0;
    var letter: aLetter is aleph;
    var array [letter] integer: occurrence is letter times 0;
  begin
    for count range 1 to 1000000 do
      aLetter := randomLetter;
      incr(occurrence[aLetter]);
    end for;
    writeln("Name   Count  Ratio    Expected");
    for aLetter range letter.first to letter.last do
      writeln(aLetter rpad 7 <& occurrence[aLetter] lpad 6 <&
              flt(occurrence[aLetter]) / 10000.9 digits 4 lpad 8 <& "%" <&
              100.0 * flt(table[aLetter]) / 27720.0 digits 4 lpad 8 <& "%");
    end for;
  end func;