05.30.08
Project Euler: Problem 7
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 10001st prime number?
A solution:
import math
def isPrime(num):
if type(num) != int: return False
if num == 2: return True
if num < 2 or num % 2 == 0: return False
return not any(num % i == 0 for i in range(3, int(math.sqrt(num))+1, 2))
n = 10001
count_of_found = 2 # assuming 2 and 3 to start
current_number = 3
current_prime = 3
while count_of_found < n:
current_number += 2
if isPrime(current_number):
current_prime = current_number
count_of_found += 1
print 'nth prime for n=%d is %s' % (n, current_prime)
This problem was originally solved with a factorize function written for a previous problem, checking primality by looking at the number of factors. This way is faster. Plus, it’s good “generator expression” practice. :)
05.29.08
Project Euler: 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?
A solution:
from math import ceil
def factorize(num):
powers = []
limit = int(ceil(float(num)/2)) # we only need to look up to num/2 for factors
for i in range(2, limit+1):
while num % i == 0: # ie, if i is a factor of num
powers.append(i)
num = num/i # take factor out of num and continue with smaller num
if len(powers) == 0: # haven't found any factors, ie, num is prime
powers.append(num)
return powers
topnum = 20
master_factors = []
total = 1
for i in range(2,topnum+1):
current_factors = factorize(i)
while len(current_factors) != 0:
fact = current_factors[0]
count_difference = current_factors.count(fact)-master_factors.count(fact)
if count_difference > 0:
for j in range(count_difference): master_factors.append(fact)
del current_factors[0:current_factors.count(fact)]
for i in range(len(master_factors)): total *= master_factors[i]
print total
This code seems pretty messy, there’s surely better ways to write it. For sure, the factorize function should be changed so that it only checks odd numbers (after two), that would get rid of half the iterations. After solving the problem I looked through the forum for ways others were solving it, and found this one written in Python, from user tenigmanogo:
def gcd(a, b): while b != 0: a, b = b, a % b return a def lcm(a, b): return a*b/gcd(a, b) print reduce(lcm, range(1, 20+1))
Definitely makes me want to learn more, and get better about looking at problems in different ways. It’s so simple! Though, with the longer solution, I now have a function that will find the prime factors of a number, which will come in handy for future problems.
Project Euler: Problem 6
These problems will show up according to “difficulty”, according to the Project Euler site. Difficulty, here, corresponds to number of people who have solved the problem. When a problem is solved by more people, it’s listed as an easier problem. Thus:
The sum of the squares of the first ten natural numbers is,
1² + 2² + … + 10² = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + … + 10)² = 55² = 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.
A solution:
n = 100 square_of_sum = (n*(n+1)/2)**2 sum_of_squares = n*(n+1)*(2*n+1)/6 diff = square_of_sum - sum_of_squares print 'sum of squares:', sum_of_squares print 'square of sum:', square_of_sum print 'difference:', diff
This is a second solution, the first was a brute-force looping through all the numbers to accumulate the sums. Then I got smart and remembered that there are formulae for these finite series; a quick google let me find them and write much better code.
05.28.08
Project Euler: 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.
A Solution:
target = 4000000
a = 0
b = 1
c = 1
sum = 0
while c <= target:
if c % 2 == 0:
sum += c
a = b
b = c
c = a+b
print sum
The problem talks about starting with 1 and 2, but if we start as shown above with 0 and 1, the first 2 will get caught in the while loop.
Update (2 days later):
I’ve gone back and prettied up a few of my solutions. In the solution that follows the number of variables necessary to keep goes down to two from three, because the right side of an equation (including multiple assignments) is evaluated before any of the assignments get made. Sneaky.
target = 4000000
a, b, sum = 0, 1, 0
while b <= target:
if b % 2 == 0: sum += b
a, b = b, a+b
print sum
Project Euler: Problem 1
Project Euler is a website with nearly 200 math-type programming problems, which look great for learning and practice.
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.
A Solution:
sum = 0
for i in range(1000):
if (i % 3 == 0)|(i % 5 == 0):
sum += i
print sum
There are surely more efficient solutions, but for the moment I’m more concerned about getting familiar with the python syntax than I am with the pretty pretty math.
05.27.08
In the beginning were the (boring) words
Having decided to take a crack at Python after a few weeks of flirting with Ruby, the first day is disappointing. These Python tutorials, man are they the boring. Come on, people, can’t we have a little humour as we learn? Yes, Why’s (Poignant) Guide sets a high bar, but surely we can do better than a few half-hearted Monty Python skit references.
Not the most encouraging beginning.
