9.9 KiB
The Monty Hall problem (Deutsch: Ziegenproblem)¶
Read about it on Wikipedia or in German as the Ziegenproblem and come back. I'll wait.
In this notebook, you will write a program to simulated the Monty Hall problem.
We are going to make extensive use of the function random.randint(a, b)
. From its docstring, it returns a random integer in range [a, b], including both end points.
import random
for i in range(10):
print(random.randint(0,2))
Q1¶
For your first task, create a function called sample_not
which takes two positional arguments (call them not1
and not2
) and will return a random integer between 0 and 2 (endpoints included) but which is not either of the arguments. The positional arguments will always be integers between 0 and 2 (inclusive).
# YOUR CODE HERE
raise NotImplementedError()
# This is a test of the above, do not change this code.
assert sample_not(0,1)==2
assert sample_not(0,2)==1
assert sample_not(1,0)==2
assert sample_not(1,2)==0
assert sample_not(2,0)==1
assert sample_not(2,1)==0
assert sample_not(0,1)==2
assert sample_not(0,0) in (1,2)
assert sample_not(1,1) in (0,2)
assert sample_not(2,2) in (0,1)
Q2¶
For your next task, consider the following code:
# generate what is behind the doors
doors = ['goat', 'goat', 'goat']
car_door = random.randint(0,2)
doors[car_door] = 'car'
# Now, the guest makes a first guess.
guess1 = random.randint(0,2)
# Now, the host opens a door, which is not the guess or the car.
host_open_door = sample_not(guess1,car_door)
# Based on the variable `do_switch` (which is not set here), the guess will either make a new choice or stay with the original guess.
if do_switch:
guess2 = sample_not(guess1,host_open_door)
final_guess = guess2
else:
final_guess = guess1
# Finally, determine what was behind the door for the final guess.
result = doors[final_guess]
Put this code in a function called run_game
which takes a single argument, do_switch
, and returns a boolean, indicating a win with True
or a loss with False
.
# YOUR CODE HERE
raise NotImplementedError()
# This is a test of the above, do not change this code.
count = 300
for do_switch in (True, False):
wins = 0
for i in range(count):
this_run_win = run_game(do_switch)
assert(type(this_run_win)==bool)
wins += int(this_run_win)
print('do_switch: %s, wins: %d, count: %d'%(do_switch, wins, count))
if do_switch:
assert abs(wins/count - 2/3) < 0.1
else:
assert abs(wins/count - 1/3) < 0.1
Note the above results. You have numerically simulated the Monty Hall problem.
Q3¶
Make a new game where there are 100 doors and the host opens 98 of them after the initial guess. Make a new function called run_game_100
, and any other functions you need, which plays a single round of this game. Again, this function should take an argument do_switch
.
# YOUR CODE HERE
raise NotImplementedError()
# This is a test of the above, do not change this code.
count = 1000
for do_switch in (True, False):
wins = 0
for i in range(count):
this_run_win = run_game_100(do_switch)
assert(type(this_run_win)==bool)
wins += int(this_run_win)
print('do_switch: %s, wins: %d, count: %d'%(do_switch, wins, count))
if do_switch:
assert abs(wins/count - 0.99) < 0.02
else:
assert abs(wins/count - 0.01) < 0.02