Documented each exercise, and placed executable code in a main() function.

git-svn-id: file:///srv/svn/euler@63 e5f4c3ec-3c0c-11df-b522-21efaa4426b5
This commit is contained in:
Correl Roush 2010-05-04 18:21:07 +00:00
parent 43e37f6dad
commit 12c5dd7875
35 changed files with 694 additions and 184 deletions

19
e001.py
View file

@ -1,6 +1,15 @@
total = 0 """Add all the natural numbers below one thousand that are multiples of 3 or 5.
for x in range(1000):
if (0 == x % 3) or (0 == x % 5):
total = total + x
print 'Answer', total 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.
"""
def main():
total = 0
for x in range(1000):
if (0 == x % 3) or (0 == x % 5):
total = total + x
print 'Answer', total
if __name__ == '__main__':
main()

38
e002.py
View file

@ -1,17 +1,23 @@
# -*- coding: utf-8 -*- """Find the sum of all the even-valued terms in the Fibonacci sequence which do not exceed four million.
# 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.
limit = 4000000 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:
#limit = 90 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
last = [0, 1] Find the sum of all the even-valued terms in the sequence which do not exceed four million.
x = 1 """
total = 0
while (x < limit): def main():
if (0 == x % 2): limit = 4000000
total += x #limit = 90
last.append(x) last = [0, 1]
last = last[-2:] x = 1
x = sum(last) total = 0
print 'Answer', total while (x < limit):
if (0 == x % 2):
total += x
last.append(x)
last = last[-2:]
x = sum(last)
print 'Answer', total
if __name__ == '__main__':
main()

11
e003.py
View file

@ -1,3 +1,9 @@
"""Find the largest prime factor of a composite number.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
"""
def pfactor(n): def pfactor(n):
i = 2 i = 2
while (n % i != 0 and i < n): while (n % i != 0 and i < n):
@ -8,6 +14,9 @@ def pfactor(n):
p.append(i) p.append(i)
return sorted(p, reverse=True) return sorted(p, reverse=True)
if __name__ == '__main__': def main():
print 'Prime factors of 600851475143:' print 'Prime factors of 600851475143:'
print pfactor(600851475143) print pfactor(600851475143)
if __name__ == '__main__':
main()

11
e004.py
View file

@ -1,3 +1,9 @@
"""Find the largest palindrome made from the product of two 3-digit numbers.
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.
"""
def palindrome(): def palindrome():
palindromes = {} palindromes = {}
for i in range(999, 99, -1): for i in range(999, 99, -1):
@ -7,5 +13,8 @@ def palindrome():
palindromes[i * ii] = [i, ii] palindromes[i * ii] = [i, ii]
p = sorted(palindromes.keys(), reverse=True)[0] p = sorted(palindromes.keys(), reverse=True)[0]
print 'Palindrome: {0}x{1}: {2}'.format(palindromes[p][0], palindromes[p][1], p) print 'Palindrome: {0}x{1}: {2}'.format(palindromes[p][0], palindromes[p][1], p)
if __name__ == '__main__': def main():
palindrome() palindrome()
if __name__ == '__main__':
main()

11
e005.py
View file

@ -1,3 +1,9 @@
"""What is the smallest number divisible by each of the numbers 1 to 20?
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?
"""
def divisible(n): def divisible(n):
i = 0 i = 0
while True: while True:
@ -8,5 +14,8 @@ def divisible(n):
break break
if ii == 1: if ii == 1:
return x return x
if __name__ == '__main__': def main():
print 'Smallest number: ', divisible(20) print 'Smallest number: ', divisible(20)
if __name__ == '__main__':
main()

15
e006.py
View file

@ -1,3 +1,13 @@
"""What is the difference between the sum of the squares and the square of the sums?
The sum of the squares of the first ten natural numbers is,
12 + 22 + ... + 102 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)2 = 552 = 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.
"""
def squarediff(n): def squarediff(n):
print 'Checking for n =', n print 'Checking for n =', n
sumofsquares = sum([x**2 for x in range(n + 1)]) sumofsquares = sum([x**2 for x in range(n + 1)])
@ -6,6 +16,9 @@ def squarediff(n):
print 'Square of sum', squareofsum print 'Square of sum', squareofsum
print 'Difference', squareofsum - sumofsquares print 'Difference', squareofsum - sumofsquares
if __name__ == '__main__': def main():
squarediff(10) squarediff(10)
squarediff(100) squarediff(100)
if __name__ == '__main__':
main()

11
e007.py
View file

@ -1,3 +1,9 @@
"""Find the 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 10001st prime number?
"""
import math import math
def is_prime(n): def is_prime(n):
@ -32,6 +38,9 @@ def primes(max_count = 0, max_value = 0):
primes.append(i) primes.append(i)
return primes return primes
if __name__ == '__main__': def main():
print '6th Prime', primes(6)[-1] print '6th Prime', primes(6)[-1]
print '10001st Prime', primes(10001)[-1] print '10001st Prime', primes(10001)[-1]
if __name__ == '__main__':
main()

26
e008.py
View file

@ -1,3 +1,5 @@
"""Discover the largest product of five consecutive digits in the 1000-digit number."""
NUMBER = """ NUMBER = """
73167176531330624919225119674426574742355349194934 73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843 96983520312774506326239578318016984801869478851843
@ -21,14 +23,18 @@ NUMBER = """
71636269561882670428252483600823257530420752963450 71636269561882670428252483600823257530420752963450
""".replace('\n', '') """.replace('\n', '')
max = 0 def main():
set = None max = 0
for i in range(len(NUMBER) - 4): set = None
product = 1 for i in range(len(NUMBER) - 4):
for ii in [int(n) for n in NUMBER[i:i+5]]: product = 1
product = product * ii for ii in [int(n) for n in NUMBER[i:i+5]]:
if product > max: product = product * ii
max = product if product > max:
set = NUMBER[i:i+5] max = product
set = NUMBER[i:i+5]
print 'Max product is {0} from {1}'.format(max, set)
print 'Max product is {0} from {1}'.format(max, set) if __name__ == '__main__':
main()

28
e009.py
View file

@ -1,9 +1,23 @@
"""Find the only Pythagorean triplet, {a, b, c}, for which a + b + c = 1000.
A Pythagorean triplet is a set of three natural numbers, a b c, for which,
a2 + b2 = c2
For example, 32 + 42 = 9 + 16 = 25 = 52.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
"""
TRIPLET_SUM = 1000 TRIPLET_SUM = 1000
for c in range(TRIPLET_SUM - 3, 3, -2): def main():
diff = TRIPLET_SUM - c for c in range(TRIPLET_SUM - 3, 3, -2):
for x in range(1, int(diff / 2) + 1): diff = TRIPLET_SUM - c
(a, b) = (x, diff - x) for x in range(1, int(diff / 2) + 1):
if a**2 + b**2 == c**2: (a, b) = (x, diff - x)
print '{a}**2 + {b}**2 == {c}**2'.format(a=a, b=b, c=c) if a**2 + b**2 == c**2:
print 'Product: ', a*b*c print '{a}**2 + {b}**2 == {c}**2'.format(a=a, b=b, c=c)
print 'Product: ', a*b*c
if __name__ == '__main__':
main()

16
e010.py
View file

@ -1,5 +1,15 @@
"""Calculate the sum of all the primes below two million.
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
"""
from e007 import primes; from e007 import primes;
print 'Fetching all primes for n < 2,000,000' def main():
p = primes(0, 2000000) print 'Fetching all primes for n < 2,000,000'
print 'Sum:', sum(p) p = primes(0, 2000000)
print 'Sum:', sum(p)
if __name__ == '__main__':
main()

102
e011.py
View file

@ -1,3 +1,33 @@
"""What is the greatest product of four numbers on the same straight line in the 20 by 20 grid?
In the 2020 grid below, four numbers along a diagonal line have been marked in red.
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10[26]38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95[63]94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17[78]78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35[14]00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
The product of these numbers is 26 63 78 14 = 1788696.
What is the greatest product of four adjacent numbers in any direction (up, down, left, right, or diagonally) in the 2020 grid?
"""
GRID = """ GRID = """
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
@ -22,54 +52,58 @@ GRID = """
""".strip().replace('\n', ' ').split(' ') """.strip().replace('\n', ' ').split(' ')
GRID = [int(n) for n in GRID] GRID = [int(n) for n in GRID]
max = 0
info = None
def product(l): def product(l):
p = 1 p = 1
for n in l: for n in l:
p = p * n p = p * n
return p return p
for row in range(1,20): def main():
for col in range(20): max = 0
pos = 20 * row + col info = None
if col <= 16: for row in range(1,20):
# Horizontal for col in range(20):
r = GRID[pos:pos+4] pos = 20 * row + col
x = product(r)
if x > max:
max = x
info = [col, row, '-', r]
if row <= 16:
# Vertical
r = []
for i in range(4):
r.append(GRID[pos + 20 * i])
x = product(r)
if x > max:
max = x
info = [col, row, '|', r]
if col <= 16: if col <= 16:
# Diagonal (\) # Horizontal
r = [] r = GRID[pos:pos+4]
for i in range(4):
r.append(GRID[pos + 20 * i + i])
x = product(r) x = product(r)
if x > max: if x > max:
max = x max = x
info = [col, row, '\\', r] info = [col, row, '-', r]
if col >= 3: if row <= 16:
# Diagonal (/) # Vertical
r = [] r = []
for i in range(4): for i in range(4):
r.append(GRID[pos + 20 * i - i]) r.append(GRID[pos + 20 * i])
x = product(r) x = product(r)
if x > max: if x > max:
max = x max = x
info = [col, row, '/', r] info = [col, row, '|', r]
if col <= 16:
# Diagonal (\)
r = []
for i in range(4):
r.append(GRID[pos + 20 * i + i])
x = product(r)
if x > max:
max = x
info = [col, row, '\\', r]
if col >= 3:
# Diagonal (/)
r = []
for i in range(4):
r.append(GRID[pos + 20 * i - i])
x = product(r)
if x > max:
max = x
info = [col, row, '/', r]
(col, row, direction, l) = info
print 'Max Product is {p} at row {row}, col {col} ({d}): {l}'.format(p=max, row=row, col=col, d=direction, l=l)
(col, row, direction, l) = info if __name__ == '__main__':
print 'Max Product is {p} at row {row}, col {col} ({d}): {l}'.format(p=max, row=row, col=col, d=direction, l=l) main()

25
e012.py
View file

@ -1,3 +1,22 @@
"""What is the value of the first triangle number to have over five hundred divisors?
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
"""
from e003 import pfactor from e003 import pfactor
from p054.poker import unique_combinations from p054.poker import unique_combinations
@ -44,7 +63,7 @@ def factor(n):
factors.append(n) factors.append(n)
return sorted(set(factors)) return sorted(set(factors))
if __name__ == '__main__': def main():
i = 1 i = 1
while True: while True:
i = i + 1 i = i + 1
@ -54,4 +73,6 @@ if __name__ == '__main__':
if len(f) > 500: if len(f) > 500:
break break
print 'Triangle number {0} has {1} factors ({2})'.format(t, len(f), f) print 'Triangle number {0} has {1} factors ({2})'.format(t, len(f), f)
if __name__ == '__main__':
main()

12
e013.py
View file

@ -1,3 +1,5 @@
"""Find the first ten digits of the sum of one-hundred 50-digit numbers."""
NUMBERS = """ NUMBERS = """
37107287533902102798797998220837590246510135740250 37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538 46376937677490009712648124896970078050417018260538
@ -103,6 +105,10 @@ NUMBERS = """
NUMBERS = [int(n) for n in NUMBERS] NUMBERS = [int(n) for n in NUMBERS]
s = sum(NUMBERS) def main():
print 'Sum:', s s = sum(NUMBERS)
print 'First 10 Digits:', str(s)[:10] print 'Sum:', s
print 'First 10 Digits:', str(s)[:10]
if __name__ == '__main__':
main()

40
e014.py
View file

@ -1,3 +1,19 @@
"""Find the longest sequence using a starting number under one million.
The following iterative sequence is defined for the set of positive integers:
n n/2 (n is even)
n 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 40 20 10 5 16 8 4 2 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
"""
def collatz(n): def collatz(n):
steps = 0 steps = 0
while n > 1: while n > 1:
@ -8,13 +24,17 @@ def collatz(n):
n = n / 2 n = n / 2
return steps return steps
i = 1000000 def main():
max = 0 i = 1000000
maxnum = i max = 0
while i > 1: maxnum = i
i = i - 1 while i > 1:
c = collatz(i) i = i - 1
if c > max: c = collatz(i)
max = c if c > max:
maxnum = i max = c
print 'Max was {0} steps for {1}'.format(max, maxnum) maxnum = i
print 'Max was {0} steps for {1}'.format(max, maxnum)
if __name__ == '__main__':
main()

14
e015.py
View file

@ -1,4 +1,13 @@
"""Starting in the top left corner in a 20 by 20 grid, how many routes are there to the bottom right corner?
Starting in the top left corner of a 22 grid, there are 6 routes (without backtracking) to the bottom right corner.
[See: p015/p_015.gif]
How many routes are there through a 2020 grid?
""" """
"""Notes:
Calculate the number of possible paths from the top left corner to the bottom Calculate the number of possible paths from the top left corner to the bottom
right, without backtracking (no moving up or left) right, without backtracking (no moving up or left)
@ -26,8 +35,11 @@ def pascal(row, col):
def paths(size): def paths(size):
return pascal(size + (size - 2), size - 1) return pascal(size + (size - 2), size - 1)
if __name__ == '__main__': def main():
# 20x20 grid # 20x20 grid
# Points = cubes + 1 # Points = cubes + 1
size = 21 size = 21
print 'Paths: ', paths(size) print 'Paths: ', paths(size)
if __name__ == '__main__':
main()

20
e016.py
View file

@ -1,7 +1,17 @@
"""What is the sum of the digits of the number 21000?
215 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 21000?
"""
n = 2**1000 n = 2**1000
s = str(n) def main():
total = 0 s = str(n)
for c in s: total = 0
total = total + int(c) for c in s:
print 'Sum of digits for {0}: {1}'.format(n, total) total = total + int(c)
print 'Sum of digits for {0}: {1}'.format(n, total)
if __name__ == '__main__':
main()

13
e017.py
View file

@ -1,3 +1,11 @@
"""How many letters would be needed to write all the numbers in words from 1 to 1000?
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
"""
NUMBERS = [ NUMBERS = [
'', '',
'one', 'one',
@ -54,8 +62,11 @@ def format(n):
s.append(NUMBERS[nn % 10]) s.append(NUMBERS[nn % 10])
return ' '.join(s) return ' '.join(s)
if __name__ == '__main__': def main():
chars = [] chars = []
for i in range(1, 1001): for i in range(1, 1001):
chars = chars + list(format(i).replace(' ', '').replace('-', '')) chars = chars + list(format(i).replace(' ', '').replace('-', ''))
print 'Chars:', len(chars) print 'Chars:', len(chars)
if __name__ == '__main__':
main()

37
e018.py
View file

@ -1,3 +1,35 @@
"""Find the maximum sum travelling from the top of the triangle to the base.
By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom of the triangle below:
75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)
"""
from e012 import triangle from e012 import triangle
class Vertex: class Vertex:
@ -81,7 +113,7 @@ class Triangle:
path.append(v) path.append(v)
return path return path
if __name__ == '__main__': def main():
vertex_data = [] vertex_data = []
with open('p018/triangle.txt', 'r') as f: with open('p018/triangle.txt', 'r') as f:
while True: while True:
@ -94,3 +126,6 @@ if __name__ == '__main__':
path = t.get_path() path = t.get_path()
print 'Path', [v.value for v in path] print 'Path', [v.value for v in path]
print 'Sum', sum([v.value for v in path]) print 'Sum', sum([v.value for v in path])
if __name__ == '__main__':
main()

19
e019.py
View file

@ -1,3 +1,19 @@
"""How many Sundays fell on the first of the month during the twentieth century?
You are given the following information, but you may prefer to do some research for yourself.
* 1 Jan 1900 was a Monday.
* Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
* A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
"""
class Day: class Day:
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY = range(7) SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY = range(7)
@ -28,3 +44,6 @@ while year < 2000:
total = total + 1 total = total + 1
print 'Total months beginning on Sunday from 1/1/1901 to 12/31/2000: {0}'.format(total) print 'Total months beginning on Sunday from 1/1/1901 to 12/31/2000: {0}'.format(total)
if __name__ == '__main__':
main()

20
e020.py
View file

@ -1,3 +1,9 @@
"""Find the sum of digits in 100!
n! means n (n 1) ... 3 2 1
Find the sum of the digits in the number 100!
"""
# Could use math.factorial, but that takes the fun out of it, doesn it # Could use math.factorial, but that takes the fun out of it, doesn it
def factorial(n): def factorial(n):
f = n f = n
@ -7,9 +13,13 @@ def factorial(n):
i = i - 1 i = i - 1
return f return f
f = str(factorial(100)) def main():
sum = 0 f = str(factorial(100))
for c in f: sum = 0
sum = sum + int(c) for c in f:
sum = sum + int(c)
print 'Sum of digits in 100!:', sum
print 'Sum of digits in 100!:', sum if __name__ == '__main__':
main()

16
e021.py
View file

@ -1,3 +1,13 @@
"""Evaluate the sum of all amicable pairs under 10000.
Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
If d(a) = b and d(b) = a, where a b, then a and b are an amicable pair and each of a and b are called amicable numbers.
For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.
Evaluate the sum of all the amicable numbers under 10000.
"""
from e007 import is_prime from e007 import is_prime
from e012 import factor from e012 import factor
@ -10,7 +20,7 @@ def proper_divisors(n):
# Knock off the last factor, since it is equal to n # Knock off the last factor, since it is equal to n
return divisors[:-1] return divisors[:-1]
if __name__ == '__main__': def main():
MIN = 2 MIN = 2
MAX = 10000 MAX = 10000
@ -26,4 +36,6 @@ if __name__ == '__main__':
amicable.append(i) amicable.append(i)
amicable.append(s) amicable.append(s)
i = i + 1 i = i + 1
print 'Sum of amicable numbers less than {0}: {1}'.format(MAX, sum(amicable)) print 'Sum of amicable numbers less than {0}: {1}'.format(MAX, sum(amicable))
if __name__ == '__main__':
main()

44
e022.py
View file

@ -1,19 +1,31 @@
"""What is the total of all the name scores in the file of first names?
Using names.txt (p022/names.txt), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.
For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 53 = 49714.
What is the total of all the name scores in the file?
"""
import csv import csv
names = [] def main():
reader = csv.reader(open('p022/names.txt'), delimiter=',', quotechar='"') names = []
for row in reader: reader = csv.reader(open('p022/names.txt'), delimiter=',', quotechar='"')
names = names + row for row in reader:
names = sorted(names) names = names + row
total = 0 names = sorted(names)
total = 0
i = 1
for name in names:
score = 0
for c in name:
score = score + (ord(c) - 64)
score = i * score
total = total + score
i = i + 1
print 'Total:', total
i = 1 if __name__ == '__main__':
for name in names: main()
score = 0
for c in name:
score = score + (ord(c) - 64)
score = i * score
total = total + score
i = i + 1
print 'Total:', total

47
e023.py
View file

@ -1,20 +1,33 @@
"""Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
"""
from e021 import proper_divisors from e021 import proper_divisors
abundant = [] def main():
total = 1 abundant = []
total = 1
i = 2
while i < 28123:
s = sum(proper_divisors(i))
if s > i:
abundant.append(i)
summed = False
for a in abundant:
if i - a in abundant:
summed = True
break
if not summed:
total = total + i
i = i + 1
print 'Total:', total
i = 2 if __name__ == '__main__':
while i < 28123: main()
s = sum(proper_divisors(i))
if s > i:
abundant.append(i)
summed = False
for a in abundant:
if i - a in abundant:
summed = True
break
if not summed:
total = total + i
i = i + 1
print 'Total:', total

13
e024.py
View file

@ -1,3 +1,11 @@
"""What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:
012 021 102 120 201 210
What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
"""
import math import math
def lexicographic_permutation(list, position): def lexicographic_permutation(list, position):
@ -17,7 +25,7 @@ def lexicographic_permutation(list, position):
p.append(list.pop(index)) p.append(list.pop(index))
return p return p
if __name__ == '__main__': def main():
print 'Testing permutations of 0..2:' print 'Testing permutations of 0..2:'
list = [str(i) for i in [0, 1, 2]] list = [str(i) for i in [0, 1, 2]]
for i in range(1, math.factorial(len(list)) + 1): for i in range(1, math.factorial(len(list)) + 1):
@ -27,3 +35,6 @@ if __name__ == '__main__':
list = [str(i) for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] list = [str(i) for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
p = lexicographic_permutation(list, 1000000) p = lexicographic_permutation(list, 1000000)
print '1 millionth lexicographic permutation of 0..9:', ''.join(p) print '1 millionth lexicographic permutation of 0..9:', ''.join(p)
if __name__ == '__main__':
main()

29
e025.py
View file

@ -1,3 +1,27 @@
"""What is the first term in the Fibonacci sequence to contain 1000 digits?
The Fibonacci sequence is defined by the recurrence relation:
Fn = Fn1 + Fn2, where F1 = 1 and F2 = 1.
Hence the first 12 terms will be:
F1 = 1
F2 = 1
F3 = 2
F4 = 3
F5 = 5
F6 = 8
F7 = 13
F8 = 21
F9 = 34
F10 = 55
F11 = 89
F12 = 144
The 12th term, F12, is the first term to contain three digits.
What is the first term in the Fibonacci sequence to contain 1000 digits?
"""
def fibonacci(n, limit=None): def fibonacci(n, limit=None):
fibonacci = [0, 1] fibonacci = [0, 1]
i = 2 i = 2
@ -9,6 +33,9 @@ def fibonacci(n, limit=None):
i = i + 1 i = i + 1
return (n, fibonacci[n]) return (n, fibonacci[n])
if __name__ == '__main__': def main():
(term, value) = fibonacci(10**999, 10**999) (term, value) = fibonacci(10**999, 10**999)
print 'First Fibonacci term with at least 1000 digits is #{0}: {1}'.format(term, value) print 'First Fibonacci term with at least 1000 digits is #{0}: {1}'.format(term, value)
if __name__ == '__main__':
main()

40
e028.py
View file

@ -1,14 +1,32 @@
n = 1 """What is the sum of both diagonals in a 1001 by 1001 spiral?
total = 1
size = 1
MAX_SIZE = 1001 Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:
while size <= MAX_SIZE: [21]22 23 24[25]
for i in range(4): 20 [7] 8 [9]10
n = n + (size - 1) 19 6 [1] 2 11
if n > 1: 18 [5] 4 [3]12
total = total + n [17]16 15 14[13]
size = size + 2
print 'Total:', total It can be verified that the sum of the numbers on the diagonals is 101.
What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
"""
def main():
n = 1
total = 1
size = 1
MAX_SIZE = 1001
while size <= MAX_SIZE:
for i in range(4):
n = n + (size - 1)
if n > 1:
total = total + n
size = size + 2
print 'Total:', total
if __name__ == '__main__':
main()

32
e029.py
View file

@ -1,10 +1,28 @@
# -*- coding: utf-8 -*-
""""How many distinct terms are in the sequence generated by a**b for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100?
Consider all integer combinations of a**b for 2 a 5 and 2 b 5:
2**2=4, 2**3=8, 2**4=16, 2**5=32
3**2=9, 3**3=27, 3**4=81, 3**5=243
4**2=16, 4**3=64, 4**4=256, 4**5=1024
5**2=25, 5**3=125, 5**4=625, 5**5=3125
If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
How many distinct terms are in the sequence generated by a**b for 2 a 100 and 2 b 100?
"""
MAX = 100 MAX = 100
numbers = [] def main():
numbers = []
for i in range(2, MAX + 1):
for ii in range(2, MAX + 1):
n = i**ii
if n not in numbers:
numbers.append(n)
print len(numbers)
for i in range(2, MAX + 1): if __name__ == '__main__':
for ii in range(2, MAX + 1): main()
n = i**ii
if n not in numbers:
numbers.append(n)
print len(numbers)

25
e030.py
View file

@ -1,3 +1,16 @@
"""Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.
Surprisingly there are only three numbers that can be written as the sum of fourth powers of their digits:
1634 = 1**4 + 6**4 + 3**4 + 4**4
8208 = 8**4 + 2**4 + 0**4 + 8**4
9474 = 9**4 + 4**4 + 7**4 + 4**4
As 1 = 14 is not a sum it is not included.
The sum of these numbers is 1634 + 8208 + 9474 = 19316.
Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.
"""
def power_sums(n): def power_sums(n):
numbers = [] numbers = []
i = 9 i = 9
@ -10,7 +23,11 @@ def power_sums(n):
numbers.append(i) numbers.append(i)
return numbers return numbers
p = power_sums(4) def main():
print 'power_sums(4)', p, sum(p) p = power_sums(4)
p = power_sums(5) print 'power_sums(4)', p, sum(p)
print 'power_sums(5)', p, sum(p) p = power_sums(5)
print 'power_sums(5)', p, sum(p)
if __name__ == '__main__':
main()

13
e034.py
View file

@ -1,3 +1,11 @@
"""Find the sum of all numbers which are equal to the sum of the factorial of their digits.
145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145.
Find the sum of all numbers which are equal to the sum of the factorial of their digits.
Note: as 1! = 1 and 2! = 2 are not sums they are not included.
"""
import math import math
def sum_factorial(n): def sum_factorial(n):
@ -9,7 +17,7 @@ def sum_factorial(n):
MAX = 100000 MAX = 100000
if __name__ == '__main__': def main():
total = 0 total = 0
i = 2 i = 2
while i <= MAX: while i <= MAX:
@ -18,3 +26,6 @@ if __name__ == '__main__':
print i print i
total = total + i total = total + i
print 'Total:', total print 'Total:', total
if __name__ == '__main__':
main()

13
e035.py
View file

@ -1,3 +1,11 @@
"""How many circular primes are there below one million?
The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
How many circular primes are there below one million?
"""
from e007 import primes from e007 import primes
class NotCircular(Exception): class NotCircular(Exception):
@ -19,7 +27,7 @@ def cyclic_rotation(n):
for i in xrange(len(s)): for i in xrange(len(s)):
yield int(s[i:] + s[:i]) yield int(s[i:] + s[:i])
if __name__ == '__main__': def main():
MAX = 1000000 MAX = 1000000
circular_primes = [] circular_primes = []
print 'Generating primes for p < {0}...'.format(MAX) print 'Generating primes for p < {0}...'.format(MAX)
@ -40,3 +48,6 @@ if __name__ == '__main__':
pass pass
# Clear all permutations from the list? # Clear all permutations from the list?
print 'Circular Primes ({0}): {1}'.format(len(circular_primes), circular_primes) print 'Circular Primes ({0}): {1}'.format(len(circular_primes), circular_primes)
if __name__ == '__main__':
main()

13
e036.py
View file

@ -1,9 +1,17 @@
"""Find the sum of all numbers less than one million, which are palindromic in base 10 and base 2.
The decimal number, 585 = 10010010012 (binary), is palindromic in both bases.
Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.
(Please note that the palindromic number, in either base, may not include leading zeros.)
"""
MAX = 1000000 MAX = 1000000
def binary(n): def binary(n):
return '{0:b}'.format(n) return '{0:b}'.format(n)
if __name__ == '__main__': def main():
total = 0 total = 0
i = 0 i = 0
while i < MAX: while i < MAX:
@ -17,3 +25,6 @@ if __name__ == '__main__':
print n, b print n, b
total = total + i total = total + i
print 'Total:', total print 'Total:', total
if __name__ == '__main__':
main()

12
e048.py
View file

@ -1,3 +1,10 @@
"""Find the last ten digits of 1**1 + 2**2 + ... + 1000**1000.
The series, 1**1 + 2**2 + 3**3 + ... + 10**10 = 10405071317.
Find the last ten digits of the series, 1**1 + 2**2 + 3**3 + ... + 1000**1000.
"""
def powerseries(n): def powerseries(n):
i = 1 i = 1
total = 0 total = 0
@ -6,6 +13,9 @@ def powerseries(n):
i = i + 1 i = i + 1
return total return total
if __name__ == '__main__': def main():
val = str(powerseries(1000)) val = str(powerseries(1000))
print 'Last 10:', val[-10:] print 'Last 10:', val[-10:]
if __name__ == '__main__':
main()

48
e054.py
View file

@ -1,6 +1,49 @@
"""How many hands did player one win in the game of poker?
In the card game poker, a hand consists of five cards and are ranked, from lowest to highest, in the following way:
High Card: Highest value card.
One Pair: Two cards of the same value.
Two Pairs: Two different pairs.
Three of a Kind: Three cards of the same value.
Straight: All cards are consecutive values.
Flush: All cards of the same suit.
Full House: Three of a kind and a pair.
Four of a Kind: Four cards of the same value.
Straight Flush: All cards are consecutive values of same suit.
Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
The cards are valued in the order:
2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
If two players have the same ranked hands then the rank made up of the highest value wins; for example, a pair of eights beats a pair of fives (see example 1 below). But if two ranks tie, for example, both players have a pair of queens, then highest cards in each hand are compared (see example 4 below); if the highest cards tie then the next highest cards are compared, and so on.
Consider the following five hands dealt to two players:
Hand Player 1 Player 2 Winner
1 5H 5C 6S 7S KD 2C 3S 8S 8D TD Player 2
Pair of Fives Pair of Eights
2 5D 8C 9S JS AC 2C 5C 7D 8S QH
Highest card Ace Highest Card Queen Player 1
3 2D 9C AS AH AC 3D 6D 7D TD QD
Three Aces Flush with Diamonds Player 2
4 4D 6S 9H QH QC 3D 6D 7H QD QS Player 1
Pair of Queens Pair of Queens
Highest card Nine Highest card Seven
5 2H 2D 4C 4D 4S 3C 3D 3S 9S 9D Player 1
Full House Full House
With Three Fours With Three Threes
The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.
How many hands does Player 1 win?
"""
from p054 import poker from p054 import poker
if __name__ == '__main__': def main():
wins = 0 wins = 0
counter = 0 counter = 0
with open('p054/poker.txt', 'r') as f: with open('p054/poker.txt', 'r') as f:
@ -26,3 +69,6 @@ if __name__ == '__main__':
one, one,
two) two)
print "Player one won {0} hands".format(wins) print "Player one won {0} hands".format(wins)
if __name__ == '__main__':
main()

45
e067.py
View file

@ -1,13 +1,34 @@
"""Using an efficient algorithm find the maximal sum in the triangle?
By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom in triangle.txt (p067/triangle.txt), a 15K text file containing a triangle with one-hundred rows.
NOTE: This is a much more difficult version of Problem 18. It is not possible to try every route to solve this problem, as there are 299 altogether! If you could check one trillion (10**12) routes every second it would take over twenty billion years to check them all. There is an efficient algorithm to solve it. ;o)
"""
from e018 import Triangle from e018 import Triangle
vertex_data = []
with open('p067/triangle.txt', 'r') as f: def main():
while True: vertex_data = []
line = f.readline() with open('p067/triangle.txt', 'r') as f:
if not line: while True:
break line = f.readline()
vertex_data = vertex_data + [int(v) for v in line.split(' ')] if not line:
t = Triangle(vertex_data) break
t.find_path() vertex_data = vertex_data + [int(v) for v in line.split(' ')]
path = t.get_path() t = Triangle(vertex_data)
print 'Path', [v.value for v in path] t.find_path()
print 'Sum', sum([v.value for v in path]) path = t.get_path()
print 'Path', [v.value for v in path]
print 'Sum', sum([v.value for v in path])
if __name__ == '__main__':
main()

BIN
p015/p_015.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB