
Lately, I have been messing around with Project Euler, a site with over 280 math problem designed to be solved using computer programming skills. You’ve probably already seen rseaton’s solution for Problem 1 in C, but I prefer python for it’s easy to read syntax and simplicity. I am not an experienced programmer by any definition, so many of my scripts will be inefficient and cumbersome. If you have improvements for them, please post in the comments.
Warning: Spoilers!
Problem #1
“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.”
Okay, so this is rather simple. we’re going to make a list of all numbers from 0 to 1000. Then we are going to take that list and pull out anything that is evenly divisible (no remainder) by either 3 or 5. Finally we will find the sum of all the numbers in that list.
Here is my resulting python script:
#Create a list containing all numbers below 1000.
possibles = range(1000)
#Find all numbers in that list that are multiples of 3 or 5.
multiples = [x for x in possibles if (x % 3 == 0) or (x % 5 == 0)]
#Add all the multiples together.
total = sum(multiples)
#Print the resulting total.
print total
Pretty simple, eh? If you didn’t understand line 4, check out list comprehension.
Problem #2
“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, …
Find the sum of all the even-valued terms in the sequence which do not exceed four million.”
So our strategy here is this:
- Create a list containing the Fibonacci sequence up to 4 million.
- Pull all the numbers that are evenly divisible by 2. We could do this with a modulus function, but I found a faster way.
- Sum the list to find the answer.
Here’s my code:
fibonacci = [] # create empty list to append to
a,b = 1,0 # assign initial values
while a < 4000000: #this loop will add numbers to our fibonacci list
fibonacci.append(a)
b, a = a, a+b # use multiple assignments to do these values
# Every 3rd number in the fibonacci sequence is even,
# so lets just pull all of those, starting with the third item (which is 2).
evens = fibonacci[2::3]
total = sum(evens) # add them up
print total
When we made the evens list, we used something called stride notation. The first value (2) tells the program to start at the 3rd item in Fibonacci. The second value (3) tells our program to take every 3rd item. In the case of the Fibonacci sequence, all those are even.
Problem #3
“The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?”
This is one that I found to be kind of tricky. I had to look up some various prime factorization algorithms and their python code equivalents. You just need to use one of the algorithms to make a list of all prime factors. Then select the largest one. This is the final code:
def factor(n):
if n == 1: return [1] # 1 is already prime.
i = 2 # i will be our divisor
limit = n**0.5 #We only need to go up to the square root of our number.
while i <= limit:
if n % i == 0: # Check if our number is divisible by the ever increasing i
ret = factor(n/i)
ret.append(i)
return ret
i += 1
return [n]
# Actual computation
print max(factor(600851475143))
Problem #4
“A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99.
Find the largest palindrome made from the product of two 3-digit numbers.”
Ah, palindromes. They’re kind of fun right? And really, that is probably the easiest part in this problem. We check the value against itself with a stride notation of -1. That tells the program to reverse the value. The hard part is making sure that the palindrome you find is a product of two three digit numbers. I know my way is not the most efficient (it take 11.53 sec to complete on my computer), but I’m not sure how I want to improve it at the moment. Please leave me some help in the comments.
def checkPalindrome(x): # a simple function that reverses the string of x to check for a palindrome.
if str(x) == str(x)[::-1]:
return True
done = False #This will break us out of the for loop once a result is found.
for x in reversed(xrange(100**2,999**2)): #The palindrome will be in this range.
if done: # If result is found, break loop.
break
elif checkPalindrome(x): # Check x to see if it is a palindrome.
for fac1 in reversed(xrange(100,1000)): # Factors must be in this range.
for fac2 in reversed(xrange(100,1000)):
if x == (fac1 * fac2): #The palindrome has to be a product of the two factors
result = x
done = True # Tell the loop we're done.
print result
Problem #5
“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 number that is evenly divisible by all of the numbers from 1 to 20?”
This is a fairly easy problem. We just need to find the least common multiple (LCM) of all the number 1-20. While python doesn’t contain a function to find lcm by default (like Ruby), we can make one. The LCM of two numbers actually equals their product divided by their GCD (Greatest Common Divisor). To find the GCD, we will use Euclid’s Algorithm. Here is the code:
def euclid(a,b): # We're going to use Euclid's algorithim to determine the GCD of the numbers.
while b > 0:
remainder = a % b
a, b = b, remainder
return a
def lcm(a,b): #Now find the LCM using the previous GCD.
return a*b / euclid(a,b)
print reduce(lcm, range(1,21)) # Now perform the LCM function over the range of numbers.
That reduce function at the end just makes the function repeat for all numbers 1-20, since the function can only handle 2 at a time.
Hopefully I will be able to make my way through the next 5 problems and share my solutions with you. stay tuned!
Related Posts
Project Euler 1 – 5 in Ruby
Euler Solution for Problem 1 in C++