8

I was searching for an algorithm to generate prime numbers. I found the following one done by Robert William Hanks. It is very efficient and better than the other algorithms but I can not understand the math behind it.

def primes(n):
    """ Returns  a list of primes < n """
    lis = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if lis[i]:
            lis[i*i::2*i]=[False]*int((n-i*i-1)/(2*i)+1)
    return [2] + [i for i in range(3,n,2) if lis[i]]

What is the relation between the array of Trues values and the final prime numbers array?

Ma0
  • 14,004
  • 2
  • 29
  • 59
Mu-Majid
  • 771
  • 7
  • 14
  • 3
    Looks like it's using the Sieve of Eratosthenes. – ForceBru Mar 15 '17 at 13:23
  • 1
    That code from [this answer](http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188) is basically a slightly optimized Sieve of Eratosthenes. Note that it's Python 2 code, it needs a couple of tweaks for use on Python 3. FWIW, I have a Python 3 version of RWH's code in [this answer](http://stackoverflow.com/a/38743446/4014959). – PM 2Ring Mar 15 '17 at 13:24
  • 4
    Walk through it with `n = 6`, write down (on paper) the value of `lis` and `i` as you go through the loop. – Peter Wood Mar 15 '17 at 13:30
  • 1
    None of the answers in the suggested dupe target replicate Robert William Hanks' code exactly, although the general principle is explained there. Maybe RWH himself will see this question... – PM 2Ring Mar 15 '17 at 14:01
  • Algorithm fails if `n < 2` – Brian J Murray Mar 15 '17 at 14:32
  • 2
    BTW, using `//` is more efficient than using float division and converting the result. That is, `lis[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)` – PM 2Ring May 16 '18 at 18:54

1 Answers1

8

Starting with n True values in an array, with i enumerated from 3 to sqrt(n) by the step of 2, if the ith entry in the array is still True, set to False all entries from i^2 to the end of the array by the step of 2*i (these all will be multiples of i).

All odd True entries above 1 that are left in the array in the end, are prime.

All thus found numbers, and 2, are all the prime numbers that exist below n.

Will Ness
  • 62,652
  • 8
  • 86
  • 167