{-# OPTIONS -cpp -fglasgow-exts -fvia-C -optc-O2 -optc-msse2 -optc-march=pentium4 -optc-ffast-math -fexcess-precision #-} #if defined(FAST) import System.Random.Mersenne #else import System.Random #endif import System.Environment #if defined(FAST) main = do [lim] <- mapM readIO =<< getArgs g <- newMTGen Nothing let go :: Int -> Int -> IO Double go throws ins | throws >= lim = return ((4 * fromIntegral ins) / (fromIntegral throws)) | otherwise = do x <- random g :: IO Double y <- random g :: IO Double if x * x + y * y < 1 then go (throws+1) $! ins + 1 else go (throws+1) ins print =<< go 0 0 {- $ time ./pi 100000000 3.14166916 ./pi 100000000 4.31s user 0.00s system 99% cpu 4.311 total -} #else main = do [lim] <- mapM readIO =<< getArgs g <- newStdGen let go :: StdGen -> Int -> Int -> IO Double go g throws ins | throws >= lim = return ((4 * fromIntegral ins) / (fromIntegral throws)) | otherwise = do let (x::Double,g1) = random g (y::Double,g2) = random g1 if x * x + y * y < 1 then go g2 (throws+1) $! ins + 1 else go g2 (throws+1) ins print =<< go g 0 0 #endif