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)


probabilities = {
  "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,
}
probabilities["heth"] = 1.0 - probabilities.each_value.inject(:+)
ordered_keys = probabilities.keys
 
sum, sums = 0.0, {}
ordered_keys.each do |key|
  sum += probabilities[key]
  sums[key] = sum
end
 
actual = Hash.new(0)
 
samples = 1_000_000
samples.times do
  r = rand
  for k in ordered_keys
    if r < sums[k]
      actual[k] += 1
      break
    end
  end
end
 
puts  "key     expected    actual        diff"
for k in ordered_keys
  act = Float(actual[k]) / samples
  val = probabilities[k]
  printf "%-8s%.8f  %.8f  %6.3f %%\n", k, val, act, 100*(act-val)/val
end