|
1 | 1 | '''
|
2 | 2 | Using sieve of Eratosthenes, primes(x) returns list of all primes less than x
|
| 3 | +
|
| 4 | +Modification: |
| 5 | +We don't need to check all even numbers, we can make the sieve excluding even |
| 6 | +numbers and adding 2 to the primes list by default. |
| 7 | +
|
| 8 | +We are going to make an array of: x / 2 - 1 if number is even, else x / 2 |
| 9 | +(The -1 with even number it's to exclude the number itself) |
| 10 | +Because we just need numbers [from 3..x if x is odd] |
| 11 | +
|
| 12 | +# We can get value represented at index i with (i*2 + 3) |
| 13 | +
|
| 14 | +For example, for x = 10, we start with an array of x / 2 - 1 = 4 |
| 15 | +[1, 1, 1, 1] |
| 16 | + 3 5 7 9 |
| 17 | +
|
| 18 | +For x = 11: |
| 19 | +[1, 1, 1, 1, 1] |
| 20 | + 3 5 7 9 11 # 11 is odd, it's included in the list |
| 21 | +
|
| 22 | +With this, we have reduced the array size to a half, |
| 23 | +and complexity it's also a half now. |
3 | 24 | '''
|
4 | 25 |
|
5 | 26 | def primes(x):
|
6 |
| - assert(x>=0) |
7 |
| - sieve = [1 for v in range(x+1)] # Sieve |
8 |
| - primes = [] # List of Primes |
9 |
| - for i in range(2,x+1): |
10 |
| - if sieve[i]==1: |
11 |
| - primes.append(i) |
12 |
| - for j in range(i,x+1,i): |
13 |
| - sieve[j]=0 |
| 27 | + assert(x >= 0) |
| 28 | + # If x is even, exclude x from list (-1): |
| 29 | + sieve_size = (x//2 - 1) if x % 2 == 0 else (x//2) |
| 30 | + sieve = [1 for v in range(sieve_size)] # Sieve |
| 31 | + primes = [] # List of Primes |
| 32 | + if x >= 2: |
| 33 | + primes.append(2) # Add 2 by default |
| 34 | + for i in range(0, sieve_size): |
| 35 | + if sieve[i] == 1: |
| 36 | + value_at_i = i*2 + 3 |
| 37 | + primes.append(value_at_i) |
| 38 | + for j in range(i, sieve_size, value_at_i): |
| 39 | + sieve[j] = 0 |
14 | 40 | return primes
|
0 commit comments