Project Euler Problem #87

Problem #87 concerns numbers which can be written as the sum of a perfect square, a perfect cube, and a perfect fourth power of prime numbers. The question reads:

Project Euler Problem 87: Prime power triples
The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is 28. In fact, there are exactly four numbers below fifty that can be expressed in such a way:
28 = 2^2 + 2^3 + 2^4
33 = 3^2 + 2^3 + 2^4
49 = 5^2 + 2^3 + 2^4
47 = 2^2 + 3^3 + 2^5
How many numbers below fifty million can be expressed as the sum of a prime square, prime cube, and prime fourth power?

My solution to this is probably vastly inefficient. Here is my solution:

Solution #1: Brute Force Sieve Approach

First we use the Sieve of Eratosthenes to list all primes up to the square root of 50,000,000. Then we make lists of all the perfect squares, perfect cubes, and perfect fourth powers of those primes which are less than 50,000,000. Finally, we make a list with boolean values representing whether each number from 0 to 50,000,000 can be represented and update the list for every triple of a prime square, a prime cube, and a prime fourth power. Finally, we iterate through the list to count the numbers which can be represented. Here is an implementation of this approach in Python 2.7:

 '''
 Author: Walker Kroubalkian
 Sieve Approach to Project Euler Problem #87
 '''
 
 import time
 from math import sqrt
 
 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 projectEulerProblemEightySeven(n):
     primes = sieveEratosthenes(int(sqrt(n)))
     squares = []
     cubes = []
     fourths = []
     cubeDone = False
     fourthDone = False
     for p in primes:
         squares.append(p*p)
         if not cubeDone:
             c = p*p*p
             if(c>n):
                 cubeDone = True
             else:
                 cubes.append(c)
         if not fourthDone:
             f = p*p*p*p
             if(f>n):
                 fourthDone = True
             else:
                 fourths.append(f)
     found = [False]*(n+1)
     for a in squares:
         for b in cubes:
             if (b+a)>n:
                 break
             for c in fourths:
                 s = a+b+c
                 if s>n:
                     break
                 else:
                     found[s] = True
     total = 0
     for x in found:
         if x:
             total+=1
     return total                
 
 start = time.time()
 print projectEulerProblemEightySeven(50000000)
 print ("--- %s seconds ---" % (time.time()-start))
 
 '''
 Prints
 
 1097343
 --- 0.985231161118 seconds ---
 
 for input of n = 50000000.
 ''' 

And with that, we’re done. That took nearly a second to run. I believe there is probably a faster way to do this, but this was the most efficient method that I could think of. I may return 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