public
Last active

  • Download Gist
prob_xkcd.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.