Skip to content

Instantly share code, notes, and snippets.

@purcell
Last active December 19, 2015 12:49
Show Gist options
  • Save purcell/5957243 to your computer and use it in GitHub Desktop.
Save purcell/5957243 to your computer and use it in GitHub Desktop.
Monty Hall problem simulated in Haskell: see http://en.wikipedia.org/wiki/Monty_Hall_problem
module MontyHall
where
import System.Random
import Control.Monad
import qualified Data.Set as Set
data Result = Win | Lose deriving (Eq, Show)
data Door = Door Int deriving (Eq, Show, Ord)
type Doors = Set.Set Door
randomChoice :: Set.Set a -> IO a
randomChoice set = (l !!) `liftM` randomRIO (0, length l - 1)
where l = Set.toList set
allDoors :: Doors
allDoors = Set.fromList $ map Door [1..3]
without :: Ord a => Set.Set a -> a -> Set.Set a
without = flip Set.delete
type PlayerStrategy = (Door -> Doors -> IO Door)
runGame :: PlayerStrategy -> IO Result
runGame strategy = do
doorWithCar <- randomChoice allDoors
playerGuess <- randomChoice allDoors
openedDoor <- randomChoice (allDoors `without` doorWithCar)
playerFinalGuess <- strategy playerGuess (allDoors `without` openedDoor)
return $ if playerFinalGuess == doorWithCar then Win else Lose
stick :: PlayerStrategy
stick x _ = return x
switch :: PlayerStrategy
switch x xs = return . head $ Set.elems $ xs `without` x
indecisive :: PlayerStrategy
indecisive _ = randomChoice
runGames :: PlayerStrategy -> Int -> IO [Result]
runGames strategy n = replicateM n $ runGame strategy
main :: IO ()
main = do
printResults stick "Stick"
printResults indecisive "Random"
printResults switch "Switch"
where printResults strategy label = do
putStrLn $ label ++ ":"
results <- runGames strategy runs
putStrLn $ map charFor results
print $ fromIntegral (length $ filter (Win ==) results) / fromIntegral runs
runs = 100
charFor Lose = '.'
charFor Win = 'X'
Stick:
.XX....X.X.X....X.X...X.X.....XX....X..........XX..X.....XXX.XXXX.......X.......X.X....X.X.XX.XX...X
0.32
Random:
X..XXXXX.X...X..X.X..X.X.X.XX.XX...X..X.XX.XX.....X.......XX.XX.X...XXX.XXXX..X...XX.XXX..XXX.XX..XX
0.49
Switch:
.......XX.XXXXX...XX...XX..X......XXXX......XXX.XX.XX..X.XXXXX.X...X.XX....XXX..XXXX.X.XX.X.X.X.X.X.
0.48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment