Project Euler Problem #7:

Problem #7 is one of the many problems on Project Euler which concerns prime numbers. The question reads:

Project Euler Problem 7: 10001st prime
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.

What is the 10,001st prime number?

As discussed in my post for Problem #3, an easy way to check if a number n is prime is to check if any numbers between 2 and the square root of n are divisors of n. Using this fact, we can do the following simple brute force approach to solve this problem:

Solution #1: The Brute Force Approach

We simply check every integer starting at 2 and going up while keeping count of the number of primes that have been encountered. Once the 10,001st prime number is encountered, the program is complete. Here is an implementation of this method in Python 2.7:

 '''
 Author: Walker Kroubalkian
 Brute Force Approach to Project Euler Problem #7
 '''

 import time
 from math import sqrt

 def isPrime(n):
     c = 2
     while(c<=sqrt(n)):
         if(n%c==0):
             return False
         c+=1
     return True

 def projectEulerProblemSeven(n):
     total = 0
     c = 2
     while(total<n):
         if(isPrime(c)):
             total+=1
         c+=1
     return c-1

 start = time.time()
 print projectEulerProblemSeven(10001)
 print ("--- %s seconds ---" % (time.time()-start))

 '''
 Prints
 104743
 --- 0.310272932053 seconds ---
 for input of n = 10001
 '''

As shown above, this approach is quite decent. However, with some more complex math, we can solve this problem with another approach:

Solution #2: Sieve of Eratosthenes Approach

A well known method for compiling a list of all of the primes up to a certain point is the Sieve of Eratosthenes. This method involves listing all of the numbers up to a point and then working up the number line, crossing off any multiples of the earliest number which has not been crossed off. As it turns out, this method can be used to make this algorithm more efficient. The one problem is that the question is asking for the 10,001st prime, not the number of primes less than 10,001.

As it turns out, some upper bounds for the nth prime are known. The Prime Number Theorem tells us that the nth prime is less than or equal to n*(ln(n)+ln(ln(n))). The proof for this fact is far beyond my mathematical expertise, so I have left a link for this fact if you wish to read more about it. Using this upper bound, we can use the Sieve of Eratosthenes to list all primes up to the upper bound for the 10,001st prime and then read the 10,001st prime off the list. Here is an implementation of this method in Python 2.7:

'''
Author: Walker Kroubalkian
Sieve Approach to Project Euler Problem #7
'''

import time
from math import log

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 projectEulerProblemSeven(n):
    if(n==1):
        return 2
    elif(n==2):
        return 3
    elif(n==3):
        return 5
    pntLimit = int(n*(log(n)+log(log(n))))
    allPossible = sieveEratosthenes(pntLimit)
    return allPossible[n-1]

start = time.time()
print projectEulerProblemSeven(10001)
print ("--- %s seconds ---" % (time.time()-start))

'''
Prints

104743
--- 0.0170910358429 seconds ---

for input of n = 10001
'''

As shown above, this approach is much more efficient with a decent implementation of the Sieve of Eratosthenes. Once again, knowing some higher level math can really make the solutions for these problems more efficient.

This marks one complete week of Project Euler problems and over 1% completion of all the problems. Hooray! Thank you for reading.

Project Euler Problem #6:

Problem #6 of Project Euler is yet another example of how having a decent background in math can save you a lot of hassle when solving coding problems. The question reads:

Project Euler Problem 6: Sum Square Difference
The sum of the squares of the first ten natural numbers is

1^2 + 2^2 + . . . + 10^2 = 385

The square of the sum of the first ten natural number is

(1 + 2 + 3 + . . . + 10)^2 = 55^2 = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025-385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Clearly each of these values can be obtained by simple iteration. Add up i^2 as i ranges from 1 to 10, add up i in the same range, square the second result, and you’re done. However, we can actually solve this question entirely with some simple formulas.

Solution #1: Formulaic Approach

The first part of the question involves finding the sum of the squares of the first n natural numbers. It is well known that this sum is equal to n(n+1)(2n+1)/6. We can prove this claim easily with induction. When n = 1, the claim is true as 1^2 = 1*2*3/6 = 1. Now assume the claim is true for n = x. Then 1^2+2^2+ . . . + x^2 = x(x+1)(2x+1)/6. Adding (x+1)^2 to both sides, we get 1^2 + 2^2 + . . . + x^2 + (x+1)^2 = (2x^3+3x^2+x + 6x^2 + 12x + 6)/6 = (2x^3+9x^2+13x+6)/6 = (x+1)(x+2)(2x+3)/6. Thus, the inductive step is done, and therefore the claim is true. Therefore, we can find the sum of the squares with a formula.

The second part of the question involves finding the square of the sum of the first n natural numbers. It suffices to find a formula for the sum of the first n natural numbers. This sum is called the nth triangular number, as it represents the number of dots in an equilateral triangle made up of n rows of dots. It is well known that the nth triangular number is n(n+1)/2. Once again, we can prove this claim with induction. The base case is true as 1 = 1*2/2 = 1. Now assume the claim is true for n = x. Thus, 1 + 2 + . . . + x = x(x+1)/2. Adding x+1 to both sides, we get 1 + 2 + . . . + x + (x+1) = (x^2+x+2x+2)/2 = (x^2+3x+2)/2 = (x+1)(x+2)/2. Thus, the inductive step is done, and the claim is true. Squaring this result, we get the formula (n^2*(n+1)^2)/4. As it turns out, you can show through induction that this formula provides the sum of the cubes of the first n natural numbers. Therefore, this value will be greater than or equal to the value from the first part.

Putting the results from each part together, we get a very short program. Here is an implementation of this method in Python 2.7:

'''
Author: Walker Kroubalkian
Formulaic Approach to Project Euler Problem #6
'''

import time

def projectEulerProblemSix(n):
    return n*n*(n+1)*(n+1)/4 - n*(n+1)*(2*n+1)/6

start = time.time()
print projectEulerProblemSix(100)
print ("--- %s seconds ---" % (time.time() - start))

'''
Prints

25164150
--- 8.82148742676e-06 seconds ---

for input of n = 100
'''

As expected, the formulaic approach absolutely crushes this problem. The formulas that were discussed above are quite common, and I probably won’t write out the proof for them in future posts.

Thank you for reading!

Project Euler Problem #5:

Project Euler Problem #5 is another question that is feasibly do-able by hand but can also be generalized. The problem reads:

Project Euler Problem 5: Smallest Multiple
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

Clearly we will generalize this problem to find the least common multiple of the integers from 1 to n. One difficulty with finding the least common multiple of 2 numbers is that any factors that they share will be counted twice in the product of the two numbers. In fact, this observation leads to the useful fact that for two integers p and q, pq = lcm(p,q)*gcd(p,q) (here lcm(p,q) is the least common multiple of p and q while gcd(p,q) is the greatest common divisor of p and q). This fact does not generalize nicely for more than 2 integers, but it can be used to solve this problem as shown below:

Solution #1: Iterative Prime Power Approach

One fact that can help us solve this problem is that if we let F(n) be the least common multiple of the first n natural numbers, then F(n+1) = F(n) whenever n+1 has more than 1 distinct prime factor. This is clearly true, as if the prime factorization of n+1 has more than one prime power, than all of those prime powers are less than n+1 itself and therefore they should already be divisors of F(n). In the event that n+1 is a prime power of the form n+1 = p^e, then we have that F(n+1) = F(p^e) = pF(n). This is because the largest power of p that divides F(n) has to be p^(e-1), and because no other new factors are added, the least common multiple must be multiplied by the prime p.

With these facts in mind, we can iterate through all numbers i from 1 to n while storing a running least common multiple. Whenever i is a prime power, we multiply the running total by its prime factor, otherwise we do nothing. Here is an implementation of this method in Python 2.7:

'''
Author: Walker Kroubalkian
Iterative Approach to Project Euler Problem #5
'''

import time
from math import sqrt

def ifPowerGetPrime(n):
    c = 2
    while(c<=sqrt(n)):
        if(n%c==0):
            while(n%c==0):
                n/=c
            if(n>1):
                return -1
            else:
                return c
        c+=1
    return n

def projectEulerProblemFive(n):
    total = 1
    c = 2
    while(c<=n):
        a = ifPowerGetPrime(c)
        if(a>0):
            total*=a
        c+=1
    return total

start = time.time()
print projectEulerProblemFive(20)
print ("--- %s seconds ---" % (time.time()-start))

'''
Prints

232792560
--- 2.09808349609e-05 seconds ---

for input of n = 20
'''

This method appears to be quite efficient in general, as even extraordinary inputs such as finding the least common multiple of the first 1,000,000 natural numbers can be processed in under 10 seconds.

However, for small inputs such as n = 20, the question is quite do-able by hand. This post marks the 5th question of Project Euler, amounting to less than 1% of all the problems. Thanks for reading!

Project Euler Problem #4

Today we have Problem #4: The first of many to feature palindromic numbers. A palindrome is defined as a number that reads the same from left to right and from right to left. Unless otherwise specified, the term refers to palindromes in base 10. Here is the statement of this problem:

Project Euler Problem 4: Largest Palindrome Product
A palindromic number reads the same both ways. The largest palindrome made 
from the product of two 2-digit numbers is 9009 = 91 * 99.

Find the largest palindrome made from the product of two 3-digit numbers.

The most obvious way to generalize this question is to let the number of digits of each factor be the input. (Doing so reveals an interesting pattern as we will find out)

Here is the solution I found to this problem:

Solution #1: Adapting Bounds on the 3-Digit Numbers

The solution I considered is constantly bounding possibilities for the factors of this palindromic product. We know the larger 3-digit number is at most 999 and the smaller one is at least 100. In general, the larger the larger factor, the larger the product will be. Therefore, it makes sense to iterate downwards from the upper bound until we either hit the lower bound or we find a number which creates a palindrome when multiplied by the upper bound. In the second case, we can reset the lower bound to this number and then continue the process of bounding by decrementing the upper bound. This process will terminate once the upper bound becomes less than the lower bound.

Sorry if that explanation was a bit confusing. Here is an implementation of that method in Python 2.7:

'''
Author: Walker Kroubalkian
"Bounding" Approach to Project Euler Problem #4
'''

import time

def isPalindrome(n):
    return str(n)==str(n)[::-1]

def projectEulerProblemFour(n):
    upper = 10**n - 1
    lower = 10**(n-1)
    maxFound = 0
    while(upper>=lower):
        c = upper
        while(c>=lower):
            if(isPalindrome(upper*c)):
                lower = c
                if(upper*c>maxFound):
                    maxFound = upper*c
                break
            c-=1
        upper-=1
    return maxFound

start = time.time()
print projectEulerProblemFour(3)
print("--- %s seconds ---" % (time.time() - start))

'''
Prints

906609
--- 0.00363111495972 seconds ---

for input of n = 3
'''

Hopefully my method makes more sense with this program. One interesting fact that results from this generalization is that it appears that in general, when the problem is done with (2n)-digit numbers instead of 3 digit numbers, the maximum product is 99 . . . 9900 . . . 0099 . . . 99 where there are n 9’s on each side and 2n 0’s in the middle. A similar pattern can be observed for (2n+1) digit numbers where the product tends to have a lot of 9’s and 6’s in its base 10 representation. I have not proved either of these patterns to continue, but I have observed that they hold true for small values of n. With 4-digit numbers the answer is 99000099, with 5-digit numbers the answer is 9966006699, with 6-digit numbers the answer is 999000000999, with 7-digit numbers the answer is 99956644665999, and with 8-digit numbers the answer is 9999000000009999.

I may return to this problem eventually to determine if there is a more definite pattern to these results. That is all for today. I hope you enjoyed!

Project Euler Problem #3

While Problem #2 of Project Euler may have featured the very common Fibonacci numbers, Problem #3 is the first to feature the super common prime numbers. Here is the statement of Problem #3:

Project Euler Problem 3: Largest Prime Factor
The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143?

Factoring large numbers is a very common part of solving Project Euler problems. When the numbers are too large, it can be difficult to check every possible number as a possible divisor. Luckily, there is a trick we can use to determine if a number is prime as soon as possible.

Solution #1: Factors Less Than or Equal to the Square Root

The trick we can notice is that any composite number n can be written as the product of 2 factors a and b such that both a and b are greater than 1. If both a and b were greater than the square root of n, then it would be impossible for their product to be equal to n. Thus, any composite number must have at least one proper factor which is less than or equal to its square root. Consequently, any number which does not have a proper factor less than or equal to its square root must be prime. This fact will probably be used in many Project Euler problems, so I will only explain it in this post.

Using this trick, it is easy to find any small prime factors of a large composite number. However, this question has asked for the largest prime factor of a large number. To get around this problem, one method we can use is dividing out any prime factors we find until the value we’re left with is prime. By default, the resulting number would have to be the largest prime. This method can be made more efficient by the trick above, as the number of potential factors decreases every time a prime is divided out.

Here is an implementation of this method in Python 2.7:

'''
 Author: Walker Kroubalkian
 "Dividing Out" Approach to Project Euler Problem #3
 '''

 import time
 from math import sqrt

 def projectEulerProblemThree(n):
     c = 2
     while(c<=sqrt(n)):
         if(n%c==0):
             while(n%c==0):
                 n/=c
         c+=1

     if(n==1):
         return (c-1)

     return n

 start = time.time()
 print projectEulerProblemThree(600851475143)
 print("--- %s seconds ---" % (time.time() - start))

 '''
 Prints
 6857
 --- 0.00019097328186 seconds ---
 for input of n = 600851475143
 '''

Factoring and primes are extremely important parts of mathematics, and as a result, I will probably refer back to the facts discussed in this post in future posts.

Signing off for today. Thanks for reading!

Project Euler Problem #2

Continuing the beginning stretch of Project Euler problems, we see Problem #2: The first of many questions to feature the Fibonacci sequence.

Project Euler Problem #2: Even Fibonacci Numbers
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, . . .

By considering the terms in the Fibonacci sequence whose values do not 
exceed four million, find the sum of the even-valued terms.

Here is a solution I found for this problem:

Solution #1: Basic Iterative Approach

The simplest solution I could think of involves checking all Fibonacci numbers less than 4,000,000 and adding the even ones to a running total. Rather than recursively generating each successive Fibonacci term, we can iteratively generate new terms by constantly updating two variables.

If we let the variable first be the nth term and we let the variable second be the (n+1)th term, then to generate the next Fibonacci number, we can store the value of second in a temporary variable, update the value of second to the sum of first and second, and finally update the value of first to the initial value of second which we stored in the temporary variable. Now the (n+1)th term will be stored in first and the (n+2)th term will be stored in second and the iteration will be complete.

Here is an implementation of this method in Python 2.7:

'''
 Author: Walker Kroubalkian
 Iterative Approach to Project Euler Problem #2
 '''
 import time
 def projectEulerProblemTwo(n):
     total = 0
     first = 1
     second = 1
     while(second<=n):
         temp = second
         second+=first
         first = temp
         if(first%2==0):
             total+=first
     return total
 start = time.time()
 print projectEulerProblemTwo(4000000)
 print("--- %s seconds ---" % (time.time() - start))
 '''
 Prints
 4613732
 --- 1.21593475342e-05 seconds ---
 for input of n = 4000000
 '''

That’s all for today, folks. Thanks for reading!

Project Euler Problem #1:

For those who like math and want to learn a programming language, I can think of no better resource than Project Euler. Project Euler contains a free database of over 600 math problems. While the problems are all technically do-able by hand, it is expected that each will be solved with a computer program. This program should be able to solve the problem in less than a minute.

The problems on Project Euler range in difficulty from beginner computer science questions to very advanced math questions. They tend to get progressively more difficult.

For an example of an easier Project Euler question, look no further than Problem #1: Project Euler’s take on the classic “FizzBuzz” interview question.

Project Euler Problem 1: Multiples of 3 and 5
If we list all the natural numbers below 10 that are multiples of 3 or 5, 
we get 3,5,6, and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

In the classic FizzBuzz question, it is asked to write a program that prints each number from 1 to 100, but whenever the number is a multiple of 3, the program should instead print “Fizz”, and whenever the number is a multiple of 5, the program should instead print “Buzz”, and finally whenever the number is a multiple of 3 and 5, the program should instead print “FizzBuzz”.

Here are two solutions I found to Project Euler’s version:

Solution #1: Basic Iterative Approach

In this approach, we simply iterate through all numbers i from 1 to 999. If i is divisible by 3 or 5, we add i to a running total, otherwise, we do nothing. Here is the result when this approach is implemented in Python 2.7:

'''
 Author: Walker Kroubalkian
 The Iterative Approach to Project Euler Problem #1
 '''

 import time

 def projectEulerProblemOne(n):
     total = 0
     for i in range(1,n):
         if(i%3==0 or i%5==0):
             total+=i
     return total

 start = time.time()
 print projectEulerProblemOne(1000)
 print("--- %s seconds ---" % (time.time() - start))

 '''
 Prints
 233168
 --- 0.000103950500488 seconds ---
 for input of n = 1000
 '''

Solution #2: Formulaic Approach

While the Iterative approach is fine for solving this problem, it is actually possible to solve this problem with a formula.

Remembering that the sum 1 + 2 + 3 + . . . + n = n(n+1)/2, we can add up all multiples of 3 less than or equal to 3n with the similar expression: 3 + 6 + 9 + . . . + 3n = 3(1 + 2 + 3 + . . . + n) = 3n(n+1)/2. Similarly, we can add up all multiples of 5 less than or equal to 5n with the expression 5n(n+1)/2. If we use these expressions to add up all multiples of 3 and 5 less than 1000, we will add all multiples of 3 and 5 twice, so we must subtract the multiples of 15 with the expression 15n(n+1)/2. Doing so, we get the following formulaic program:

'''
Author: Walker Kroubalkian
The Formulaic Approach to Project Euler Problem #1
'''

from math import floor
import time

def projectEulerProblemOne(n):
    numberThrees = floor((n-1)/3)
    numberFives = floor((n-1)/5)
    numberFifteens = floor((n-1)/15)
    
    addThrees = 3*numberThrees*(numberThrees+1)/2
    addFives = 5*numberFives*(numberFives+1)/2
    addFifteens = 15*numberFifteens*(numberFifteens+1)/2start = time.time()

    return addThrees + addFives - addFifteens
    
print projectEulerProblemOne(1000)
print("--- %s seconds ---" % (time.time() - start))

'''
Prints
233168
--- 2.19345092773e-05 seconds ---
for input of n = 1000
'''

As expected, the formulaic approach tends to be faster for solving this problem. With this approach, it is even feasible to do this question by hand.

I will try to post a solution to a Project Euler problem each day for as long as I can.

Thanks for reading my first blog post!

Design a site like this with WordPress.com
Get started