Most efficient code for the first 10000 prime numbers?

前端 未结 30 1409
日久生厌
日久生厌 2020-11-29 19:09

I want to print the first 10000 prime numbers. Can anyone give me the most efficient code for this? Clarifications:

  1. It does not matter if your code is ineffici
30条回答
  •  粉色の甜心
    2020-11-29 19:38

    In Haskell, we can write down almost word for word the mathematical definition of the sieve of Eratosthenes, "primes are natural numbers above 1 without any composite numbers, where composites are found by enumeration of each prime's multiples":

    import Data.List.Ordered (minus, union)
    
    primes = 2 : minus [3..] (foldr (\p r -> p*p : union [p*p+p, p*p+2*p..] r)
                                    [] primes)
    

    primes !! 10000 is near-instantaneous.

    References:

    • Sieve of Eratosthenes
    • Richard Bird's sieve (see pp. 10,11)
    • minus, union

    The above code is easily tweaked into working on odds only, primes = 2 : 3 : minus [5,7..] (foldr (\p r -> p*p : union [p*p+2*p, p*p+4*p..] r) [] (tail primes)). Time complexity is much improved (to just about a log factor above optimal) by folding in a tree-like structure, and space complexity is drastically improved by multistage primes production, in

    primes = 2 : _Y ( (3:) . sieve 5 . _U . map (\p -> [p*p, p*p+2*p..]) )
      where
        _Y g = g (_Y g)                        -- non-sharing fixpoint combinator
        _U ((x:xs):t) = x : (union xs . _U . pairs) t       -- ~= nub.sort.concat
        pairs    (xs:ys:t)  = union xs ys : pairs t
        sieve k s@(x:xs) | k < x      = k : sieve (k+2) s   -- ~= [k,k+2..]\\s,
                         | otherwise  =     sieve (k+2) xs  --   when s⊂[k,k+2..]
    

    (In Haskell the parentheses are used for grouping, a function call is signified just by juxtaposition, (:) is a cons operator for lists, and (.) is a functional composition operator: (f . g) x = (\y -> f (g y)) x = f (g x)).

提交回复
热议问题