[Haskell-cafe] Re: Code and Perf. Data for Prime Finders
(was:Genuine Eratosthenes sieve)
Melissa O'Neill
oneill at cs.hmc.edu
Sun Feb 25 14:37:39 EST 2007
Claus Reinke wrote:
> folklore3: merging the sieves, instead of stacking them as
> implicit thunks
Here's Claus's code:
primes3 = 2 : folklore3 [] [3,5..]
> folklore3 pns xs = x : folklore3 (insert (x,x*x) pns') xs'
> where (x,pns',xs') = sieve3 pns xs
>
> sieve3 ((p,n):pns) (x:xs) | x<n = (x,((p,n):pns),xs)
> | otherwise = sieve3 (insert (p,(n+p))
> pns) ([x|x>n]++xs)
> sieve3 [] (x:xs) = (x,[],xs)
>
> insert (p,n) [] = [(p,n)]
> insert (p,n) ((p',n'):pns) | n<=n' = (p,n):(p',n'):pns
> | otherwise = (p',n'):insert (p,n) pns
This isn't a variant of the "folklore sieve", it's actually the real
one! Let's take a look at ``pns'' at the 20th prime, having just
found that 67 is prime (we're about to discover that 71 is prime):
[(3,69),(5,70),(7,70),(11,121),(13,169),(17,289),(19,361),(23,529),
(29,841),(31,961),(37,1369),(41,1681),(43,1849),(47,2209),(53,2809),
(59,3481),(61,3721),(67,4489)]
As you can see, 70 will be crossed off twice, once by the 5 iterator
and once by the iterator for 7. And we won't think about 11, 13,
etc. until they're needed.
This algorithm is doing pretty much exactly what mine does, except
that in mine I use a priority queue to represent this information.
In fact, with my most recent code, I'd only store (3,69), (5,70),
(7,70) in the priority queue and keep (11,121), (13,169), ...,
(67,4489) in a feeder queue so that I only use the power of the
priority queue when I need it.
Melissa.
P.S. Mine actually wouldn't have quite the same numbers, because I go
to a bit of trouble to skip numbers like 70 which will never actually
show up in the x:xs list.
More information about the Haskell-Cafe
mailing list