
Sieve of Eratosthenes in Python (2015) - ColinWright
http://www.solipsys.co.uk/new/SieveOfEratosthenesInPython.html
======
hyperfekt
For anyone interested in implementations of the Sieve of Erastothenes, here is
a very interesting paper about functional ones, which are harder than they
appear at first: [https://www.cs.hmc.edu/~oneill/papers/Sieve-
JFP.pdf](https://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf)

~~~
bjoli
I implemented that in chez scheme recently, and it is pretty darn fast.

[https://bitbucket.org/bjoli/primes/src](https://bitbucket.org/bjoli/primes/src)
(the file lazy-prime-sieve.scm)

it uses Nietzsche which can be found in my repos. On my three year old
computer, it computes the first ten million primes in about 40 seconds (up to,
and including 179424673). That is only about 4 times slower than the optimized
non-lazy naive sieve.

~~~
agumonkey
Years don't tell much, what kind of CPU is it ? Still very nice to see.

~~~
bjoli
It is an Ivy Bridge or Haswell mobile i7. It was pretty high en for a laptop
in late 2013/early 2014.

------
nayuki
The sieve of Eratosthenes can be adapted to build tables of other number
properties: smallest prime factor, totient function, number of unique prime
factors (omega), product of unique prime factors (radical).

Contains code in Python and other languages: [https://www.nayuki.io/page/the-
versatile-sieve-of-eratosthen...](https://www.nayuki.io/page/the-versatile-
sieve-of-eratosthenes)

------
wyldfire
I first learned of this sieve while reviewing the code for the Primecoin
proof-of-work. Primecoin is a cryptocurrency that tries to have its PoW
provide greater utility than hashing, but its PoW otherwise is similar to
hashing. The task is to produce Cunningham chains [1] of prime numbers. The
reference implementation of Primecoin computes primes using the Sieve of
Eratosthenes (w/arbitrary precision integer math).

[1]
[https://en.wikipedia.org/wiki/Cunningham_chain](https://en.wikipedia.org/wiki/Cunningham_chain)

~~~
Bromskloss
What is the use of producing these primes?

------
hal9000xp
Here is very concise implementation of sieve I use in algorithm contests:

    
    
      int n = 100;
      vector<int> p(n);
    
      void sieve()
      {
          for(int i = 2; i < n; i++)
              for(int j = i; j < n; j += i) p[j]++;
      }
    
      int is_prime(int k)
      {
          return p[k] == 1;
      }

~~~
jventura
There's a small optimization on the original article which I think your
implementation doesn't do: "At each stage we know that every composite number
up to p^2 has definitely been marked as such"..

Assuming your implementation is working fine (didn't test it), I think the
change would be j = i * i on the inline for:

    
    
      void sieve()
      {
          for(int i = 2; i < n; i++)
              for (int j = i*i; j < n; j += i) p[j]++;
      }
    

It's tricky to explain, but take for instance the numbers from 1 to 20. When
i=2, it will clear [4, 6, 8, 10, 12, 14, 16, 18, 20] as non-primes. So when
i=3, you can skip 6 (which was cleared by i=2) and start directly at 9 (i * i
= 3 * 3) to clear [9, 12, 15, 18]. Also, when i=4, you can skip the 8 and 12
(which were cleared by i=2 and i=3) and start on 16 to clear [16, 20].
Finally, when i=5, you can start directly at 25 (out of bounds in this case)
because 10, 15 and 20 were already cleared by the previous iterations..

Edit: But as other posters are saying below, the original sieves algorithm
shouldn't even have to test i=4 because the numbers it clears (naivelly
[4,8,12,16,20]) have already been cleared by the previous iterations of the
algorithm.

~~~
stabbles
Maybe stop the outer loop as soon as i * i > n then as well.

Also, where's the check whether `i` is actually prime before you start
crossing off multiples? You don't need to cross off multiples of composite
numbers.

~~~
jventura
> Also, where's the check whether `i` is actually prime before you start
> crossing of multiples? You don't need to cross off multiples of composite
> numbers.

You are absolutely right as the original method seems to specify that. I've
edited my answer to show it.

So the function would be something like (untested):

    
    
      void sieve()
      {
          for (int i = 2; i*i < n; i++)
              if (p[i] == 1)
                  for (int j = i*i; j < n; j += i) p[j]++;
      }
    

There's the problem, as other posters are saying, that if p[j] == 1 is because
it was cleared as non-prime, but I've just tested p[i] == 1 for primality for
coherence with the original author.

------
stabbles
In C++ we do it compile time :) [http://stoppels.blog/posts/compile-time-
primes#a-compile-tim...](http://stoppels.blog/posts/compile-time-
primes#a-compile-time-prime-sieve-for-counting-prime-numbers)

~~~
mjcohen
Back about 1964, when I was learning to program (IBM 7090 in assembly
language), I did it at assembly time in the surprisingly powerful IBM 7090
macro assembly language. Probably somewhat slower.

~~~
stabbles
Do you still have a reference for that?

------
dahart
Re: the 'more Dynamic"' version, have you seen the amazing postponed sieve
generator?

This is the ' _really_ Dynamic' version, it recursively treats all previous
primes as a special case.

[https://stackoverflow.com/questions/2211990/how-to-
implement...](https://stackoverflow.com/questions/2211990/how-to-implement-an-
efficient-infinite-generator-of-prime-numbers-in-python/10733621#10733621)

------
squashmode
This is a well written post. It's not new stuff, but the combination of the
sieve, along with the python code makes it pretty accessible.

The site itself is actually really interesting, I never knew about Russian
Peasant Multiplication before [0].

EDIT: Fixed typo in link, thanks!

[0]
[http://www.solipsys.co.uk/new/RussianPeasantMultiplication.h...](http://www.solipsys.co.uk/new/RussianPeasantMultiplication.html)

~~~
ColinWright
Thanks for fixing the link - I was going to remove this comment for the sake
of being tidy (sys admin thinking) but it appears I can't delete it, only edit
it.

So I've done that.

Cheers!

~~~
SomeStupidPoint
( It's okay not to tidy up all the history.

Have a good day everyone!

------
e12e
Reminds me of some code I wrote for a codeeval challenge for returning the sum
of all primes up to n inclusive. IE: sum_primes(2) = 2, sum_primes(3) = 2+3 =
5 = sum_primes(4)...

It's odd that this version doesn't use a set(), but dictionary/list.

Anyway, I'll have to refactoring my code and measure against op - although I
only used the python as a reference to sanity-check my naive c++ code:

[https://github.com/e12e/codeeval/blob/master/4-sumprime/prim...](https://github.com/e12e/codeeval/blob/master/4-sumprime/primes.py)

(I believe, like most(?) codeeval challenges, this is from project Euler)

[ed: should probably add that this isn't a sieve]

------
deckar01
I usually use this sieve any time I need to work with small prime numbers, but
I dug deeper into probabilistic primality tests recently. If you try to run a
sieve on large numbers you quickly realize that it is not feasible.
Probabilistic primality tests like the Miller-Rabin are very fast and
incredibly accurate, yet they are nearly as simple as this sieve. I didn't
fully trust RSA until I learned enough about Miller-Rabin to convince myself
the prime numbers it uses are safe.

------
chris-laffra
If you want to do your own visualizations using PyAlgoViz, check out
[http://chrislaffra.blogspot.nl/2016/12/generating-prime-
numb...](http://chrislaffra.blogspot.nl/2016/12/generating-prime-numbers.html)

------
ineptech
very slightly relevant:

    
    
        Upon a stack of bits, about so tall,
        just think, O traveller, what we could do
        if every other bit was set to false
        beginning with (but not including) two?
        
        Now take two lowly numbers, A and B
        that equal three and two. What would happen
        if they, by twos and ones respectively,
        were incremented in a nested fashion,
        
        And if we falsified, at every turn,
        the value offset by A groups of Bs?
        Then to the aether let those bits return,
        to fly back home to Eratosthenes!
    

from www.ineptech.com (the "Langston" example)

------
ez3chi3l
The Eratosthenes sieve is pretty basic. I would expect any programmer to be
able to do it on the whiteboard. Now the quadratic sieve, that is a challenge.
The GNFS even more so.

~~~
credit_guy
These sieves are indeed much more complex, but are not really related to the
sieve of Erathostenes except in name. Not clear why you bring them up.

