Monty Hall empirical proof
require 'test/unit' | |
# Read about the problem and mathematical proof here: | |
# http://www.greenteapress.com/thinkbayes/html/thinkbayes002.html#sec15 | |
class MontyHall | |
include Test::Unit::Assertions | |
NUM_DOORS = 3 | |
# @return [Boolean] whether player won | |
def play | |
winning_door = rand(NUM_DOORS) | |
player_first_choice = rand(NUM_DOORS) | |
opened_empty_door = open_empty_door(winning_door, player_first_choice) | |
assert_not_equal winning_door, opened_empty_door | |
assert_not_equal player_first_choice, opened_empty_door | |
player_second_choice = second_choice(player_first_choice, opened_empty_door) | |
return (player_second_choice == winning_door) | |
end | |
end | |
# basic Monty Hall rules, player always switches doors | |
class MontyHallStandard < MontyHall | |
def open_empty_door(winning_door, player_first_choice) | |
((0...NUM_DOORS).to_a - [winning_door, player_first_choice]).sample | |
end | |
# always switch doors | |
def second_choice(player_first_choice, opened_empty_door) | |
((0...NUM_DOORS).to_a - [player_first_choice, opened_empty_door]).sample | |
end | |
end | |
class MontyHallAlwaysB < MontyHallStandard | |
PREFERRED_DOOR = 1 | |
def open_empty_door(winning_door, player_first_choice) | |
forbidden_doors = [winning_door, player_first_choice] | |
if forbidden_doors.include?(PREFERRED_DOOR) | |
super | |
else | |
PREFERRED_DOOR | |
end | |
end | |
end | |
class MontyHallAlwaysBPlayerStick < MontyHallAlwaysB | |
def second_choice(player_first_choice, opened_empty_door) | |
opened_empty_door == PREFERRED_DOOR ? player_first_choice : super | |
end | |
end | |
attempts = 10000 | |
# game = MontyHallStandard.new | |
# game = MontyHallAlwaysB.new | |
game = MontyHallAlwaysBPlayerStick.new | |
successes = attempts.times.count { game.play } | |
success_rate = successes.to_f/attempts | |
puts "player success rate #{success_rate} in #{attempts} attempts" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment