Skip to content

Instantly share code, notes, and snippets.

@neongreen
Last active April 18, 2016 10:22
Show Gist options
  • Save neongreen/96384198675b99fb87cc152a43edf3f0 to your computer and use it in GitHub Desktop.
Save neongreen/96384198675b99fb87cc152a43edf3f0 to your computer and use it in GitHub Desktop.
import System.Random
import Control.Arrow
import Control.Monad
import Text.Printf
run :: Int -> Int -> IO ()
run newPills pillsMin = step newPills pillsMin 1 [] []
step :: Int -> Int -> Int -> [Double] -> [Double] -> IO ()
step newPills pillsMin day pills eaten = do
-- Morning: half a day has passed and the pills have aged again; also, if
-- there's less than X pills left, some more pills are added
pills <- return $ if length pills <= pillsMin
then map (+0.5) pills ++ replicate newPills 0
else map (+0.5) pills
-- Night: half a day has passed, the pills have aged
pills <- return (map (+0.5) pills)
-- Eat a pill (chosen randomly)
i <- randomRIO (0, length pills - 1)
eaten <- return ((pills !! i) : eaten)
pills <- return (uncurry (++) $ second tail $ splitAt i pills)
-- Stats are printed and the next day begins
when (day `mod` 10 == 0) $
printf "%d: average = %.2f, max = %.2f\n"
day (sum eaten / fromIntegral day) (maximum eaten)
unless (day == 360) $
step newPills pillsMin (day+1) pills eaten
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment