Haskell Quiz/Probable Iterations/Solution Dolio
< Haskell Quiz | Probable Iterations
This quiz was pretty simple. The list monad makes generation of the test cases simple, and the writer monad is handy for capturing potential output for each line. I used a DList for the writer accumulator to avoid repeated copying.
module Main where import Data.DList import Control.Monad.Writer.Lazy import System.Environment import System.Exit import Control.Monad import Text.Printf die = [1..6] check :: ([Int] -> Bool) -> (Int, [Int]) -> Writer (DList String) Bool check p (line, roll) = do tell $ if b then singleton hit else singleton noHit ; return b where b = p roll noHit = printf "%12d %s" line (show roll) hit = noHit ++ " <==" sample :: Int -> Int -> (Int, (Int, DList String)) sample i j = (length l, runWriter . liftM length . filterM (check p) $ zip [1..] l) where p l = length (filter (==5) l) >= j l = replicateM i die chop :: [a] -> [a] chop  =  chop (x:xs) = x : chop (drop 49999 xs) main = do (v,s,i,j) <- processArgs let (total, (selected, out)) = sample i j if v then mapM_ putStrLn $ toList out else when s . mapM_ putStrLn . chop $ toList out putStrLn "" putStr "Number of desirable outcomes is " print selected putStr "Number of possible outcomes is " print total putStrLn "" putStr "Probability is " print $ fromIntegral selected / fromIntegral total processArgs = do l <- getArgs case l of [i,j] -> return (False, False, read i, read j) ["-v", i, j] -> return (True, False, read i, read j) ["-s", i, j] -> return (False, True, read i, read j) _ -> do putStrLn "Unrecognized arguments." exitFailure