diff --git a/14/monty.py b/14/monty.py new file mode 100644 index 0000000000000000000000000000000000000000..9c1942480329bbad83e8f430fbfa60cd0aa35729 --- /dev/null +++ b/14/monty.py @@ -0,0 +1,62 @@ +from collections import Counter +from enum import Enum +from fractions import Fraction +import random + +DoorOption = Enum('DoorOption', ['GOAT', 'CAR']) +Situation = list[DoorOption] + + +def generate_situation(N=3) -> Situation: + output: list[DoorOption] = [] + car_index = random.randint(0, N - 1) + for i in range(N): + output.append(DoorOption.GOAT) + output[car_index] = DoorOption.CAR + return output + + +def choose_door(situation: Situation, disallowed: set[int]): + choices = list(range(len(situation))) + for x in disallowed: + choices.remove(x) + return random.choice(choices) + + +def play_game(situation: Situation, use_switch_strategy=True) -> bool: + choice: int = choose_door(situation, set()) + car: int = situation.index(DoorOption.CAR) + goat: int = choose_door(situation, set([choice, car])) + if use_switch_strategy: + choice = choose_door(situation, set([choice, goat])) + return situation[choice] == DoorOption.CAR + + +NUM_DOORS = 8 +games_played = 0 +wins: Counter[str] = Counter() + + +def actual_probability(doors): + return str((doors - 1)) + '/' + str((doors * (doors - 2))) + " = " + str((((doors - 1)) / ((doors * (doors - 2))))) + + +def frac(num, dem): + return Fraction(num, dem).limit_denominator(NUM_DOORS * NUM_DOORS) + + +while True: + situation = generate_situation(NUM_DOORS) + if play_game(situation, True): + wins['switch'] += 1 + if play_game(situation, False): + wins['stay'] += 1 + games_played += 1 + + if games_played % 10000 == 0: + print("\033c", end="", flush=True) + print("stay :", frac( + wins['stay'], games_played), "= " + str(wins['stay'] / games_played)) + print("switch (exp):", frac( + wins['switch'], games_played), "= " + str(wins['switch'] / games_played)) + print("switch (act):", actual_probability(NUM_DOORS))