Skip to content

Instantly share code, notes, and snippets.

@zakharskorokhodov
Created February 18, 2015 07:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zakharskorokhodov/47dc7aec80de8980146b to your computer and use it in GitHub Desktop.
Save zakharskorokhodov/47dc7aec80de8980146b to your computer and use it in GitHub Desktop.
100 Prisoners & boxes chalenge with dicts
#!/usr/bin/python3
"""
Prisoners & boxes chalenge
"""
from random import shuffle
import time
class Profiler(object):
"""
Simple profiler.
"""
def __enter__(self):
self._startTime = time.time()
def __exit__(self, type, value, traceback):
print('Elapsed time: {:.3f} sec'.format(
time.time() - self._startTime
))
NOP = 100 # n of prisoners
HALF_NOP = int(NOP/2)
BOXES = []
PRISONERS = []
def create_objects():
"""
Fill objects lists.
"""
labels_numbers = list(range(1, NOP + 1))
shuffle(labels_numbers)
prisoners_numbers = list(range(1, NOP + 1))
shuffle(prisoners_numbers)
for number in range(1, NOP + 1):
BOXES.append(
{
'number': number,
'label': labels_numbers[number - 1],
'opening': 0
}
)
PRISONERS.append(
{
'number': prisoners_numbers[number - 1],
'tries': 0,
'status': None
}
)
def find_tries():
"""
Try find label by each prisoner.
"""
def find_try(prisoner, box=None):
"""
Try find label by one prisoner.
"""
prisoner['tries'] += 1
if prisoner['tries'] > HALF_NOP:
prisoner['status'] = 'dead'
return None
if not box:
box = prisoner['number']
label = BOXES[box - 1]['label']
BOXES[box - 1]['opening'] += 1
print('\tTry #{0}: Box #{1} with label #{2} was opened {3} times.'.format(
prisoner['tries'],
BOXES[box - 1]['number'],
BOXES[box - 1]['label'],
BOXES[box - 1]['opening'],
))
if label == prisoner['number']:
prisoner['status'] = 'alive'
return None
else:
find_try(prisoner, label)
for number, prisoner in enumerate(PRISONERS):
print('Prisoner #{0} ({1} from {2})'.format(
prisoner['number'], number + 1, NOP
))
find_try(prisoner)
print('Prisoner #{0} is {1}. He used {2} tries.'.format(
prisoner['number'],
prisoner['status'],
prisoner['tries'],
))
print()
if prisoner['status'] == 'dead':
return prisoner
def main():
"""
Main action.
"""
create_objects()
fail_prisoner = find_tries()
if fail_prisoner:
print('All die...')
for box in BOXES:
if box['label'] == fail_prisoner['number']:
print('Required label was in box #{0}'.format(
box['number']
))
print('Box #{0} with label #{1} was opened {2} times.'.format(
box['number'],
box['label'],
box['opening']
))
else:
print('All alive!')
if __name__ == '__main__':
with Profiler() as p:
main()
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment