This page contains automated test results for code from O'Reilly's Ruby Cookbook. If this code looks interesting or useful, you might want to buy the whole book.
Choosing Randomly From a Weighted List | ||
---|---|---|
Code | Expected | Actual |
def choose_weighted(weighted) sum = weighted.inject(0) do |sum, item_and_weight| sum += item_and_weight[1] end target = rand(sum) weighted.each do |item, weight| return item if target <= weight target -= weight end end marbles = { :black => 51, :white => 17 } 3.times { puts choose_weighted(marbles) } |
black white black |
black white black |
lottery_probabilities = { "You've wasted your money!" => 1000, "You've won back the cost of your ticket!" => 50, "You've won two shiny zorkmids!" => 20, "You've won five zorkmids!" => 10, "You've won ten zorkmids!" => 5, "You've won a hundred zorkmids!" => 1 } |
Let's buy some lottery tickets. |
|
5.times { puts choose_weighted(lottery_probabilities) } |
You've wasted your money! You've wasted your money! You've wasted your money! You've wasted your money! You've won five zorkmids! |
You've wasted your money! You've wasted your money! You've wasted your money! You've wasted your money! You've won five zorkmids! |
def normalize!(weighted) sum = weighted.inject(0) do |sum, item_and_weight| sum += item_and_weight[1] end sum = sum.to_f weighted.each { |item, weight| weighted[item] = weight/sum } end lottery_probabilities["You've won five hundred zorkmids!"] = 0.1 normalize!(lottery_probabilities) |
{ "You've wasted your money!" => 0.920725531718995, | {"You've won ten zorkmids!"=>0.00460362765859497, "You've won a hundred zorkmids!"=>0.000920725531718995, "You've won two shiny zorkmids!"=>0.0184145106343799, "You've wasted your money!"=>0.920725531718995, "You've won five zorkmids!"=>0.00920725531718995, "You've won back the cost of your ticket!"=>0.0460362765859497, "You've won five hundred zorkmids!"=>9.20725531718995e-05} |
def choose_weighted_assuming_unity(weighted) target = rand weighted.each do |item, weight| return item if target <= weight target -= weight end end 5.times { puts choose_weighted_assuming_unity(lottery_probabilities) } |
You've wasted your money! You've wasted your money! You've wasted your money! You've wasted your money! You've won back the cost of your ticket! |
You've wasted your money! You've wasted your money! You've wasted your money! You've wasted your money! You've won back the cost of your ticket! |