Created
August 23, 2018 16:30
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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