Add comments

Added comments to the python code for the first 25 problems
This commit is contained in:
daniele 2019-09-26 13:41:22 +02:00
parent ecdbadba7e
commit dfb13c083b
Signed by: fuxino
GPG Key ID: 6FE25B4A3EE16FDA
30 changed files with 538 additions and 44 deletions

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "projecteuler.h"

View File

@ -1,4 +1,4 @@
/* n the 20×20 grid below, four numbers along a diagonal line have been marked in red.
/* In the 20×20 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

View File

@ -33,7 +33,7 @@ int main(int argc, char **argv)
clock_gettime(CLOCK_MONOTONIC, &end);
elapsed=(end.tv_sec-start.tv_sec)+(double)(end.tv_nsec-start.tv_nsec)/1000000000;
elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000;
printf("Project Euler, Problem 20\n");
gmp_printf("Answer: %Zd\n", sum);

View File

@ -3,8 +3,8 @@
*
* 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.*/
*
* Evaluate the sum of all the amicable numbers under 10000.*/
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,5 +1,9 @@
#!/usr/bin/python3
# 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.
from timeit import default_timer
def main():
@ -7,6 +11,8 @@ def main():
sum_ = 0
# Simple brute-force approach: try every number between 3 and 999,
# check if it's a multiple of 3 or 5, if yes add it to the total.
for i in range(3, 1000):
if i % 3 == 0 or i % 5 == 0:
sum_ += i

View File

@ -1,17 +1,27 @@
#!/usr/bin/python3
# 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.
from timeit import default_timer
def main():
start = default_timer()
N = 4000000
fib1 = 1
fib2 = 2
fibn = fib1 + fib2
sum_ = 2
while fibn < 4000000:
# Simple brute-force approach: generate every value in the Fibonacci
# sequence smaller than 4 million and if it's even add it to the total.
while fibn < N:
if fibn % 2 == 0:
sum_ = sum_ + fibn

View File

@ -1,24 +1,39 @@
#!/usr/bin/python3
# The prime factors of 13195 are 5, 7, 13 and 29.
#
# What is the largest prime factor of the number 600851475143?
from math import floor, sqrt
from timeit import default_timer
from projecteuler import is_prime
# Recursive approach: if num is prime, return num, otherwise
# recursively look for the largest prime factor of num divided
# by its prime factors until only the largest remains.
def max_prime_factor(num):
# Use function defined in projecteuler.py to check if a number is prime.
if is_prime(num):
return num
# If num is even, find the largest prime factor of num/2.
if num % 2 == 0:
return max_prime_factor(num // 2)
else:
limit = floor(sqrt(num)) + 1
i = 3
for i in range(3, limit, 2):
# If num is divisible by i and i is prime, find largest
# prime factor of num/i.
while 1:
if num % i == 0:
if is_prime(i):
return max_prime_factor(num // i)
return max_prime_factor(num//i)
i = i + 2
# Should never get here
return -1
def main():
start = default_timer()

View File

@ -1,5 +1,9 @@
#!/usr/bin/python3
# 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.
from timeit import default_timer
from projecteuler import is_palindrome
@ -8,9 +12,13 @@ def main():
max_ = 0
# Using a brute-force approach: generate every product of 3-digit numbers
# and check if it's palindrome. If the product found is greater than the
# current maximum, save the current product.
for i in range(999, 99, -1):
for j in range(i, 99, -1):
num = i * j
# Use the function defined in projecteuler.py to check if a number is palindrome.
if num > max_ and is_palindrome(num, 10):
max_ = num

View File

@ -1,5 +1,9 @@
#!/usr/bin/python3
# 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?
from timeit import default_timer
from projecteuler import lcmm
@ -9,6 +13,7 @@ def main():
values = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
# Function define in projecteuler.py to find the least common multiple of multiple numbers.
res = lcmm(values, 20)
end = default_timer()

View File

@ -1,12 +1,26 @@
#!/usr/bin/python3
# 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 numbers is,
#
# (1 + 2 + ... + 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.
from timeit import default_timer
def main():
start = default_timer()
sum_squares = 0
square_sum = 0
# Straightforward brute-force approach.
for i in range(1, 101):
sum_squares = sum_squares + i * i
square_sum = square_sum + i

View File

@ -1,5 +1,9 @@
#!/usr/bin/python3
# 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?
from timeit import default_timer
from projecteuler import is_prime
@ -9,9 +13,12 @@ def main():
count = 1
n = 1
# Brute force approach: start with count=1 and check every odd number
# (2 is the only even prime), if it's prime increment count, until the
# target prime is reached.
while count != 10001:
n = n + 2
# Use the function in projecteuler.py to check if a number is prime.
if is_prime(n):
count = count + 1

View File

@ -1,5 +1,30 @@
#!/usr/bin/python3
# The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.
#
# 73167176531330624919225119674426574742355349194934
# 96983520312774506326239578318016984801869478851843
# 85861560789112949495459501737958331952853208805511
# 12540698747158523863050715693290963295227443043557
# 66896648950445244523161731856403098711121722383113
# 62229893423380308135336276614282806444486645238749
# 30358907296290491560440772390713810515859307960866
# 70172427121883998797908792274921901699720888093776
# 65727333001053367881220235421809751254540594752243
# 52584907711670556013604839586446706324415722155397
# 53697817977846174064955149290862569321978468622482
# 83972241375657056057490261407972968652414535100474
# 82166370484403199890008895243450658541227588666881
# 16427171479924442928230863465674813919123162824586
# 17866458359124566529476545682848912883142607690042
# 24219022671055626321111109370544217506941658960408
# 07198403850962455444362981230987879927244284909188
# 84580156166097919133875499200524063689912560717606
# 05886116467109405077541002256983155200055935729725
# 71636269561882670428252483600823257530420752963450
#
# Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
from timeit import default_timer
def main():
@ -25,10 +50,12 @@ def main():
'05886116467109405077541002256983155200055935729725' +\
'71636269561882670428252483600823257530420752963450'
# Transform the string into a list of integers
number = list(map(int, number))
max_ = 0
# Calculate all the 13-digit products, and save the maximum
for i in range(1000-13):
curr = number[i:i+13]
prod = 1

View File

@ -1,5 +1,15 @@
#!/usr/bin/python3
# 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.
from timeit import default_timer
def main():
@ -9,6 +19,8 @@ def main():
m = 2
# Brute force approach: generate all the Pythagorean triplets using
# Euclid's formula, until the one where a+b+c=1000 is found.
while not found:
for n in range(1, m):
a = m * m - n * n

View File

@ -1,5 +1,9 @@
#!/usr/bin/python3
# The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
#
# Find the sum of all the primes below two million.
from timeit import default_timer
from projecteuler import sieve
@ -8,9 +12,12 @@ def main():
N = 2000000
# Use the function in projecteuler.py implementing the
# Sieve of Eratosthenes algorithm to generate primes.
primes = sieve(N)
sum_ = 0
# Sum all the primes
for i in range(N):
if primes[i] == 1:
sum_ = sum_ + i

View File

@ -1,5 +1,32 @@
#!/usr/bin/python3
# In the 20×20 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 the same direction (up, down, left, right, or diagonally) in the 20×20 grid?
from timeit import default_timer
def main():
@ -28,11 +55,14 @@ def main():
max_ = 0
# Brute-force approach: for each number in the grid, try products with its three
# adjacent numbers in every direction (horizontal, vertical and the two diagonals).
# If the product is larger than the current maximum, save it.
for i in range(17):
for j in range(17):
# Horizontal direction.
prod = 1
k = j
while k < j + 4:
prod = prod * grid[i][k]
k = k + 1
@ -40,9 +70,9 @@ def main():
if prod > max_:
max_ = prod
# Vertical direction.
prod = 1
k = i
while k < i + 4:
prod = prod * grid[k][j]
k = k + 1
@ -50,6 +80,7 @@ def main():
if prod > max_:
max_ = prod
# Diagonal direction, from top left to bottom right.
prod = 1
k = i
w = j
@ -62,8 +93,10 @@ def main():
if prod > max_:
max_ = prod
# The last diagonal is handled separately
for i in range(17):
for j in range(3, 20):
# Diagonal direction, from top right to bottom left.
prod = 1
k = i
w = j

View File

@ -1,5 +1,24 @@
#!/usr/bin/python3
# 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 timeit import default_timer
from projecteuler import count_divisors
@ -10,10 +29,12 @@ def main():
triang = 0
finished = 0
# Generate all triangle numbers until the first one with more than 500 divisors is found.
while not finished:
i = i + 1
triang = triang + i
# Use the function implemented in projecteuler.py to count divisors of a number.
if count_divisors(triang) > 500:
finished = 1

View File

@ -1,5 +1,108 @@
#!/usr/bin/python3
# Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.
#
# 37107287533902102798797998220837590246510135740250
# 46376937677490009712648124896970078050417018260538
# 74324986199524741059474233309513058123726617309629
# 91942213363574161572522430563301811072406154908250
# 23067588207539346171171980310421047513778063246676
# 89261670696623633820136378418383684178734361726757
# 28112879812849979408065481931592621691275889832738
# 44274228917432520321923589422876796487670272189318
# 47451445736001306439091167216856844588711603153276
# 70386486105843025439939619828917593665686757934951
# 62176457141856560629502157223196586755079324193331
# 64906352462741904929101432445813822663347944758178
# 92575867718337217661963751590579239728245598838407
# 58203565325359399008402633568948830189458628227828
# 80181199384826282014278194139940567587151170094390
# 35398664372827112653829987240784473053190104293586
# 86515506006295864861532075273371959191420517255829
# 71693888707715466499115593487603532921714970056938
# 54370070576826684624621495650076471787294438377604
# 53282654108756828443191190634694037855217779295145
# 36123272525000296071075082563815656710885258350721
# 45876576172410976447339110607218265236877223636045
# 17423706905851860660448207621209813287860733969412
# 81142660418086830619328460811191061556940512689692
# 51934325451728388641918047049293215058642563049483
# 62467221648435076201727918039944693004732956340691
# 15732444386908125794514089057706229429197107928209
# 55037687525678773091862540744969844508330393682126
# 18336384825330154686196124348767681297534375946515
# 80386287592878490201521685554828717201219257766954
# 78182833757993103614740356856449095527097864797581
# 16726320100436897842553539920931837441497806860984
# 48403098129077791799088218795327364475675590848030
# 87086987551392711854517078544161852424320693150332
# 59959406895756536782107074926966537676326235447210
# 69793950679652694742597709739166693763042633987085
# 41052684708299085211399427365734116182760315001271
# 65378607361501080857009149939512557028198746004375
# 35829035317434717326932123578154982629742552737307
# 94953759765105305946966067683156574377167401875275
# 88902802571733229619176668713819931811048770190271
# 25267680276078003013678680992525463401061632866526
# 36270218540497705585629946580636237993140746255962
# 24074486908231174977792365466257246923322810917141
# 91430288197103288597806669760892938638285025333403
# 34413065578016127815921815005561868836468420090470
# 23053081172816430487623791969842487255036638784583
# 11487696932154902810424020138335124462181441773470
# 63783299490636259666498587618221225225512486764533
# 67720186971698544312419572409913959008952310058822
# 95548255300263520781532296796249481641953868218774
# 76085327132285723110424803456124867697064507995236
# 37774242535411291684276865538926205024910326572967
# 23701913275725675285653248258265463092207058596522
# 29798860272258331913126375147341994889534765745501
# 18495701454879288984856827726077713721403798879715
# 38298203783031473527721580348144513491373226651381
# 34829543829199918180278916522431027392251122869539
# 40957953066405232632538044100059654939159879593635
# 29746152185502371307642255121183693803580388584903
# 41698116222072977186158236678424689157993532961922
# 62467957194401269043877107275048102390895523597457
# 23189706772547915061505504953922979530901129967519
# 86188088225875314529584099251203829009407770775672
# 11306739708304724483816533873502340845647058077308
# 82959174767140363198008187129011875491310547126581
# 97623331044818386269515456334926366572897563400500
# 42846280183517070527831839425882145521227251250327
# 55121603546981200581762165212827652751691296897789
# 32238195734329339946437501907836945765883352399886
# 75506164965184775180738168837861091527357929701337
# 62177842752192623401942399639168044983993173312731
# 32924185707147349566916674687634660915035914677504
# 99518671430235219628894890102423325116913619626622
# 73267460800591547471830798392868535206946944540724
# 76841822524674417161514036427982273348055556214818
# 97142617910342598647204516893989422179826088076852
# 87783646182799346313767754307809363333018982642090
# 10848802521674670883215120185883543223812876952786
# 71329612474782464538636993009049310363619763878039
# 62184073572399794223406235393808339651327408011116
# 66627891981488087797941876876144230030984490851411
# 60661826293682836764744779239180335110989069790714
# 85786944089552990653640447425576083659976645795096
# 66024396409905389607120198219976047599490197230297
# 64913982680032973156037120041377903785566085089252
# 16730939319872750275468906903707539413042652315011
# 94809377245048795150954100921645863754710598436791
# 78639167021187492431995700641917969777599028300699
# 15368713711936614952811305876380278410754449733078
# 40789923115535562561142322423255033685442488917353
# 44889911501440648020369068063960672322193204149535
# 41503128880339536053299340368006977710650566631954
# 81234880673210146739058568557934581403627822703280
# 82616570773948327592232845941706525094512325230608
# 22918802058777319719839450180888072429661980811197
# 77158542502016545090413245809786882778948721859617
# 72107838435069186155435662884062257473692284509516
# 20849603980134001723930671666823555245252804609722
# 53503534226472524250874054075591789781264330331690
import numpy as np
from timeit import default_timer
@ -108,6 +211,7 @@ def main():
20849603980134001723930671666823555245252804609722,
53503534226472524250874054075591789781264330331690]
# Convert the list of numbers in a numpy array and calculate the sum
numbers = np.array(numbers)
sum_ = str(numbers.sum())

View File

@ -1,15 +1,39 @@
#!/usr/bin/python3
# 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.
from numpy import zeros
from timeit import default_timer
collatz_found = zeros(1000000, dtype=int)
N = 1000000
collatz_found = zeros(N, dtype=int)
# Recursive function to calculate the Collatz sequence for n.
# If n is even, Collatz(n)=1+Collatz(n/2), if n is odd
# Collatz(n)=1+Collatz(3*n+1).
def collatz_length(n):
if n == 1:
return 1
if n < 1000000 and collatz_found[n]:
# If Collatz(n) has been previously calculated,
# just return the value.
if n < N and collatz_found[n]:
return collatz_found[n]
if n % 2 == 0:
@ -23,7 +47,9 @@ def main():
max_l = 0
max_ = 0
for i in range(1, 1000000):
# For each number from 1 to 1000000, find the length of the sequence
# and save its value, so that it can be used for the next numbers.
for i in range(1, N):
count = collatz_length(i)
collatz_found[i] = count

View File

@ -1,5 +1,8 @@
#!/usr/bin/python3
# Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 routes to the bottom right corner
# How many such routes are there through a 20×20 grid?
from math import factorial
from timeit import default_timer
@ -7,6 +10,10 @@ from timeit import default_timer
def main():
start = default_timer()
# Using a combinatorial solution: in a 20x20 grid there will always be
# 20 movements to the right and 20 movements down, that can be represented
# as a string of Rs and Ds. The number of routes is the number of combinations.
# This is obtained calculating n!/(k!*(n-k)!), where n=40 and k=20.
count = factorial(40)
tmp = factorial(20)
tmp = tmp * tmp

View File

@ -1,10 +1,16 @@
#!/usr/bin/python3
# 2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
#
# What is the sum of the digits of the number 2^1000?
from timeit import default_timer
def main():
start = default_timer()
# Simply calculate 2^1000, convert the result to string and calculate
# the sum of the digits
res = str(2 ** 1000)
sum_ = 0

View File

@ -1,32 +1,59 @@
#!/usr/bin/python3
# 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.
from timeit import default_timer
def main():
start = default_timer()
# First list contains number of letters for numbers from 1 to 19,
# the second letters for "twenty", "thirty", ..., "ninety",
# the third letters for "one hundred and", "two hundred and", ..., "nine hundre and",
# the last one-element one the number of letters of 1000
n_letters = [[3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8],\
[60, 60, 50, 50, 50, 70, 60, 60],\
[1300, 1300, 1500, 1400, 1400, 1300, 1500, 1500, 1400],\
[6, 6, 5, 5, 5, 7, 6, 6],\
[13, 13, 15, 14, 14, 13, 15, 15, 14],\
[11]]
sum_ = 0
# Sum the letters of the first 19 numbers.
for i in range(19):
sum_ = sum_ + n_letters[0][i]
# Add the letters of the numbers from 20 to 99.
for i in range(8):
# "Twenty", "thirty", ... "ninety" are used ten times each
# (e.g. "twenty", "twenty one", "twenty two", ..., "twenty nine").
n_letters[1][i] = n_letters[1][i] * 10
# Add "one", "two", ..., "nine".
for j in range(9):
n_letters[1][i] = n_letters[1][i] + n_letters[0][j]
sum_ = sum_ + n_letters[1][i]
# Add the letters of the numbers from 100 to 999.
for i in range(9):
# "One hundred and", "two hundred and",... are used 100 times each.
n_letters[2][i] = n_letters[2][i] * 100
# Add "one" to "nineteen".
for j in range(19):
n_letters[2][i] = n_letters[2][i] + n_letters[0][j]
# Add "twenty" to "ninety nine", previously calculated.
for j in range(8):
n_letters[2][i] = n_letters[2][i] + n_letters[1][j]
# "One hundred", "two hundred", ... don't have the "and", so remove
# three letters for each of them.
sum_ = sum_ + n_letters[2][i] - 3
# Add "one thousand".
sum_ = sum_ + n_letters[3][0]
end = default_timer()

View File

@ -1,5 +1,35 @@
#!/usr/bin/python3
# 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 timeit import default_timer
from projecteuler import find_max_path
@ -24,6 +54,7 @@ def main():
for i in range(l):
triang[i] = list(map(int, triang[i]))
# Use function implemented in projecteuler.c to find the maximum path.
max_ = find_max_path(triang, 15)
end = default_timer()

View File

@ -1,5 +1,18 @@
#!/usr/bin/python3
# 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)?
import datetime
from timeit import default_timer
@ -9,6 +22,7 @@ def main():
count = 0
# Use the datetime library to find out which first day of the month is a Sunday
for year in range(1901, 2001):
for month in range(1, 13):
if datetime.datetime(year, month, 1).weekday() == 6:

View File

@ -1,5 +1,12 @@
#!/usr/bin/python3
# n! means n × (n 1) × ... × 3 × 2 × 1
#
# For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
# and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
#
# Find the sum of the digits in the number 100!
from math import factorial
from timeit import default_timer
@ -7,6 +14,7 @@ from timeit import default_timer
def main():
start = default_timer()
# Calculate the factorial, convert the result to string and sum the digits.
n = str(factorial(100))
sum_ = 0

View File

@ -1,21 +1,17 @@
#!/usr/bin/python3
# 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 math import floor, sqrt
from timeit import default_timer
def sum_of_divisors(n):
limit = floor(sqrt(n)) + 1
sum_ = 1
for i in range(2, limit):
if n % i == 0:
sum_ = sum_ + i
if n != i * i:
sum_ = sum_ + n // i
return sum_
from projecteuler import sum_of_divisors
def main():
start = default_timer()
@ -23,7 +19,11 @@ def main():
sum_ = 0
for i in range(2, 10000):
# Calculate the sum of proper divisors with the function
# implemented in projecteuler.py.
n = sum_of_divisors(i)
# If i!=n and the sum of proper divisors of n=i,
# sum the pair of numbers and add it to the total.
if i != n and sum_of_divisors(n) == i:
sum_ = sum_ + i + n

View File

@ -1,5 +1,13 @@
#!/usr/bin/python3
# Using 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?
from timeit import default_timer
def main():
@ -17,6 +25,7 @@ def main():
sum_ = 0
i = 1
# Calculate the score of each name an multiply by its position.
for name in names:
l = len(name)
score = 0

View File

@ -1,31 +1,39 @@
#!/usr/bin/python3
# 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 math import floor, sqrt
from timeit import default_timer
from projecteuler import sum_of_divisors
def is_abundant(n):
limit = floor(sqrt(n)) + 1
sum_ = 1
for i in range(2, limit):
if n % i == 0:
sum_ = sum_ + i
if n != i * i:
sum_ = sum_ + n // i
return sum_ > n
return sum_of_divisors(n) > n
def main():
start = default_timer()
ab_nums = [False] * 28124
# Find all abundant numbers smaller than 28123.
for i in range(12, 28124):
ab_nums[i] = is_abundant(i)
sums = [False] * 28124
# For every abundant number, sum every other abundant number greater
# than itself, until the sum exceeds 28123. Record that the resulting
# number is the sum of two abundant numbers.
for i in range(1, 28123):
if ab_nums[i]:
for j in range(i, 28123):
@ -36,6 +44,7 @@ def main():
sum_ = 0
# Sum every number that was not found as a sum of two abundant numbers.
for i in range(1, 28124):
if not sums[i]:
sum_ = sum_ + i

View File

@ -1,5 +1,12 @@
#!/usr/bin/python3
# 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?
from itertools import permutations
from timeit import default_timer
@ -7,6 +14,7 @@ from timeit import default_timer
def main():
start = default_timer()
# Generate all the permutations in lexicographic order and get the millionth one.
perm = list(permutations('0123456789'))
res = int(''.join(map(str, perm[999999])))

View File

@ -1,5 +1,26 @@
#!/usr/bin/python3
# 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 index of the first term in the Fibonacci sequence to contain 1000 digits?
from timeit import default_timer
def main():
@ -11,6 +32,7 @@ def main():
i = 3
# Calculate the Fibonacci numbers until one with 1000 digits is found.
while len(str(fibn)) < 1000:
fib1 = fib2
fib2 = fibn

View File

@ -6,17 +6,26 @@ from numpy import ndarray, zeros
def is_prime(num):
if num < 4:
# If num is 2 or 3 then it's prime.
return num == 2 or num == 3
# If num is divisible by 2 or 3 then it's not prime.
if num % 2 == 0 or num % 3 == 0:
return False
# Any number can have only one prime factor greater than its
# square root. If we reach the square root and we haven't found
# any smaller prime factors, then the number is prime.
limit = floor(sqrt(num)) + 1
# Every prime other than 2 and 3 is in the form 6k+1 or 6k-1.
# If I check all those value no prime factors of the number
# will be missed. If a factor is found, the number is not prime
# and the function returns 0.
for i in range(5, limit, 6):
if num % i == 0 or num % (i + 2) == 0:
return False
# If no factor is found up to the square root of num, num is prime.
return True
def is_palindrome(num, base):
@ -24,44 +33,64 @@ def is_palindrome(num, base):
tmp = num
# Start with reverse=0, get the rightmost digit of the number using
# modulo operation (num modulo base), add it to reverse. Remove the
# rightmost digit from num dividing num by the base, shift the reverse left
# multiplying by the base, repeat until all digits have been inserted
# in reverse order.
while tmp > 0:
reverse = reverse * base
reverse = reverse + tmp % base
tmp = tmp // base
# If the reversed number is equal to the original one, then it's palindrome.
if num == reverse:
return True
return False
# Least common multiple algorithm using the greatest common divisor.
def lcm(a, b):
return a * b // gcd(a, b)
# Recursive function to calculate the least common multiple of more than 2 numbers.
def lcmm(values, n):
# If there are only two numbers, use the lcm function to calculate the lcm.
if n == 2:
return lcm(values[0], values[1])
value = values[0]
for i in range(1, n):
return lcm(value, lcmm(values[i:], n-1))
# Recursively calculate lcm(a, b, c, ..., n) = lcm(a, lcm(b, c, ..., n)).
return lcm(value, lcmm(values[1:], n-1))
# Function implementing the Sieve or Eratosthenes to generate
# primes up to a certain number.
def sieve(n):
primes = ndarray((n,), int)
# 0 and 1 are not prime, 2 and 3 are prime.
primes[0] = 0
primes[1] = 0
primes[2] = 1
primes[3] = 1
# Cross out (set to 0) all even numbers and set the odd numbers to 1 (possible prime).
for i in range(4, n -1, 2):
primes[i] = 0
primes[i+1] = 1
# If i is prime, all multiples of i smaller than i*i have already been crossed out.
# if i=sqrt(n), all multiples of i up to n (the target) have been crossed out. So
# there is no need check i>sqrt(n).
limit = floor(sqrt(n))
for i in range(3, limit, 2):
# Find the next number not crossed out, which is prime.
if primes[i] == 1:
# Cross out all multiples of i, starting with i*i because any smaller multiple
# of i has a smaller prime factor and has already been crossed out. Also, since
# i is odd, i*i+i is even and has already been crossed out, so multiples are
# crossed out with steps of 2*i.
for j in range(i * i, n, 2 * i):
primes[j] = 0
@ -69,6 +98,10 @@ def sieve(n):
def count_divisors(n):
count = 0
# For every divisor below the square root of n, there is a corresponding one
# above the square root, so it's sufficient to check up to the square root of n
# and count every divisor twice. If n is a perfect square, the last divisor is
# wrongly counted twice and must be corrected.
limit = floor(sqrt(n))
for i in range(1, limit):
@ -81,7 +114,11 @@ def count_divisors(n):
return count
def find_max_path(triang, n):
# Start from the second to last row and go up.
for i in range(n-2, -1, -1):
# For each element in the row, check the two adjacent elements
# in the row below and sum the larger one to it. At the end,
# the element at the top will contain the value of the maximum path.
for j in range(0, i+1):
if triang[i+1][j] > triang[i+1][j+1]:
triang[i][j] = triang[i][j] + triang[i+1][j]
@ -90,6 +127,26 @@ def find_max_path(triang, n):
return triang[0][0]
def sum_of_divisors(n):
# For each divisor of n smaller than the square root of n,
# there is another one larger than the square root. If i is
# a divisor of n, so is n/i. Checking divisors i up to square
# root of n and adding both i and n/i is sufficient to sum
# all divisors.
limit = floor(sqrt(n)) + 1
sum_ = 1
for i in range(2, limit):
if n % i == 0:
sum_ = sum_ + i
# If n is a perfect square, i=limit is a divisor and
# has to be counted only once.
if n != i * i:
sum_ = sum_ + n // i
return sum_
def is_pandigital(value, n):
i = 0
digits = zeros(n + 1, int)
@ -116,6 +173,8 @@ def is_pandigital(value, n):
return True
def is_pentagonal(n):
# A number n is pentagonal if p=(sqrt(24n+1)+1)/6 is an integer.
# In this case, n is the pth pentagonal number.
i = (sqrt(24*n+1) + 1) / 6
return i.is_integer()