|
# This code is Licensed under CC-0 / Public Domain / WTFPL |
|
# Written by Claudius Coenen <[email protected]> |
|
# Related reading: |
|
# - http://priceonomics.com/the-time-everyone-corrected-the-worlds-smartest/ |
|
# - http://en.wikipedia.org/wiki/Monty_Hall_problem |
|
|
|
class MontyHall |
|
def initialize(doors, eliminations) |
|
@available_doors = (0...doors).to_a |
|
@prize_door = @available_doors[rand(doors)] |
|
@eliminations = eliminations |
|
end |
|
|
|
def run |
|
@initial_choice = choose_random |
|
puts "Prize at #{@prize_door}, You're selecting #{@initial_choice}." if VERBOSITY > 1 |
|
print_choices if VERBOSITY > 3 |
|
|
|
host_eliminates = eliminate_doors_except([@initial_choice]) |
|
puts " Host eliminates #{host_eliminates.join(', ')}." if VERBOSITY > 2 |
|
print_choices if VERBOSITY > 3 |
|
|
|
@available_doors.delete @initial_choice |
|
@altered_choice = choose_random |
|
puts " Choice changed to #{@altered_choice}." if VERBOSITY > 2 && @altered_choice != @initial_choice |
|
end |
|
|
|
def choose_random |
|
@available_doors[rand(@available_doors.length)] |
|
end |
|
|
|
def eliminate_doors_except(exceptions) |
|
elimination_candidates = @available_doors - exceptions - [@prize_door] |
|
host_eliminates = [] |
|
@eliminations.times do |
|
eliminate = elimination_candidates.delete_at rand(elimination_candidates.length) |
|
host_eliminates.push eliminate |
|
end |
|
@available_doors -= host_eliminates |
|
host_eliminates |
|
end |
|
|
|
def print_choices |
|
puts " Your current choices are #{@available_doors.join(', ')}." |
|
end |
|
|
|
def initial_choice_correct? |
|
@initial_choice == @prize_door |
|
end |
|
|
|
def altered_choice_correct? |
|
@altered_choice == @prize_door |
|
end |
|
end |
|
|
|
VERBOSITY = 1 |
|
iterations = 10000 |
|
|
|
(3..5).to_a.each do |doors| |
|
(0..3).to_a.each do |eliminations| |
|
# you can't run this test unless you have anything to switch to. (doors must be at least eliminations + 2) |
|
next if eliminations > doors - 2 |
|
|
|
puts "Monty Hall with #{iterations} iterations of #{doors} doors and #{eliminations} eliminations" if VERBOSITY > 0 |
|
win_by_keeping = 0 |
|
win_by_switching = 0 |
|
|
|
iterations.times do |
|
mh = MontyHall.new(doors, eliminations) |
|
mh.run |
|
win_by_keeping += 1 if mh.initial_choice_correct? |
|
win_by_switching += 1 if mh.altered_choice_correct? |
|
end |
|
|
|
puts " Keeping wins #{win_by_keeping}/#{iterations} times" if VERBOSITY > 0 |
|
puts " Switching wins #{win_by_switching}/#{iterations} times" if VERBOSITY > 0 |
|
end |
|
end |