fork download
  1. {-# OPTIONS_GHC -O2 #-}
  2. {-# LANGUAGE MonoLocalBinds #-}
  3. import Control.Monad (forM_, when)
  4. import Control.Monad.ST
  5. import Control.Arrow -- based on Daniel Fischer's code from
  6. import Data.Array.ST -- stackoverflow.com/a/15026238/849891
  7. import Data.Array.Unboxed
  8. import Data.Array.Base
  9.  
  10. primeSieve :: Int -> UArray Int Bool
  11. primeSieve top = runSTUArray $ do
  12. a <- newArray (0,top) True -- two extra at start: '0', '1'
  13. let r = ceiling . sqrt $ fromIntegral top
  14. mark step idx
  15. | top < idx = return ()
  16. | otherwise = do
  17. unsafeWrite a idx False -- unsafe: idx from start
  18. mark step (idx+step)
  19. sift p
  20. | r < p = return a
  21. | otherwise = do
  22. prim <- unsafeRead a p
  23. when prim $ mark (2*p) (p*p)
  24. sift (p+2)
  25. mark 2 4
  26. sift 3
  27.  
  28. -- Return primes from sieve as list:
  29. primesTo :: Int -> [Int]
  30. primesTo top = drop 2 [p | (p,True) <- assocs $ primeSieve top]
  31.  
  32. main :: IO ()
  33. main1 = print . ( length &&& last) $ primesTo 20000000 -- 10mln: x=9999991 0.09s-7.7M
  34. -- main = print . ( last) $ primesTo 20000000 -- n=664579 0.17s-7.8M list:0.27-30.3
  35.  
  36. main = do -- 20mln: x=19999999 0.20s-8.8M
  37. let a = primeSieve 104395305 -- n=1270607 0.37s-8.8M list:0.54-38.4
  38. (0,t) = bounds a
  39. p = head [idx | idx <- [t,t-1..2], a!idx] -- top prime
  40. n = length [ () | (p,True) <- assocs a] - 2
  41. print (n, p) -- see also: ideone.com/j24jxV
  42. {- Success time: 2.55 memory: 9304 signal:0
  43.   (6000001,104395303) -}
Success #stdin #stdout 2.55s 9304KB
stdin
Standard input is empty
stdout
(6000001,104395303)