fork(4) download
  1. {-# OPTIONS_GHC -O2 #-}
  2.  
  3. module Main where
  4.  
  5. import Data.Array.Unboxed
  6.  
  7. main = do spec <- map read . take 2 . words <$> getLine
  8. case spec of
  9. -- [n] -> print . take 10 . drop (n-10) $ primesTMWE
  10. [n,lim] -> print $ primesLimAOE lim n
  11.  
  12. -- array-based Sieve of Eratosthenes, using an array that is passed as
  13. -- an accumulating argument between steps of iterative computation, and
  14. -- as such is liable to the destructive update (doesn't happen, but still is fast,
  15. -- on unboxed arrays, with explicit type signature, GHC-compiled with -O2),
  16. -- working with odds only (original: ideone.com/dE0iU)
  17.  
  18. primesLimAOE :: Int -> Int -> (Int,[Int])
  19. primesLimAOE m n | m > 2 = sieve 3 ( accumArray const True (1,m2) [] )
  20. where
  21. m2 = (m-1) `div` 2
  22. r = floor . sqrt $ fromIntegral m + 1
  23. sieve :: Int -> UArray Int Bool -> (Int, [Int]) -- 2017: moved type decl here
  24. sieve p a
  25. | p > r = let k = 10
  26. (l,u) = bounds a
  27. len = 1 + length [() | (i,True) <- assocs a]
  28. ixs = reverse $ take (len-n+k) [i | i<-[u,u-1..l], a!i]
  29. last = (if len < n then [2] else []) ++
  30. [2*i+1 | i <- take k ixs]
  31. in ( len, last )
  32. | a!p2 = sieve (p+2) $ a//[(i,False) | i <- [q2, q2+p..m2]]
  33. | otherwise = sieve (p+2) a
  34. where p2 = (p-1) `div` 2
  35. q2 = (p*p-1) `div` 2
  36.  
  37. -- 2017: NB: newer compiler currently in use runs this code almost 3x faster.
  38. -- abPSOx-derived code (for odds, that is) might be faster.
  39.  
  40. -- 1m:78498:0.04-4.8 2750159:200k:0.09-4.8 5800079:400k:0.21-5.8 15485863:1m:0.67-7.8 32452843:2m:2.16-11.9
  41.  
  42. -- 67867967:4m:5.63-24.2 104395301:6m:9.84-39.6 122949823:7m:12.20-36.5 141650939:8m:14.61-40.6
Success #stdin #stdout 0.31s 8388607KB
stdin
1000000 15485863    (older Ideone used GHC (6.8....))
400000 5800079     (now it's twice slower, with GHC (7.6.3) ...?)
stdout
(1000000,[15485761,15485773,15485783,15485801,15485807,15485837,15485843,15485849,15485857,15485863])