fork(3) download
  1. {-# OPTIONS_GHC -O2 #-}
  2. module Main where
  3. import Data.List (tails)
  4. main = print $ primes !! 1000000 -- -fno-cse -fno-full-laziness
  5.  
  6. primes0 = _Y $ (2:) . minus [3..] .
  7. foldr (\p-> (p*p :) . union [p*p+p, p*p+2*p..]) []
  8.  
  9. primes :: [Int]
  10. primes = [2,3,5,7] ++ _Y ((11:) . tail . minus (scanl (+) 11 wh11)
  11. . foldi (\(x:xs)-> (x:) . union xs)
  12. . map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)
  13. . equalsBy snd (tails wh11 `zip` scanl (+) 11 wh11))
  14.  
  15. wh3 = 2:wh3 -- ([3],2) {1*2,2*3}
  16. wh5 = 2:4:wh5 -- ([5,7],6) {2*4,6*5}
  17. wh7 = 4:2:4:2:4:6:2:6:wh7 -- ([7,11,13,17,19,23,29,31],30) {8*6,30*7}
  18. wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:
  19. 4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11
  20. _Y g = g (_Y g) -- multistage with non-sharing fixpoint combinator
  21. -- = g (fix g) -- two stages with sharing fixpoint combinator
  22.  
  23. foldi f (xs:t) = f xs . foldi f . pairs f $ t
  24. pairs f (x:y:t) = f x y : pairs f t
  25.  
  26. union a@(x:xs) b@(y:ys) = case compare x y of
  27. LT -> x : union xs b
  28. EQ -> x : union xs ys
  29. GT -> y : union a ys
  30. minus a@(x:xs) b@(y:ys) = case compare x y of
  31. LT -> x : minus xs b
  32. EQ -> minus xs ys
  33. GT -> minus a ys
  34. equalsBy f a@(x:xs) b@(y:ys) = case compare (f x) y of
  35. LT -> equalsBy f xs b
  36. EQ -> x : equalsBy f xs ys
  37. GT -> equalsBy f a ys
Success #stdin #stdout 2.55s 9312KB
stdin
1mln: 2.50s - 9.4 M                  ordmergeBy : 4.44s - 9.4 M
2mln: 5.90s - 9.3 M     n^1.24                    9.91s - 9.4 M    n^1.16
3mln: 9.29s - 9.4 M     n^1.12

-- something changed on 2013-07-31:
-- suddenly `minus (scanl (+) 11 wh11)` doesn't cause HUGE space leak anymore !??!!
--  and runs slower that gaps/hits (see vkXCXt). -- IDEONE SWITCHED from 7.4.1 to 7.6.3 !....
-- (map (p*) $ scanl (+) p w): 3.15s ... 6.91s , 9.3 MB   n^1.13

-- ...... and in 7.8.3 it LEAKS AGAIN like crazy!!   only gaps/hits doesn't leak
stdout
15485867