Create a gist now

Instantly share code, notes, and snippets.

import Control.Monad.Random
import Control.Monad.Writer
type Sim = Rand StdGen
-- returns the series of rolls, with the final 6 omitted (implied)
simGame :: Sim [Int]
simGame = do
roll <- getRandomR (1,6)
if roll == 6
then return []
else fmap (roll:) simGame
-- bob wins if there were an odd number of rolls before a 6
bobWins :: [Int] -> Bool
bobWins = odd . length
bobWinsSecondTurn :: [Int] -> Bool
bobWinsSecondTurn rolls = length rolls == 3
-- returns a list of ever-refining probabilities
simulate :: Sim [Double]
simulate = execWriterT (go 0 0)
where
go tries successes = do
tell [successes/tries]
game <- lift simGame
go (inc (bobWins game) tries) (inc (bobWinsSecondTurn game) successes)
-- converts a bool into an incrementor function
-- (if true, adds one, else leaves alone)
inc True = (+1)
inc False = id
main = mapM_ print =<< fmap (evalRand simulate) newStdGen
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment