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! |