Skip to content

Instantly share code, notes, and snippets.

@vivax3794
Created May 15, 2021 00:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vivax3794/ca1ee7f2dea6256c4cfdd331c58c007f to your computer and use it in GitHub Desktop.
Save vivax3794/ca1ee7f2dea6256c4cfdd331c58c007f to your computer and use it in GitHub Desktop.
import System.Random
import Data.List
import Control.Monad
type StepTwoChoice = IO Int
type StepFourChoice = Int -> IO Bool
data Stratergy = Stratergy
{ setpTwo :: StepTwoChoice,
stepFour :: StepFourChoice
}
simulationAmount :: Num n => n
simulationAmount = 1000
alice :: Stratergy
alice = Stratergy (return 1) (const (return False))
bob :: Stratergy
bob = Stratergy (return 1) (const (return True))
carol :: Stratergy
carol = Stratergy (randomRIO (1, 3)) randomBool
where randomBool _ = toEnum <$> randomRIO (0, 1)
dave :: Stratergy
dave = Stratergy (randomRIO (1, 3)) (const (return False))
erin :: Stratergy
erin = Stratergy (randomRIO (1, 3)) (const (return True))
frank :: Stratergy
frank = Stratergy (return 1) fourth
where fourth a = return $ a == 2
pickStillClosedDoor :: Int -> Int -> IO Int
pickStillClosedDoor winning_door picked_door =
if winning_door == picked_door
then do
index <- randomRIO (0, 1)
return $ remaining !! index
else return winning_door
where remaining = [door | door <- [1,2,3], door /= picked_door]
game :: Stratergy -> IO Bool
game (Stratergy first second) = do
winning_door <- randomRIO (1, 3)
first_choice <- first
closedDoor <- pickStillClosedDoor winning_door first_choice
swap <- second closedDoor
let final_choice = if swap then closedDoor else first_choice
return $ final_choice == winning_door
boolToFloat :: Bool -> Float
boolToFloat True = 1
boolToFloat False = 0
simulate :: Stratergy -> IO Float
simulate strat = do
games <- replicateM simulationAmount $ game strat
let won = sum $ map boolToFloat games
return $ won / simulationAmount
strats = [
("alice", alice)
,("bob", bob)
,("carol", carol)
,("dave", dave)
,("erin", erin)
,("frank", frank)
]
main = do
forM_ strats $ \(name, strat) -> do
result <- simulate strat
let prosent = round $ result * 100
putStrLn $ name ++ " won " ++ show prosent ++ "%"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment