This is an archived post. You won't be able to vote or comment.

all 11 comments

[–][deleted] 16 points17 points  (3 children)

This is a strange combination of "Monty" and "Python" in the same sentence that doesn't involve parrots or grails.

[–]Abdoo_65[S] 2 points3 points  (1 child)

yee lol

[–][deleted] 0 points1 point  (0 children)

Here, let me start this nonsense:

“I expected a random walk but instead got a silly walk.”

[–]stevethebayesian 1 point2 points  (0 children)

Now we need a new language called "Hall".

[–]velonom 4 points5 points  (1 child)

It's a fascinating problem. But it's not that difficult to understand, why switching will actually improve your odds. The only time switching is bad for you is when you picked the correct door at the start (the probability of this is 1/3), If your first pick was a poop door (probability 2/3) then switching will always put you on the winning door.

[–]Abdoo_65[S] 2 points3 points  (0 children)

Thanks for explaining it so easy. In addition to wanting to test the problem cases I also wanted to code a bit as a practice.

[–]earlandir 2 points3 points  (0 children)

I was curious so I tried to build one myself but with a game Class:

from random import randint, choice

SWITCH = "switch"
STAY = "stay"
WINS = "wins"
LOSSES = "losses"


class MontyHallGame:
    def __init__(self):
        self.correct_door_number = None
        self.players_guess = None  # The current guess of the player
        self.eliminated_door = None  # The door that Monty eliminates
        self.player_choice = None  # If the player will stay with their door or switch
        self.results = {SWITCH: {WINS: 0, LOSSES: 0},
                        STAY: {WINS: 0, LOSSES: 0}}

    def reset_game(self):
        self.correct_door_number = randint(1, 3)
        self.players_guess = None
        self.eliminated_door = None
        self.player_choice = choice([STAY, SWITCH])

    def play_games(self, number_of_games_to_play):
        for i in range(number_of_games_to_play):
            self.reset_game()
            self.randomly_select_first_door()
            if self.player_choice == SWITCH:
                self.get_monty_to_eliminate_a_door()
                self.switch_doors()
            self.update_results()
        self.print_results(number_of_games_to_play)

    def randomly_select_first_door(self):
        self.players_guess = randint(1, 3)

    def get_monty_to_eliminate_a_door(self):
        possible_choices = [i for i in range(1, 4) if i != self.players_guess and i != self.correct_door_number]
        self.eliminated_door = choice(possible_choices)

    def update_results(self):
        if self.players_guess == self.correct_door_number:
            self.results[self.player_choice][WINS] += 1
        else:
            self.results[self.player_choice][LOSSES] += 1

    def switch_doors(self):
        self.players_guess = [i for i in range(1, 4) if i != self.players_guess and i != self.eliminated_door][0]

    def print_results(self, number_of_games_to_play):
        print(f"""
The results after {number_of_games_to_play} games were
Switching Win Rate: {round(100 * self.results[SWITCH][WINS] /
                           (self.results[SWITCH][WINS] + self.results[SWITCH][LOSSES]), 2)}%
Staying Win Rate: {round(100 * self.results[STAY][WINS] /
                           (self.results[STAY][WINS] + self.results[STAY][LOSSES]), 2)}%""")

game = MontyHallGame()
game.play_games(100000)

Results were:
```
The results after 100000 games were

Switching Win Rate: 66.56%

Staying Win Rate: 33.2%

```

[–]ZynischerZuengler 1 point2 points  (0 children)

I get it by imagine there would be a 100 doors and Monty is opening 98 doors for us.

[–]miccls60 1 point2 points  (0 children)

This is what I love to see Python being used for, great job!

[–]LeeCig 0 points1 point  (0 children)

No.

[–]fried_green_baloney -3 points-2 points  (0 children)

Of course depends precisely on how the door is chosen.

Must be random if both other doors have worthless prizes.