Created
July 28, 2022 11:47
-
-
Save triffid/e68247fcb5491dafc870f8b3d8b445e0 to your computer and use it in GitHub Desktop.
cat box puzzle
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
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
from random import randint | |
from functools import reduce | |
print("There is a row of boxes. A cat is hiding in one of the boxes.") | |
print("Every time you check a box, the cat (invisibly) moves to an adjacent box.") | |
print() | |
print("Find a pattern that corners the cat with the least number of checks!") | |
print(" (select a box with 100% probability to win)") | |
print() | |
while True: | |
try: | |
n_boxes = int(input("How many boxes in the row? (≥2) \x1B[1m")) | |
if (n_boxes >= 2): | |
print("\x1B[0m", end='') | |
break | |
except ValueError: | |
print("\x1B[0mPlease enter an integer!") | |
pass | |
except KeyboardInterrupt: | |
print("\x1B[0m\nBye!") | |
exit(0) | |
else: | |
print("\x1B[0mBox count must be at least 2!") | |
boxprob = [1 / n_boxes for i in range(n_boxes)] | |
print("Box Index : |" + "".join(map(lambda p: "\x1B[1m%7s\x1B[0m |" % (p + 1), range(n_boxes)))) | |
guesses = 0 | |
while True: | |
print("Probabilities : |" + "".join(list(map( lambda p: "\x1B[1m%7.4g%%\x1B[0m|" % (p * 100), boxprob)))) | |
# select box to check | |
while True: | |
try: | |
b = int(input("Check box number (1-%d): \x1B[1m" % n_boxes)) - 1 | |
if ((b >= 0) and (b < n_boxes)): | |
print("\x1B[0m", end='') | |
break | |
except ValueError: | |
print("\x1B[0mPlease enter an integer between 1 and %d!" % n_boxes) | |
except KeyboardInterrupt: | |
print("\n\x1B[0mBye!") | |
exit(0) | |
else: | |
print("\x1B[0mBox number must be between 1 and %d!" % n_boxes) | |
guesses += 1 | |
print("Box %d goes to 0%% probability" % (b + 1)) | |
boxprob[b] = 0 | |
# rescale probabilities | |
scale = reduce((lambda x, y: x + y), boxprob) | |
if (scale == 0): | |
print("\nCat cornered after %d checks! Score: %.3g%%\n" % (guesses, max(n_boxes - 2, 1) * 200 / guesses)) | |
exit(0) | |
boxprob = list(map(lambda r: r / scale, boxprob)) | |
print("Probabilities after choice: |" + "".join(list(map( lambda p: "\x1B[1m%7.4g%%\x1B[0m|" % (p * 100), boxprob)))) | |
# move cat | |
print("\n→ Cat moves one box left or right\n") | |
boxprobn = [0 for z in range(n_boxes)] | |
for i in range(n_boxes): | |
if (i == 0): | |
boxprobn[i + 1] += boxprob[i] | |
elif (i == (n_boxes - 1)): | |
boxprobn[i - 1] += boxprob[i] | |
else: | |
boxprobn[i + 1] += boxprob[i] / 2 | |
boxprobn[i - 1] += boxprob[i] / 2 | |
boxprob = boxprobn |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment