Project Euler Problem #50

Problem #50 involves sums of consecutive primes. The question reads:

Project Euler Problem 50: Consecutive prime sum
The prime 41, can be written as the sum of six consecutive primes:
41 = 2 + 3 + 5 + 7 + 11 + 13
This is the longest sum of consecutive primes that adds to a prime below one-hundred.
The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953.
Which prime, below one-million, can be written as the sum of the most consecutive primes?

If you’ve seen my solutions to other Project Euler problems that involve primes, you can probably guess that my solution involves the Sieve of Eratosthenes. Here is my solution:

Solution #1: Brute Force Sieve Approach

We simply iterate through the sums of different numbers of consecutive primes until the minimum sum of the given number of consecutive primes is greater than 1,000,000. We can use a sieve to list all of the primes less than 1,000,000, and we can use binary search to check if a given sum is in the list of primes. Here is an implementation of this approach in Python 2.7:

 '''
 Author: Walker Kroubalkian
 Sieve Approach to Project Euler Problem #50
 '''
 
 import time
 
 def sieveEratosthenes(n):
     myPrimes = []
     
     primePossible = [True]*(n+1)
     primePossible[0] = False
     primePossible[1] = False
     
     for (i,possible) in enumerate(primePossible):
         if possible:
             for x in range(i*i, (n+1), i):
                 primePossible[x] = False
             myPrimes.append(i)
 
     return myPrimes
 
 def binarySearch(myList,v):
     lower = 0
     upper = len(myList)-1
     while(lower<upper-1):
         middle = (lower+upper)/2
         a = myList[middle]
         if a<v:
             lower = middle
         elif a>v:
             upper = middle
         else:
             return middle
     if myList[lower] == v:
         return lower
     if myList[upper] == v:
         return upper
     return -1
 
 def projectEulerProblemFifty(n):
     allPrimes = sieveEratosthenes(n)
     maxPrime = 41
     c = 7
     while(c<=n):
         total = 0
         for x in range(c):
             total+=allPrimes[x]
         if(total>n):
             return maxPrime
         if(total in allPrimes):
             maxPrime = total
         a = c
         while(a<n):
             total+=allPrimes[a]
             total-=allPrimes[a-c]
             if(total > n):
                 break
             x = binarySearch(allPrimes, total)
             if(x>=0):
                 maxPrime = total
             a+=1
         c+=1
     return maxPrime
 
 start = time.time()
 print projectEulerProblemFifty(1000000)
 print ("--- %s seconds ---" % (time.time()-start))

 '''
 Prints
 
 997651
 --- 1.33064293861 seconds ---
 
 for input of n = 1000000.
 ''' 

And with that, we’re done. While writing this, I realized that the solution can probably be greatly improved if the number of consecutive primes were to count down from the smallest number n such that the sum of the first n primes is greater than 1,000,000. Unfortunately, I am too lazy to implement this right now. I may come back to this problem eventually.

Thanks for reading! See you tomorrow.

Published by Walker Kroubalkian

My name is Walker Kroubalkian. I really enjoy math, computer science, and hiking.

Leave a comment

Design a site like this with WordPress.com
Get started