The 10th problem in Project Euler:
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
I found this snippet :
sieve = [True] * 2000000 # Sieve is faster for 2M primes
def mark(sieve, x):
for i in xrange(x+x, len(sieve), x):
sieve[i] = False
for x in xrange(2, int(len(sieve) ** 0.5) + 1):
if sieve[x]: mark(sieve, x)
print sum(i for i in xrange(2, len(sieve)) if sieve[i])
published here which run for 3 seconds.
I wrote this code:
def isprime(n):
for x in xrange(3, int(n**0.5)+1):
if n % x == 0:
return False
return True
sum=0;
for i in xrange(1,int(2e6),2):
if isprime(i):
sum += i
I don't understand why my code (the second one) is much slower?
Your algorithm is checking every number individually from 2 to N (where N=2000000) for primality.
Snippet-1 uses the sieve of Eratosthenes algorithm, discovered about 2200 years ago. It does not check every number but:
So the algorithm produces all primes up to N.
Notice that it does not do any division, only additions (not even multiplications, and not that it matters with so small numbers but it might with bigger ones). Time complexity is O(n loglogn)
while your algorithm has something near O(n^(3/2))
(or O(n^(3/2) / logn)
as @Daniel Fischer commented), assuming divisions cost the same as multiplications.
From the Wikipedia (linked above) article:
Time complexity in the random access machine model is O(n log log n) operations, a direct consequence of the fact that the prime harmonic series asymptotically approaches
log log n
.
(with n = 2e6
in this case)
The first version pre-computes all the primes in the range and stores them in the sieve
array, then finding the solution is a simple matter of adding the primes in the array. It can be seen as a form of memoization.
The second version tests for each number in the range to see if it is prime, repeating a lot of work already made by previous calculations.
In conclusion, the first version avoids re-computing values, whereas the second version performs the same operations again and again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With