Skip to content

Instantly share code, notes, and snippets.

@robbintt
Last active May 10, 2018 22:59
Show Gist options
  • Save robbintt/b9b3ca3550f52afcd3a5ac0327645498 to your computer and use it in GitHub Desktop.
Save robbintt/b9b3ca3550f52afcd3a5ac0327645498 to your computer and use it in GitHub Desktop.
A quick and dirty hundred-prisoner game implementation done over lunch
''' 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