Created
February 18, 2015 07:35
-
-
Save zakharskorokhodov/47dc7aec80de8980146b to your computer and use it in GitHub Desktop.
100 Prisoners & boxes chalenge with dicts
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
#!/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