import qualified Data.IntMap as I
import Control.Monad
import Data.List
import Data.Maybe
import System.Random
main :: IO ()
main = do
let f d =
print =<< (fmap (count (length d)) $ replicateM 100000 $ rollIkasamaDice d)
rd = take 6 $ cycle [1,2]
rd1 = map sqrt [1..4]
rd2 = replicate 9 1
mapM_ f [rd, rd1, rd2]
count :: (Enum a, Num a) => I.Key -> [I.Key] -> I.IntMap a
count len = foldr (I.update ((Just $!) . succ)) (I.fromList $ zip [1..len] [0,0..])
rollIkasamaDice :: [Double] -> IO Int
{-# INLINE rollIkasamaDice #-}
rollIkasamaDice dist = do
r <- getStdRandom (randomR (0, 1)) :: IO Double
return $ snd $ fromJust $ find ((r <=) . fst) dice
where
thr = scanl1 (+) $ map . flip (/) =<< sum $ dist
dice = zip thr [1..] :: [(Double, Int)]