The Monty Hall Problem

Jeff Atwood mentioned the Monty Hall problem, and that some Eduardo guy had not been convinced about it until a computer program simulated the theory over and over.

I had the same issue, being unconvinced about it, and so I wrote a similar program in Python. (Yeah, I'm a productive guy at work.)

import random

pot_goat = "GOAT"
pot_car = "CAR"
pots = pot_goat, pot_car

door_a = "DOOR A"
door_b = "DOOR B"
door_c = "DOOR C"
doors = door_a, door_b, door_c

player_nonswitch = "PLAYER NS"
player_switch = "PLAYER SW"
player_repick = "PLAYER RP"
players = player_nonswitch, player_switch, player_repick

def make_round():
    door_pots = dict((door, pot_goat) for door in doors)
    door_pots[random.choice(doors)] = pot_car
    return door_pots

stats = dict((player, dict((pot, 0) for pot in pots)) for player in players)

num_rounds = 10 ** 7
for round_num in xrange(num_rounds):
    if (round_num % (10 ** 5)) == 0:
        print "Round #%d (%.2f%%)" % (round_num, float(round_num) / num_rounds * 100)
    door_pots = make_round()
    for player in players:
        # First the contestant gets to choose from all three doors.
        choice = random.choice(doors)
        # Then, the host reveals a door which has a goat behind it which the
        # contestant didn't choose, asking if the contestant wants to remake
        # the door choice.
        goats = [d for (d, p) in door_pots.iteritems()
                 if p == pot_goat and d != choice]
        reveal_door = random.choice(goats)
        remaining_doors = [d for d in doors if d != reveal_door]
        if player == player_repick:
            # Contestant just picks randomly, blindfolded.
            choice = random.choice(remaining_doors)
        elif player == player_switch:
            # Contestant does want to switch, and so chooses again from the
            # remaining doors.
            choice = [d for d in remaining_doors if d != choice][0]
        stats[player][door_pots[choice]] += 1

for player, player_pots in stats.iteritems():
    goats, cars = player_pots[pot_goat], player_pots[pot_car]
    cars_amount = float(cars) / (goats + cars) * 100
    print "%s: %d goats, %d cars - %.2f%% cars" % (player, goats, cars, cars_amount)

The results?

PLAYER NS: 6665086 goats, 3334914 cars - 33.35% cars
PLAYER SW: 3333893 goats, 6666107 cars - 66.66% cars
PLAYER RP: 5001588 goats, 4998412 cars - 49.98% cars

PLAYER NS is the non-switching player, PLAYER SW switches, and PLAYER RP just randomly chooses again.

I can't explain this at all.

simples3 0.3 released!

Just released simples3 version 0.3.

This release adds support for generating those nice only-valid-until-some-time URLs (expiring URLs.) Thanks to Pavel Repin for that.

Otherwise mostly bugfixes and cosmetic changes (non-API breaking.)

simples3 0.3-r2. on PyPI or just sudo easy_install -U simples3 as usual.

RSS 2.0