fork(3) download
  1. {-# OPTIONS_GHC -O2 #-}
  2.  
  3. import Control.Monad
  4. import Control.Monad.ST
  5. import Data.Array.ST
  6. import Data.Array.Unboxed
  7. import Data.Char
  8.  
  9.  
  10. main = do
  11. forM_ (takeWhile (isDigit . head) $ words s) $ \w-> do
  12. -- let ps = primesTo (read w)
  13. -- print (length ps, last ps) -- leaks badly
  14. print (lastPrimes (read w)) -- no leak
  15.  
  16. sieveUA :: Int -> UArray Int Bool
  17. sieveUA top = runSTUArray $ do
  18. let m = (top-1) `div` 2
  19. r = floor . sqrt . fromIntegral $ top + 1
  20. sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)
  21. forM_ [1..r `div` 2] $ \i -> do
  22. isPrime <- readArray sieve i
  23. when isPrime $ -- ((2*i+1)^2-1)`div`2 = 2*i*(i+1)
  24. forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j ->
  25. writeArray sieve j False
  26. return sieve
  27.  
  28. primesTo :: Int -> [Int]
  29. primesTo top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]
  30.  
  31. lastPrimes :: Int -> (Int,[Int]) -- (nth, vals)
  32. lastPrimes top =
  33. let arr = sieveUA top
  34. (b,t) = bounds arr
  35. in
  36. ( 1 + length [() | (i,True) <- assocs arr]
  37. , (if (top < 13) then (2:) else id)
  38. $ reverse $ take 5 [ 2*i+1 | i <- [t,t-1..b], arr ! i ] )
  39.  
  40. {-
  41. ST Array [Int] ON ODDS
  42.   -= n =- -= top =-
  43.   30,000: 350,377: 0.01s 3.7MB
  44.   100,000: 1,299,709: 0.03s 3.7MB
  45.   300,000: 4,256,233: 0.10s 3.7MB
  46.   1 mln --> 15,485,863: 0.43s 4.8MB time space (s_0=3.7)
  47.   2 mln --> 32,452,843: 0.98s 5.8MB
  48.   4 mln --> 67,867,967: 2.31s 8.9MB 1m-> n^1.21 n^1.12
  49.   5 mln --> 86,028,121: 3.04s 9.9MB
  50.   6 mln --> 104,395,301: 3.77s 10.9MB (leak: was: ***6.7s-227MB***!!!) ****
  51. 6,500,000-> 113,648,393: 4.14s 10.9MB
  52.   7 mln --> 122,949,823: 4.52s 11.9MB
  53. 7,538,613-> 133,000,999: 4.95s 11.9MB
  54.   8 mln --> 141,650,939: 5.32s 13.0MB 4m-> n^1.20 n^0.84
  55.   9 mln --> 160,481,183: 6.12s 14.0MB
  56.  10 mln --> 179,424,673: 6.91s 15.0MB
  57.  15 mln --> 275,604,541: 11.01s 21.1MB
  58.  18 mln --> 334,214,459: 13.65s 24.2MB 8m-> n^1.16 n^0.97 (1m->n^1.01)
  59.  20 mln --> 373,587,883: TIMEOUT
  60. -}
Success #stdin #stdout 9.69s 24016KB
stdin
10
334214459
---
104395305
---
2018-06-15 rerun for current timing
6 mln primes, limit 104395301, was 2.78s at 2013-08-12
         now it's    2.63s-10MB, ( fapob, C++ : 0.27s-8.9MB , 9.7x faster )
         so, no substantial change
18 mln to 334214459, 9.69s-24MB  ( fapob, C++ : 1.11s-22.9MB , 8.7x faster )
  n                   n ^ 1.19  
stdout
(4,[2,3,5,7])
(18000000,[334214347,334214359,334214369,334214431,334214459])