Use timing decorator for problems 11-20

This commit is contained in:
daniele 2023-06-07 17:55:56 +02:00
parent 885084211a
commit 634eb3f750
Signed by: fuxino
GPG Key ID: 981A2B2A3BBF5514
10 changed files with 85 additions and 130 deletions

View File

@ -27,12 +27,11 @@
# #
# What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid? # 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 from projecteuler import timing
def main(): @timing
start = default_timer() def p011():
grid = [[8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8], grid = [[8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8],
[49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0], [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0],
[81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65], [81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65],
@ -56,12 +55,12 @@ def main():
max_ = 0 max_ = 0
# Brute-force approach: for each number in the grid, try products with its three # 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). # adjacent numbers in every direction (horizontal, vertical and the two diagonals).
# If the product is larger than the current maximum, save it. # If the product is larger than the current maximum, save it.
for i in range(17): for i in range(17):
for j in range(17): for j in range(17):
# Horizontal direction. # Horizontal direction.
prod = 1 prod = 1
k = j k = j
while k < j + 4: while k < j + 4:
@ -71,7 +70,7 @@ def main():
if prod > max_: if prod > max_:
max_ = prod max_ = prod
# Vertical direction. # Vertical direction.
prod = 1 prod = 1
k = i k = i
while k < i + 4: while k < i + 4:
@ -81,7 +80,7 @@ def main():
if prod > max_: if prod > max_:
max_ = prod max_ = prod
# Diagonal direction, from top left to bottom right. # Diagonal direction, from top left to bottom right.
prod = 1 prod = 1
k = i k = i
w = j w = j
@ -94,10 +93,10 @@ def main():
if prod > max_: if prod > max_:
max_ = prod max_ = prod
# The last diagonal is handled separately # The last diagonal is handled separately
for i in range(17): for i in range(17):
for j in range(3, 20): for j in range(3, 20):
# Diagonal direction, from top right to bottom left. # Diagonal direction, from top right to bottom left.
prod = 1 prod = 1
k = i k = i
w = j w = j
@ -110,13 +109,9 @@ def main():
if prod > max_: if prod > max_:
max_ = prod max_ = prod
end = default_timer()
print('Project Euler, Problem 11') print('Project Euler, Problem 11')
print(f'Answer: {max_}') print(f'Answer: {max_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p011()

View File

@ -19,33 +19,27 @@
# #
# What is the value of the first triangle number to have over five hundred 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, timing
from projecteuler import count_divisors
def main(): @timing
start = default_timer() def p012():
i = 0 i = 0
triang = 0 triang = 0
finished = 0 finished = 0
# Generate all triangle numbers until the first one with more than 500 divisors is found. # Generate all triangle numbers until the first one with more than 500 divisors is found.
while not finished: while not finished:
i = i + 1 i = i + 1
triang = triang + i triang = triang + i
# Use the function implemented in projecteuler.py to count divisors of a number. # Use the function implemented in projecteuler.py to count divisors of a number.
if count_divisors(triang) > 500: if count_divisors(triang) > 500:
finished = 1 finished = 1
end = default_timer()
print('Project Euler, Problem 12') print('Project Euler, Problem 12')
print(f'Answer: {triang}') print(f'Answer: {triang}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p012()

View File

@ -103,13 +103,13 @@
# 20849603980134001723930671666823555245252804609722 # 20849603980134001723930671666823555245252804609722
# 53503534226472524250874054075591789781264330331690 # 53503534226472524250874054075591789781264330331690
from timeit import default_timer
import numpy as np import numpy as np
from projecteuler import timing
def main():
start = default_timer()
@timing
def p013():
numbers = [37107287533902102798797998220837590246510135740250, numbers = [37107287533902102798797998220837590246510135740250,
46376937677490009712648124896970078050417018260538, 46376937677490009712648124896970078050417018260538,
74324986199524741059474233309513058123726617309629, 74324986199524741059474233309513058123726617309629,
@ -211,18 +211,14 @@ def main():
20849603980134001723930671666823555245252804609722, 20849603980134001723930671666823555245252804609722,
53503534226472524250874054075591789781264330331690] 53503534226472524250874054075591789781264330331690]
# Convert the list of numbers in a numpy array and calculate the sum # Convert the list of numbers in a numpy array and calculate the sum
numbers = np.array(numbers) numbers = np.array(numbers)
sum_ = str(numbers.sum()) sum_ = str(numbers.sum())
end = default_timer()
print('Project Euler, Problem 13') print('Project Euler, Problem 13')
print(f'Answer: {sum_[:10]}') print(f'Answer: {sum_[:10]}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p013()

View File

@ -16,9 +16,10 @@
# #
# NOTE: Once the chain starts the terms are allowed to go above one million. # NOTE: Once the chain starts the terms are allowed to go above one million.
from timeit import default_timer
from numpy import zeros from numpy import zeros
from projecteuler import timing
N = 1000000 N = 1000000
collatz_found = zeros(N, dtype=int) collatz_found = zeros(N, dtype=int)
@ -32,8 +33,8 @@ def collatz_length(n):
if n == 1: if n == 1:
return 1 return 1
# If Collatz(n) has been previously calculated, # If Collatz(n) has been previously calculated,
# just return the value. # just return the value.
if n < N and collatz_found[n]: if n < N and collatz_found[n]:
return collatz_found[n] return collatz_found[n]
@ -42,14 +43,14 @@ def collatz_length(n):
return 1 + collatz_length(3*n+1) return 1 + collatz_length(3*n+1)
def main():
start = default_timer()
@timing
def p014():
max_l = 0 max_l = 0
max_ = 0 max_ = 0
# For each number from 1 to 1000000, find the length of the sequence # 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. # and save its value, so that it can be used for the next numbers.
for i in range(1, N): for i in range(1, N):
count = collatz_length(i) count = collatz_length(i)
collatz_found[i] = count collatz_found[i] = count
@ -58,13 +59,9 @@ def main():
max_l = count max_l = count
max_ = i max_ = i
end = default_timer()
print('Project Euler, Problem 14') print('Project Euler, Problem 14')
print(f'Answer: {max_}') print(f'Answer: {max_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p014()

View File

@ -4,28 +4,24 @@
# How many such routes are there through a 20×20 grid? # How many such routes are there through a 20×20 grid?
from math import factorial from math import factorial
from timeit import default_timer
from projecteuler import timing
def main(): @timing
start = default_timer() def p015():
# Using a combinatorial solution: in a 20x20 grid there will always be
# 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
# 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.
# 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.
# This is obtained calculating n!/(k!*(n-k)!), where n=40 and k=20.
count = factorial(40) count = factorial(40)
tmp = factorial(20) tmp = factorial(20)
tmp = tmp * tmp tmp = tmp * tmp
count = count // tmp count = count // tmp
end = default_timer()
print('Project Euler, Problem 15') print('Project Euler, Problem 15')
print(f'Answer: {count}') print(f'Answer: {count}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p015()

View File

@ -4,14 +4,13 @@
# #
# What is the sum of the digits of the number 2^1000? # What is the sum of the digits of the number 2^1000?
from timeit import default_timer from projecteuler import timing
def main(): @timing
start = default_timer() def p016():
# Simply calculate 2^1000, convert the result to string and calculate
# Simply calculate 2^1000, convert the result to string and calculate # the sum of the digits
# the sum of the digits
res = str(2 ** 1000) res = str(2 ** 1000)
sum_ = 0 sum_ = 0
@ -19,13 +18,9 @@ def main():
for i in res: for i in res:
sum_ = sum_ + int(i) sum_ = sum_ + int(i)
end = default_timer()
print('Project Euler, Problem 16') print('Project Euler, Problem 16')
print(f'Answer: {sum_}') print(f'Answer: {sum_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p016()

View File

@ -7,16 +7,15 @@
# NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) # 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. # contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
from timeit import default_timer from projecteuler import timing
def main(): @timing
start = default_timer() def p017():
# First list contains number of letters for numbers from 1 to 19,
# First list contains number of letters for numbers from 1 to 19, # the second letters for "twenty", "thirty", ..., "ninety",
# the second letters for "twenty", "thirty", ..., "ninety", # the third letters for "one hundred and", "two hundred and", ..., "nine hundre and",
# the third letters for "one hundred and", "two hundred and", ..., "nine hundre and", # the last one-element one the number of letters of 1000
# 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], n_letters = [[3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8],
[6, 6, 5, 5, 5, 7, 6, 6], [6, 6, 5, 5, 5, 7, 6, 6],
[13, 13, 15, 14, 14, 13, 15, 15, 14], [13, 13, 15, 14, 14, 13, 15, 15, 14],
@ -24,46 +23,43 @@ def main():
sum_ = 0 sum_ = 0
# Sum the letters of the first 19 numbers. # Sum the letters of the first 19 numbers.
for i in range(19): for i in range(19):
sum_ = sum_ + n_letters[0][i] sum_ = sum_ + n_letters[0][i]
# Add the letters of the numbers from 20 to 99. # Add the letters of the numbers from 20 to 99.
for i in range(8): for i in range(8):
# "Twenty", "thirty", ... "ninety" are used ten times each # "Twenty", "thirty", ... "ninety" are used ten times each
# (e.g. "twenty", "twenty one", "twenty two", ..., "twenty nine"). # (e.g. "twenty", "twenty one", "twenty two", ..., "twenty nine").
n_letters[1][i] = n_letters[1][i] * 10 n_letters[1][i] = n_letters[1][i] * 10
# Add "one", "two", ..., "nine". # Add "one", "two", ..., "nine".
for j in range(9): for j in range(9):
n_letters[1][i] = n_letters[1][i] + n_letters[0][j] n_letters[1][i] = n_letters[1][i] + n_letters[0][j]
sum_ = sum_ + n_letters[1][i] sum_ = sum_ + n_letters[1][i]
# Add the letters of the numbers from 100 to 999. # Add the letters of the numbers from 100 to 999.
for i in range(9): for i in range(9):
# "One hundred and", "two hundred and",... are used 100 times each. # "One hundred and", "two hundred and",... are used 100 times each.
n_letters[2][i] = n_letters[2][i] * 100 n_letters[2][i] = n_letters[2][i] * 100
# Add "one" to "nineteen". # Add "one" to "nineteen".
for j in range(19): for j in range(19):
n_letters[2][i] = n_letters[2][i] + n_letters[0][j] n_letters[2][i] = n_letters[2][i] + n_letters[0][j]
# Add "twenty" to "ninety nine", previously calculated. # Add "twenty" to "ninety nine", previously calculated.
for j in range(8): for j in range(8):
n_letters[2][i] = n_letters[2][i] + n_letters[1][j] n_letters[2][i] = n_letters[2][i] + n_letters[1][j]
# "One hundred", "two hundred", ... don't have the "and", so remove # "One hundred", "two hundred", ... don't have the "and", so remove
# three letters for each of them. # three letters for each of them.
sum_ = sum_ + n_letters[2][i] - 3 sum_ = sum_ + n_letters[2][i] - 3
# Add "one thousand". # Add "one thousand".
sum_ = sum_ + n_letters[3][0] sum_ = sum_ + n_letters[3][0]
end = default_timer()
print('Project Euler, Problem 17') print('Project Euler, Problem 17')
print(f'Answer: {sum_}') print(f'Answer: {sum_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p017()

View File

@ -31,14 +31,12 @@
# with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o) # with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)
import sys import sys
from timeit import default_timer
from projecteuler import find_max_path from projecteuler import find_max_path, timing
def main(): @timing
start = default_timer() def p018():
try: try:
with open('p018_triangle.txt', 'r', encoding='utf-8') as fp: with open('p018_triangle.txt', 'r', encoding='utf-8') as fp:
triang = [] triang = []
@ -54,16 +52,12 @@ def main():
for i in range(l): for i in range(l):
triang[i] = list(map(int, triang[i])) triang[i] = list(map(int, triang[i]))
# Use the function implemented in projecteuler.c to find the maximum path. # Use the function implemented in projecteuler.c to find the maximum path.
max_ = find_max_path(triang, 15) max_ = find_max_path(triang, 15)
end = default_timer()
print('Project Euler, Problem 18') print('Project Euler, Problem 18')
print(f'Answer: {max_}') print(f'Answer: {max_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p018()

View File

@ -14,27 +14,23 @@
# How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)? # How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
import datetime import datetime
from timeit import default_timer
from projecteuler import timing
def main(): @timing
start = default_timer() def p019():
count = 0 count = 0
# Use the datetime library to find out which first day of the month is a Sunday # Use the datetime library to find out which first day of the month is a Sunday
for year in range(1901, 2001): for year in range(1901, 2001):
for month in range(1, 13): for month in range(1, 13):
if datetime.datetime(year, month, 1).weekday() == 6: if datetime.datetime(year, month, 1).weekday() == 6:
count = count + 1 count = count + 1
end = default_timer()
print('Project Euler, Problem 19') print('Project Euler, Problem 19')
print(f'Answer: {count}') print(f'Answer: {count}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p019()

View File

@ -8,13 +8,13 @@
# Find the sum of the digits in the number 100! # Find the sum of the digits in the number 100!
from math import factorial from math import factorial
from timeit import default_timer
from projecteuler import timing
def main(): @timing
start = default_timer() def p020():
# Calculate the factorial, convert the result to string and sum the digits.
# Calculate the factorial, convert the result to string and sum the digits.
n = str(factorial(100)) n = str(factorial(100))
sum_ = 0 sum_ = 0
@ -22,13 +22,9 @@ def main():
for i in n: for i in n:
sum_ = sum_ + int(i) sum_ = sum_ + int(i)
end = default_timer()
print('Project Euler, Problem 20') print('Project Euler, Problem 20')
print(f'Answer: {sum_}') print(f'Answer: {sum_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__': if __name__ == '__main__':
main() p020()