#!/usr/bin/ruby

#
## Rejection sampling algorithm
## https://en.wikipedia.org/wiki/Rejection_sampling
#

func accept_reject(table) {

    var accepted = nil
    var max_fitness = table.map{|h| h{:weight} }.max
    var prob = max_fitness.rand

    loop {
        var item = table.rand

        if (prob < item{:weight}) {
            accepted = item
            break
        }
    }

    accepted
}

var table = [
    Hash(value => "Sidef",  weight => 1.0.rand(0.5)),
    Hash(value => "Ruby",   weight => 0.5.rand),
    Hash(value => "Perl",   weight => 0.5.rand),
    Hash(value => "Python", weight => 0.5.rand),
    Hash(value => "Julia",  weight => 0.5.rand),
]

var picked = accept_reject(table)
say "Picked #{picked{:value}} with a probability of #{picked{:weight}.round(-2)}%"

var freq = 100.of { accept_reject(table){:value} }.freq
var max = freq.max_by { |_,v| v }

if (max.key == "Sidef") {
    say "In average, Sidef is the winner!"
}
else {
    say "In average, #{max.key} is the winner -- that's sad..."
}
