From be5e97dfbb39fb6bc68e80158a7d03e0d6138dd4 Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Wed, 7 Jun 2023 18:17:42 +0200 Subject: [PATCH] Use timing decorator for problems 21-40 --- Python/p021.py | 24 +++++++++-------------- Python/p022.py | 14 +++++-------- Python/p023.py | 25 +++++++++--------------- Python/p024.py | 16 ++++++--------- Python/p025.py | 15 +++++--------- Python/p026.py | 27 ++++++++++--------------- Python/p027.py | 19 ++++++------------ Python/p028.py | 21 ++++++++------------ Python/p029.py | 17 ++++++---------- Python/p030.py | 19 +++++++----------- Python/p031.py | 13 ++++--------- Python/p032.py | 53 ++++++++++++++++++++++---------------------------- Python/p033.py | 20 ++++++++----------- Python/p034.py | 16 ++++++--------- Python/p035.py | 29 +++++++++++---------------- Python/p036.py | 21 +++++++------------- Python/p037.py | 32 ++++++++++++------------------ Python/p038.py | 27 ++++++++++--------------- Python/p039.py | 31 ++++++++++++----------------- Python/p040.py | 21 ++++++++------------ 20 files changed, 172 insertions(+), 288 deletions(-) diff --git a/Python/p021.py b/Python/p021.py index 8693f3c..50e4bc4 100644 --- a/Python/p021.py +++ b/Python/p021.py @@ -9,34 +9,28 @@ # Evaluate the sum of all the amicable numbers under 10000. -from timeit import default_timer - -from projecteuler import sum_of_divisors +from projecteuler import sum_of_divisors, timing -def main(): - start = default_timer() - +@timing +def p021(): sum_ = 0 for i in range(2, 10000): -# Calculate the sum of proper divisors with the function -# implemented in projecteuler.py. + # 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 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 sum_ = sum_ // 2 - end = default_timer() - print('Project Euler, Problem 21') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p021() diff --git a/Python/p022.py b/Python/p022.py index 57e1374..9965a67 100644 --- a/Python/p022.py +++ b/Python/p022.py @@ -9,12 +9,12 @@ # What is the total of all the name scores in the file? import sys -from timeit import default_timer + +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p022(): try: with open('p022_names.txt', 'r', encoding='utf-8') as fp: names = list(fp.readline().replace('"', '').split(',')) @@ -37,13 +37,9 @@ def main(): sum_ = sum_ + score i = i + 1 - end = default_timer() - print('Project Euler, Problem 22') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p022() diff --git a/Python/p023.py b/Python/p023.py index be364ea..118cbf1 100644 --- a/Python/p023.py +++ b/Python/p023.py @@ -12,29 +12,26 @@ # # Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers. -from timeit import default_timer - -from projecteuler import sum_of_divisors +from projecteuler import sum_of_divisors, timing def is_abundant(n): return sum_of_divisors(n) > n -def main(): - start = default_timer() - +@timing +def p023(): ab_nums = [False] * 28124 -# Find all abundant numbers smaller than 28123. + # 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 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): @@ -45,18 +42,14 @@ def main(): sum_ = 0 -# Sum every number that was not found as a sum of two abundant numbers. + # 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 - end = default_timer() - print('Project Euler, Problem 23') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p023() diff --git a/Python/p024.py b/Python/p024.py index ab723e6..51dbb06 100644 --- a/Python/p024.py +++ b/Python/p024.py @@ -8,23 +8,19 @@ # 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 + +from projecteuler import timing -def main(): - start = default_timer() - -# Generate all the permutations in lexicographic order and get the millionth one. +@timing +def p024(): + # Generate all the permutations in lexicographic order and get the millionth one. perm = list(permutations('0123456789')) res = int(''.join(map(str, perm[999999]))) - end = default_timer() - print('Project Euler, Problem 24') print(f'Answer: {res}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p024() diff --git a/Python/p025.py b/Python/p025.py index 4791a6b..2b3d7ba 100644 --- a/Python/p025.py +++ b/Python/p025.py @@ -21,32 +21,27 @@ # # What is the index of the first term in the Fibonacci sequence to contain 1000 digits? -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p025(): fib1 = 1 fib2 = 1 fibn = fib1 + fib2 i = 3 -# Calculate the Fibonacci numbers until one with 1000 digits is found. + # Calculate the Fibonacci numbers until one with 1000 digits is found. while len(str(fibn)) < 1000: fib1 = fib2 fib2 = fibn fibn = fib1 + fib2 i = i + 1 - end = default_timer() - print('Project Euler, Problem 25') print(f'Answer: {i}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p025() diff --git a/Python/p026.py b/Python/p026.py index 91cd636..93f1448 100644 --- a/Python/p026.py +++ b/Python/p026.py @@ -16,27 +16,24 @@ # # Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part. -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p026(): max_ = 0 for i in range(2, 1000): j = i -# The repeating cycle of 1/(2^a*5^b*p^c*...) is equal to -# that of 1/p^c*..., so factors 2 and 5 can be eliminated. + # The repeating cycle of 1/(2^a*5^b*p^c*...) is equal to that of 1/p^c*..., so factors 2 and 5 can be eliminated. while j % 2 == 0 and j > 1: j = j // 2 while j % 5 == 0 and j > 1: j = j // 5 -# If the denominator had only factors 2 and 5, there is no -# repeating cycle. + # If the denominator had only factors 2 and 5, there is no repeating cycle. if j == 1: n = 0 else: @@ -44,10 +41,10 @@ def main(): k = 9 div = j -# After eliminating factors 2s and 5s, the length of the repeating cycle -# of 1/d is the smallest n for which k=10^n-1/d is an integer. So we start -# with k=9, then k=99, k=999 and so on until k is divisible by d. -# The number of digits of k is the length of the repeating cycle. + # After eliminating factors 2s and 5s, the length of the repeating cycle + # of 1/d is the smallest n for which k=10^n-1/d is an integer. So we start + # with k=9, then k=99, k=999 and so on until k is divisible by d. + # The number of digits of k is the length of the repeating cycle. while k % div != 0: n = n + 1 k = k * 10 @@ -57,13 +54,9 @@ def main(): max_ = n max_n = i - end = default_timer() - print('Project Euler, Problem 26') print(f'Answer: {max_n}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p026() diff --git a/Python/p027.py b/Python/p027.py index b093c6f..cb2ae22 100644 --- a/Python/p027.py +++ b/Python/p027.py @@ -19,20 +19,17 @@ # # Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n=0. -from timeit import default_timer - -from projecteuler import is_prime +from projecteuler import is_prime, timing -def main(): - start = default_timer() - +@timing +def p027(): max_ = 0 -# Brute force approach, optimized by checking only values of b where b is prime. + # Brute force approach, optimized by checking only values of b where b is prime. for a in range(-999, 1000): for b in range(2, 1001): -# For n=0, n^2+an+b=b, so b must be prime. + # For n=0, n^2+an+b=b, so b must be prime. if is_prime(b): n = 0 count = 0 @@ -51,13 +48,9 @@ def main(): save_a = a save_b = b - end = default_timer() - print('Project Euler, Problem 27') print(f'Answer: {save_a * save_b}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p027() diff --git a/Python/p028.py b/Python/p028.py index 8984cd4..6cd2eae 100644 --- a/Python/p028.py +++ b/Python/p028.py @@ -12,12 +12,11 @@ # # What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way? -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p028(): N = 1001 limit = N * N @@ -27,10 +26,10 @@ def main(): step = 0 sum_ = 1 -# Starting with the central 1, it's easy to see that the next four numbers in the diagonal -# are 1+2, 1+2+2, 1+2+2+2 and 1+2+2+2+2, then for the next four number the step is increased -# by two, so from 9 to 9+4, 9+4+4 etc, for the next four number the step is again increased -# by two, and so on. We go on until the value is equal to N*N, with N=1001 for this problem. + # Starting with the central 1, it's easy to see that the next four numbers in the diagonal + # are 1+2, 1+2+2, 1+2+2+2 and 1+2+2+2+2, then for the next four number the step is increased + # by two, so from 9 to 9+4, 9+4+4 etc, for the next four number the step is again increased + # by two, and so on. We go on until the value is equal to N*N, with N=1001 for this problem. while j < limit: if i == 0: step = step + 2 @@ -38,13 +37,9 @@ def main(): sum_ = sum_ + j i = (i + 1) % 4 - end = default_timer() - print('Project Euler, Problem 28') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p028() diff --git a/Python/p029.py b/Python/p029.py index 8396d0e..2ce0438 100644 --- a/Python/p029.py +++ b/Python/p029.py @@ -13,23 +13,22 @@ # # How many distinct terms are in the sequence generated by ab for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100? -from timeit import default_timer - from numpy import zeros +from projecteuler import timing -def main(): - start = default_timer() +@timing +def p029(): powers = zeros(9801) -# Generate all the powers + # Generate all the powers for i in range(2, 101): a = i for j in range(2, 101): powers[(i-2)*99+j-2] = a ** j -# Sort the values and count the different values. + # Sort the values and count the different values. powers = list(powers) powers.sort() @@ -39,13 +38,9 @@ def main(): if powers[i] != powers[i-1]: count = count + 1 - end = default_timer() - print('Project Euler, Problem 29') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p029() diff --git a/Python/p030.py b/Python/p030.py index a91e0bc..6c164c3 100644 --- a/Python/p030.py +++ b/Python/p030.py @@ -12,17 +12,16 @@ # # Find the sum of all the numbers that can be written as the sum of fifth powers of their digits. -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p030(): tot = 0 -# Straightforward brute force approach. The limit is chosen considering that -# 6*9^5=354294, so no number larger than that can be expressed as sum -# of 5th power of its digits. + # Straightforward brute force approach. The limit is chosen considering that + # 6*9^5=354294, so no number larger than that can be expressed as sum + # of 5th power of its digits. for i in range(10, 354295): j = i sum_ = 0 @@ -35,13 +34,9 @@ def main(): if sum_ == i: tot = tot + i - end = default_timer() - print('Project Euler, Problem 30') print(f'Answer: {tot}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p030() diff --git a/Python/p031.py b/Python/p031.py index 25981e6..0a617c3 100644 --- a/Python/p031.py +++ b/Python/p031.py @@ -10,7 +10,7 @@ # # How many different ways can £2 be made using any number of coins? -from timeit import default_timer +from projecteuler import timing # Simple recursive function that tries every combination. @@ -29,20 +29,15 @@ def count(coins, value, n, i): return n -def main(): - start = default_timer() - +@timing +def p031(): coins = [1, 2, 5, 10, 20, 50, 100, 200] n = count(coins, 0, 0, 0) - end = default_timer() - print('Project Euler, Problem 31') print(f'Answer: {n}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p031() diff --git a/Python/p032.py b/Python/p032.py index 1c16343..4b32281 100644 --- a/Python/p032.py +++ b/Python/p032.py @@ -9,34 +9,31 @@ # # HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum. -from timeit import default_timer - import numpy as np from numpy import zeros -from projecteuler import is_pandigital +from projecteuler import is_pandigital, timing -def main(): - start = default_timer() - +@timing +def p032(): n = 0 -# Initially I used a bigger array, but printing the resulting products -# shows that 10 values are sufficient. + # Initially I used a bigger array, but printing the resulting products + # shows that 10 values are sufficient. products = zeros(10, int) -# To get a 1 to 9 pandigital concatenation of the two factors and product, -# we need to multiply a 1 digit number times a 4 digit numbers (the biggest -# one digit number 9 times the biggest 3 digit number 999 multiplied give -# 8991 and the total digit count is 8, which is not enough), or a 2 digit -# number times a 3 digit number (the smallest two different 3 digits number, -# 100 and 101, multiplied give 10100, and the total digit count is 11, which -# is too many). The outer loop starts at 2 because 1 times any number gives -# the same number, so its digit will be repeated and the result can't be -# pandigital. The nested loop starts from 1234 because it's the smallest -# 4-digit number with no repeated digits, and it ends at 4987 because it's -# the biggest number without repeated digits that multiplied by 2 gives a -# 4 digit number. + # To get a 1 to 9 pandigital concatenation of the two factors and product, + # we need to multiply a 1 digit number times a 4 digit numbers (the biggest + # one digit number 9 times the biggest 3 digit number 999 multiplied give + # 8991 and the total digit count is 8, which is not enough), or a 2 digit + # number times a 3 digit number (the smallest two different 3 digits number, + # 100 and 101, multiplied give 10100, and the total digit count is 11, which + # is too many). The outer loop starts at 2 because 1 times any number gives + # the same number, so its digit will be repeated and the result can't be + # pandigital. The nested loop starts from 1234 because it's the smallest + # 4-digit number with no repeated digits, and it ends at 4987 because it's + # the biggest number without repeated digits that multiplied by 2 gives a + # 4 digit number. for i in range(2, 9): for j in range(1234, 4987): p = i * j @@ -51,10 +48,10 @@ def main(): products[n] = p n = n + 1 -# The outer loop starts at 12 because 10 has a 0 and 11 has two 1s, so -# the result can't be pandigital. The nested loop starts at 123 because -# it's the smallest 3-digit number with no digit repetitions and ends at -# 833, because 834*12 has 5 digits. + # The outer loop starts at 12 because 10 has a 0 and 11 has two 1s, so + # the result can't be pandigital. The nested loop starts at 123 because + # it's the smallest 3-digit number with no digit repetitions and ends at + # 833, because 834*12 has 5 digits. for i in range(12, 99): for j in range(123, 834): p = i * j @@ -70,7 +67,7 @@ def main(): products[n] = p n = n + 1 -# Sort the found products to easily see if there are duplicates. + # Sort the found products to easily see if there are duplicates. products = np.sort(products[:n]) sum_ = products[0] @@ -79,13 +76,9 @@ def main(): if products[i] != products[i-1]: sum_ = sum_ + products[i] - end = default_timer() - print('Project Euler, Problem 32') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p032() diff --git a/Python/p033.py b/Python/p033.py index 01870b4..0532362 100644 --- a/Python/p033.py +++ b/Python/p033.py @@ -11,19 +11,19 @@ # If the product of these four fractions is given in its lowest common terms, find the value of the denominator. from math import gcd -from timeit import default_timer + +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p033(): prod_n = 1 prod_d = 1 for i in range(11, 100): for j in range(11, 100): -# If the example is non-trivial, check if cancelling the digit that's equal -# in numerator and denominator gives the same fraction. + # If the example is non-trivial, check if cancelling the digit that's equal + # in numerator and denominator gives the same fraction. if i % 10 != 0 and j % 10 != 0 and\ i != j and i % 10 == j // 10: n = i // 10 @@ -36,16 +36,12 @@ def main(): prod_n = prod_n * i prod_d = prod_d * j -# Find the greater common divisor of the fraction found. + # Find the greater common divisor of the fraction found. div = gcd(prod_n, prod_d) - end = default_timer() - print('Project Euler, Problem 33') print(f'Answer: {prod_d // div}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p033() diff --git a/Python/p034.py b/Python/p034.py index fd7fd9a..52f66ed 100644 --- a/Python/p034.py +++ b/Python/p034.py @@ -7,23 +7,23 @@ # Note: as 1! = 1 and 2! = 2 are not sums they are not included. from math import factorial -from timeit import default_timer from numpy import ones +from projecteuler import timing -def main(): - start = default_timer() +@timing +def p034(): a = 10 sum_ = 0 factorials = ones(10, int) -# Pre-calculate factorials of each digit from 0 to 9. + # Pre-calculate factorials of each digit from 0 to 9. for i in range(2, 10): factorials[i] = factorial(i) -# 9!*7<9999999, so 9999999 is certainly un upper bound. + # 9!*7<9999999, so 9999999 is certainly un upper bound. while a < 9999999: b = a sum_f = 0 @@ -38,13 +38,9 @@ def main(): a = a + 1 - end = default_timer() - print('Project Euler, Problem 34') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p034() diff --git a/Python/p035.py b/Python/p035.py index 6f4e5dd..9190de2 100644 --- a/Python/p035.py +++ b/Python/p035.py @@ -6,9 +6,7 @@ # # How many circular primes are there below one million? -from timeit import default_timer - -from projecteuler import sieve +from projecteuler import sieve, timing # Calculate all primes below one million, then check if they're circular. @@ -17,28 +15,28 @@ primes = sieve(N) def is_circular_prime(n): -# If n is not prime, it's obviously not a circular prime. + # If n is not prime, it's obviously not a circular prime. if primes[n] == 0: return False -# The primes below 10 are circular primes. + # The primes below 10 are circular primes. if primes[n] == 1 and n < 10: return True tmp = n count = 0 -# If the number has one or more even digits, it can't be a circular prime. -# because at least one of the rotations will be even. + # If the number has one or more even digits, it can't be a circular prime. + # because at least one of the rotations will be even. while tmp > 0: if tmp % 2 == 0: return False -# Count the number of digits. + # Count the number of digits. count = count + 1 tmp = tmp // 10 for _ in range(1, count): -# Generate rotations and check if they're prime. + # Generate rotations and check if they're prime. n = n % (10 ** (count - 1)) * 10 + n // (10 ** (count - 1)) if primes[n] == 0: @@ -47,23 +45,18 @@ def is_circular_prime(n): return True -def main(): - start = default_timer() - +@timing +def p035(): count = 13 -# Calculate all primes below one million, then check if they're circular. + # Calculate all primes below one million, then check if they're circular. for i in range(101, N, 2): if is_circular_prime(i): count = count + 1 - end = default_timer() - print('Project Euler, Problem 35') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p035() diff --git a/Python/p036.py b/Python/p036.py index eeb0138..127e1ae 100644 --- a/Python/p036.py +++ b/Python/p036.py @@ -6,32 +6,25 @@ # # (Please note that the palindromic number, in either base, may not include leading zeros.) -from timeit import default_timer - -from projecteuler import is_palindrome +from projecteuler import is_palindrome, timing -def main(): - start = default_timer() - +@timing +def p036(): N = 1000000 sum_ = 0 -# Brute force approach. For every number below 1 million, -# check if they're palindrome in base 2 and 10 using the -# function implemented in projecteuler.c. + # Brute force approach. For every number below 1 million, + # check if they're palindrome in base 2 and 10 using the + # function implemented in projecteuler.c. for i in range(1, N): if is_palindrome(i, 10) and is_palindrome(i, 2): sum_ = sum_ + i - end = default_timer() - print('Project Euler, Problem 36') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p036() diff --git a/Python/p037.py b/Python/p037.py index d0e3cdc..e4279e2 100644 --- a/Python/p037.py +++ b/Python/p037.py @@ -7,29 +7,26 @@ # # NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. -from timeit import default_timer - -from projecteuler import is_prime +from projecteuler import is_prime, timing def is_tr_prime(n): -# One-digit numbers and non-prime numbers are -# not truncatable primes. + # One-digit numbers and non-prime numbers are + # not truncatable primes. if n < 11 or not is_prime(n): return False tmp = n // 10 -# Remove one digit at a time from the right and check -# if the resulting number is prime. Return 0 if it isn't. + # Remove one digit at a time from the right and check + # if the resulting number is prime. Return 0 if it isn't. while tmp > 0: if not is_prime(tmp): return False tmp = tmp // 10 -# Starting from the last digit, check if it's prime, then -# add back one digit at a time on the left and check if it -# is prime. Return 0 when it isn't. + # Starting from the last digit, check if it's prime, then add back one digit at a time on the left and check if it + # is prime. Return 0 when it isn't. i = 10 tmp = n % i @@ -39,31 +36,26 @@ def is_tr_prime(n): i = i * 10 tmp = n % i -# If it gets here, the number is truncatable prime. + # If it gets here, the number is truncatable prime. return True -def main(): - start = default_timer() - +@timing +def p037(): i = 0 n = 1 sum_ = 0 -# Check every number until 11 truncatable primes are found. + # Check every number until 11 truncatable primes are found. while i < 11: if is_tr_prime(n): sum_ = sum_ + n i = i + 1 n = n + 1 - end = default_timer() - print('Project Euler, Problem 37') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p037() diff --git a/Python/p038.py b/Python/p038.py index f22efa1..2464e2f 100644 --- a/Python/p038.py +++ b/Python/p038.py @@ -13,22 +13,19 @@ # # What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n > 1? -from timeit import default_timer - -from projecteuler import is_pandigital +from projecteuler import is_pandigital, timing -def main(): - start = default_timer() - +@timing +def p038(): max_ = 0 -# A brute force approach is used, starting with 1 and multiplying -# the number by 1, 2 etc., concatenating the results, checking if -# it's 1 to 9 pandigital, and going to the next number when the -# concatenated result is greater than the greatest 9 digit pandigital -# value. The limit is set to 10000, since 1*10000=10000, 2*10000=20000 and -# concatenating this two numbers a 10-digit number is obtained. + # A brute force approach is used, starting with 1 and multiplying + # the number by 1, 2 etc., concatenating the results, checking if + # it's 1 to 9 pandigital, and going to the next number when the + # concatenated result is greater than the greatest 9 digit pandigital + # value. The limit is set to 10000, since 1*10000=10000, 2*10000=20000 and + # concatenating this two numbers a 10-digit number is obtained. for i in range(1, 10000): n = 0 j = 1 @@ -54,13 +51,9 @@ def main(): if n > 987654321: break - end = default_timer() - print('Project Euler, Problem 38') print(f'Answer: {max_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p038() diff --git a/Python/p039.py b/Python/p039.py index 4946387..b539848 100644 --- a/Python/p039.py +++ b/Python/p039.py @@ -6,18 +6,17 @@ # # For which value of p ≤ 1000, is the number of solutions maximised? -from timeit import default_timer - from numpy import zeros +from projecteuler import timing -def main(): - start = default_timer() +@timing +def p039(): max_ = 0 savedc = zeros(1000, int) -# Start with p=12 (the smallest pythagorean triplet is (3,4,5) and 3+4+5=12. + # Start with p=12 (the smallest pythagorean triplet is (3,4,5) and 3+4+5=12. for p in range(12, 1001): count = 0 a = 0 @@ -25,16 +24,15 @@ def main(): c = 0 m = 2 -# Generate pythagorean triplets. + # Generate pythagorean triplets. while m * m < p: for n in range(1, m): a = m * m - n * n b = 2 * m * n c = m * m + n * n -# Increase counter if a+b+c=p and the triplet is new, -# then save the value of c to avoid counting the same -# triplet more than once. + # Increase counter if a+b+c=p and the triplet is new, then save the value of c to avoid counting the same + # triplet more than once. if a + b + c == p and savedc[c] == 0: savedc[c] = 1 count = count + 1 @@ -44,14 +42,13 @@ def main(): tmpb = b tmpc = c -# Check all the triplets obtained multiplying a, b and c -# for integer numbers, until the perimeters exceeds p. + # Check all the triplets obtained multiplying a, b and c for integer numbers, until the perimeters exceeds p. while tmpa + tmpb + tmpc < p: tmpa = a * i tmpb = b * i tmpc = c * i -# Increase counter if the new a, b and c give a perimeter=p. + # Increase counter if the new a, b and c give a perimeter=p. if tmpa + tmpb + tmpc == p and savedc[tmpc] == 0: savedc[tmpc] = 1 count = count + 1 @@ -60,19 +57,15 @@ def main(): m = m + 1 -# If the current value is greater than the maximum, -# save the new maximum and the value of p. + # If the current value is greater than the maximum, + # save the new maximum and the value of p. if count > max_: max_ = count res = p - end = default_timer() - print('Project Euler, Problem 39') print(f'Answer: {res}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p039() diff --git a/Python/p040.py b/Python/p040.py index 215be92..59b9a88 100644 --- a/Python/p040.py +++ b/Python/p040.py @@ -10,21 +10,20 @@ # # d_1 × d_10 × d_100 × d_1000 × d_10000 × d_100000 × d_1000000 -from timeit import default_timer - from numpy import zeros +from projecteuler import timing -def main(): - start = default_timer() +@timing +def p040(): digits = zeros(1000005, int) i = 1 value = 1 -# Loop on all numbers and put the digits in the right place -# in an array. Use modulo and division to get the digits -# for numbers with more than one digit. + # Loop on all numbers and put the digits in the right place + # in an array. Use modulo and division to get the digits + # for numbers with more than one digit. while i <= 1000000: if value < 10: digits[i-1] = value @@ -61,16 +60,12 @@ def main(): i = i + 6 value = value + 1 -# Calculate the product. + # Calculate the product. n = digits[0] * digits[9] * digits[99] * digits[999] * digits[9999] * digits[99999] * digits[999999] - end = default_timer() - print('Project Euler, Problem 40') print(f'Answer: {n}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p040()