Last active
May 10, 2018 22:59
-
-
Save robbintt/b9b3ca3550f52afcd3a5ac0327645498 to your computer and use it in GitHub Desktop.
A quick and dirty hundred-prisoner game implementation done over lunch
This file contains hidden or 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
''' A quick and dirty hundred-prisoner game implementation done over lunch | |
From: http://datagenetics.com/blog/december42014/index.html | |
hackernews: https://news.ycombinator.com/item?id=16984815 | |
Assumptions | |
- The boxes must be indexed, e.g. they must be ordered and the order must be static across prisoners. | |
The index of the prisoner's list is the order the prisoners will open the box in. | |
The value of the index is the box they will open. | |
Lose condition: | |
The prisoners lose if any prisoner does not find the box for their number. | |
The prisoner_list is mapped onto the random values | |
we use 0-99 for the prisoner list to match the prisoner index values | |
in python the 0th item is the first item in a list, so we use 0-99 everywhere | |
Ideas: | |
- Consider abstracting number of prisoners, number of boxes, and tries... number of prisoners == number of boxes, what if it doesn't?? | |
References: | |
- Python's random module: https://docs.python.org/2/library/random.html | |
''' | |
import random | |
def prison_test(prisoner_list, box_list, allowed_tries): | |
# go through each prisoner | |
prisoner_index = 0 | |
failed = False | |
while prisoner_index < len(prisoner_list): | |
''' go through each prisoner, they will try 50 boxes | |
''' | |
tries = allowed_tries | |
number_to_attempt = prisoner_list[prisoner_index] | |
while tries > 0: | |
''' go through each box | |
''' | |
# open a box | |
# this test could also be done by getting the first 50 values in the chain | |
# but then if the chain loops we need to detect that, no big deal | |
# then testing if the number_to_attempt is in the tested_chain (first 50 values of chain) | |
# this gives us a lot more state to work with if we want to learn more about this set of games | |
if box_list[number_to_attempt] == prisoner_list[prisoner_index]: | |
# prisoner finds their box, fail flag will not be triggered | |
break | |
else: | |
# next, try the number in the box | |
number_to_attempt = box_list[number_to_attempt] | |
tries -= 1 | |
# the chain was too long and the number was too far down the chain | |
else: | |
failed = True | |
# this breaks the outer while loop | |
break | |
prisoner_index += 1 | |
return failed | |
if __name__ == "__main__": | |
boxes = 100 | |
prisoners = 100 | |
# per prisoner | |
allowed_tries = 50 | |
iterations = 100000 | |
# run the simulation | |
i = iterations | |
wins = 0 | |
losses = 0 | |
while i > 0: | |
# prisoners and their tickets, gives 0-99 | |
prisoner_list = range(prisoners) | |
random.shuffle(prisoner_list) | |
# boxes and their contents, gives 0-99 | |
box_list = range(boxes) | |
random.shuffle(box_list) | |
result = prison_test(prisoner_list, box_list, allowed_tries) | |
if result: | |
losses += 1 | |
else: | |
wins += 1 | |
i -= 1 | |
win_rate = float(wins)/iterations | |
print("iterations: {} | wins: {} | losses: {} | win rate: {}").format(iterations, wins, losses, win_rate) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment