Last active
December 19, 2015 12:49
-
-
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
This file contains 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
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' |
This file contains 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
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