Skip to content

Instantly share code, notes, and snippets.

@EvanTurner
Created August 23, 2018 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EvanTurner/08fdc4b65c17adb3e55c9a883fb92100 to your computer and use it in GitHub Desktop.
Save EvanTurner/08fdc4b65c17adb3e55c9a883fb92100 to your computer and use it in GitHub Desktop.
Python implementation of a Monte Carlo simulation of the famous "cars and goats" problem. Yes it is a mess.
# USAGE just copy/paste this in to a Python interpreter and invoke it with try_doors_with_strategy(), e.g.
# >>> num_trials, found_cars, found_goats = try_doors_with_strategy()
# >>> print 'car rate: {}'.format(str(1.0 * found_cars / num_trials))
# car rate: 0.338
# >>> num_trials, found_cars, found_goats = try_doors_with_strategy(num_trials = int(1e6), strategy='switch')
# >>> print 'car rate: {}'.format(str(1.0 * found_cars / num_trials))
# car rate: 0.666569
import os
# os.urandom()
def bytes2int(str):
return int(str.encode('hex'), 16)
def pick_door(doors=3):
return bytes2int(os.urandom(1)) % doors
goat_str = 'G'
car_str = 'C'
def fill_doors(num_doors=3):
car_door = pick_door(num_doors)
doors = []
for d in range(num_doors):
if d is car_door:
doors.append(car_str)
else:
doors.append(goat_str)
return doors
# total_count = 0
# car_count = 0
# goat_count = 0
# for trial in range(2000):
# total_count += 1
# if fill_doors(3)[pick_door(3)] is car_str:
# car_count += 1
# else:
# goat_count += 1
# def try_doors(num_trials=2000):
# total_count = 0
# car_count = 0
# goat_count = 0
# for trial in range(num_trials):
# total_count += 1
# if fill_doors(3)[pick_door(3)] is car_str:
# car_count += 1
# else:
# goat_count += 1
# return total_count, car_count, goat_count
def try_doors_with_strategy(num_trials=1000, num_doors=3, strategy='stay'):
total_count = 0
car_count = 0
goat_count = 0
for trial in range(num_trials):
total_count += 1
doors = fill_doors(num_doors)
chosen_door = pick_door(num_doors)
shown_door = -1
offered_door = -1
unchosen_goat_doors =[]
# find the remaining goats!
for door in range(num_doors):
if (door is not chosen_door) and (doors[door] is goat_str):
unchosen_goat_doors.append(door)
# pick a goat and show him
shown_door = unchosen_goat_doors[pick_door(len(unchosen_goat_doors))]
remaining_doors = []
# offer the remaining door
# there has to be a better way
for door in range(num_doors):
if (door is not chosen_door) and (door is not shown_door):
remaining_doors.append(door)
# choose your destiny
if strategy is 'stay':
pass
else:
chosen_door = remaining_doors[pick_door(len(remaining_doors))]
# let's see what they won!
if doors[chosen_door] is car_str:
car_count += 1
else:
goat_count += 1
return total_count, car_count, goat_count
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment