Use timing decorator for problems 61-70

This commit is contained in:
daniele 2023-06-07 20:27:05 +02:00
parent 5b99c1ef1c
commit f54083389b
Signed by: fuxino
GPG Key ID: 981A2B2A3BBF5514
10 changed files with 112 additions and 180 deletions

View File

@ -19,10 +19,10 @@
# Find the sum of the only ordered set of six cyclic 4-digit numbers for which each polygonal type: triangle, square, pentagonal,
# hexagonal, heptagonal, and octagonal, is represented by a different number in the set.
from timeit import default_timer
from numpy import zeros
from projecteuler import timing
polygonal = zeros((6, 10000), int)
chain = [0] * 6
@ -30,10 +30,8 @@ flags = [0] * 6
sum_ = 0
# Recursive function to find the required set. It finds a polygonal number,
# check if it can be part of the chain, then use recursion to find the next
# number. If a solution can't be found with the current numbers, it uses
# backtracking and tries the next polygonal number.
# Recursive function to find the required set. It finds a polygonal number, check if it can be part of the chain, then use recursion to find the next
# number. If a solution can't be found with the current numbers, it uses backtracking and tries the next polygonal number.
def find_set(step):
global sum_
@ -44,8 +42,7 @@ def find_set(step):
# Set a flag to record that the current polygonal type has been used.
flags[i] = 1
# Start from 1010 because numbers finishing with 00, 01, ..., 09 can't
# be part of the chain.
# Start from 1010 because numbers finishing with 00, 01, ..., 09 can't be part of the chain.
for j in range(1010, 10000):
# If the number doesn't finish with 00, 01, ..., 09 and is poligonal,
# try adding it to the chain and add its value to the total sum.
@ -55,22 +52,18 @@ def find_set(step):
chain[step] = j
sum_ += j
# Recursively try to add other numbers to the chain. If a solution
# is found, return 1.
# Recursively try to add other numbers to the chain. If a solution is found, return 1.
if find_set(step+1):
return 1
# If a solution was not found, backtrack, subtracting the value of
# the number from the total.
# If a solution was not found, backtrack, subtracting the value of the number from the total.
sum_ -= j
# If this is the last step and the current number can be added to the chain,
# add it, update the sum and return 1. A solution has been found.
# If this is the last step and the current number can be added to the chain, add it, update the sum and return 1. A solution has been found.
elif step == 5 and j % 100 == chain[0] // 100 and j // 100 == chain[step-1] % 100:
chain[step] = j
sum_ += j
return 1
# For every other step, add the number to the chain if possible, then recursively
# try to add other numbers.
# For every other step, add the number to the chain if possible, then recursively try to add other numbers.
elif step < 5 and j // 100 == chain[step-1] % 100:
chain[step] = j
sum_ += + j
@ -87,9 +80,8 @@ def find_set(step):
return 0
def main():
start = default_timer()
@timing
def p061():
i = 1
n = 1
@ -152,6 +144,7 @@ def main():
i = 1
n = 1
# Generate all octagonal numbers smaller than 10000
while True:
polygonal[5, n] = 1
@ -165,13 +158,9 @@ def main():
if find_set(0) == 0:
print('Set not found')
end = default_timer()
print('Project Euler, Problem 61')
print(f'Answer: {sum_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p061()

View File

@ -5,14 +5,13 @@
#
# Find the smallest cube for which exactly five permutations of its digits are cube.
from timeit import default_timer
from numpy import zeros
from projecteuler import timing
def main():
start = default_timer()
@timing
def p062():
N = 10000
cubes = zeros(N, int)
@ -43,13 +42,9 @@ def main():
if count == 5:
break
end = default_timer()
print('Project Euler, Problem 62')
print(f'Answer: {cubes[i]}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p062()

View File

@ -4,12 +4,11 @@
#
# How many n-digit positive integers exist which are also an nth power?
from timeit import default_timer
from projecteuler import timing
def main():
start = default_timer()
@timing
def p063():
i = 1
count = 0
finished = 0
@ -28,13 +27,9 @@ def main():
i = i + 1
end = default_timer()
print('Project Euler, Problem 63')
print(f'Answer: {count}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p063()

View File

@ -43,9 +43,8 @@
# How many continued fractions for N≤10000 have an odd period?
from math import sqrt
from timeit import default_timer
from projecteuler import build_sqrt_cont_fraction
from projecteuler import build_sqrt_cont_fraction, timing
def is_square(n):
@ -55,9 +54,8 @@ def is_square(n):
return bool(p == m)
def main():
start = default_timer()
@timing
def p064():
count = 0
for i in range(2, 10000):
@ -65,18 +63,14 @@ def main():
# For all other numbers, calculate their period and check if it's odd.
if not is_square(i):
# period_cf(i) % 2 != 0:
fraction, period = build_sqrt_cont_fraction(i, 300)
_, period = build_sqrt_cont_fraction(i, 300)
if period % 2 != 0:
count = count + 1
end = default_timer()
print('Project Euler, Problem 64')
print(f'Answer: {count}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p064()

View File

@ -29,12 +29,11 @@
#
# Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.
from timeit import default_timer
from projecteuler import timing
def main():
start = default_timer()
@timing
def p065():
ai = [1, 2, 1]
count = 4
@ -68,13 +67,9 @@ def main():
sum_ = sum_ + n2 % 10
n2 = n2 // 10
end = default_timer()
print('Project Euler, Problem 65')
print(f'Answer: {sum_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p065()

View File

@ -21,9 +21,8 @@
# Find the value of D ≤ 1000 in minimal solutions of x for which the largest value of x is obtained.
from math import sqrt
from timeit import default_timer
from projecteuler import pell_eq
from projecteuler import pell_eq, timing
def is_square(n):
@ -33,9 +32,8 @@ def is_square(n):
return bool(p == m)
def main():
start = default_timer()
@timing
def p066():
max_ = 0
max_d = -1
@ -48,13 +46,9 @@ def main():
max_ = x
max_d = i
end = default_timer()
print('Project Euler, Problem 66')
print(f'Answer: {max_d}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p066()

View File

@ -16,14 +16,12 @@
# There is an efficient algorithm to solve it. ;o)
import sys
from timeit import default_timer
from projecteuler import find_max_path
from projecteuler import find_max_path, timing
def main():
start = default_timer()
@timing
def p067():
triang = []
try:
@ -42,13 +40,9 @@ def main():
# Use the function implemented in projecteuler.c to find the maximum path.
max_ = find_max_path(triang, 100)
end = default_timer()
print('Project Euler, Problem 67')
print(f'Answer: {max_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p067()

View File

@ -46,7 +46,8 @@
#
from itertools import permutations
from timeit import default_timer
from projecteuler import timing
# Function to evaluate the ring. The ring is represented as a vector of 2*n elements,
@ -69,14 +70,12 @@ def eval_ring(ring, n):
j = 0
for i in range(n):
# We need to find the maximum 16-digit string, this is
# possible only if the element "10" is used only once,
# We need to find the maximum 16-digit string, this is possible only if the element "10" is used only once,
# i.e. if it's one of the external nodes.
if ring[n+i] == 10 or ring[n+(i+1) % n] == 10:
return None
# Check that the value of the current three-element group
# is the "magic" value.
# Check that the value of the current three-element group is the "magic" value.
val = ring[i] + ring[n+i] + ring[n+(i+1) % n]
if val != magic_val:
@ -110,11 +109,9 @@ def list_to_int(l):
return res
def main():
start = default_timer()
# Generate all possible permutations, for each one check if
# it's a possible solution for the ring and save the maximum
@timing
def p068():
# Generate all possible permutations, for each one check if it's a possible solution for the ring and save the maximum
rings = list(permutations(list(range(1, 11))))
max_ = 0
n = None
@ -128,13 +125,9 @@ def main():
if n > max_:
max_ = n
end = default_timer()
print('Project Euler, Problem 68')
print(f'Answer: {max_}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p068()

View File

@ -18,14 +18,11 @@
#
# Find the value of n ≤ 1,000,000 for which n/φ(n) is a maximum.
from timeit import default_timer
from projecteuler import is_prime
from projecteuler import is_prime, timing
def main():
start = default_timer()
@timing
def p069():
N = 1000000
i = 1
@ -46,13 +43,9 @@ def main():
# We need the previous value, because we want i<1000000
res = res // i
end = default_timer()
print('Project Euler, Problem 69')
print(f'Answer: {res}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p069()

View File

@ -9,14 +9,11 @@
#
# Find the value of n, 1 < n < 10^7, for which φ(n) is a permutation of n and the ratio n/φ(n) produces a minimum.
from timeit import default_timer
from projecteuler import sieve, is_semiprime, phi_semiprime
from projecteuler import sieve, is_semiprime, phi_semiprime, timing
def main():
start = default_timer()
@timing
def p070():
N = 10000000
n = -1
min_ = float('inf')
@ -25,12 +22,9 @@ def main():
primes = sieve(N)
for i in range(2, N):
# When n is prime, phi(n)=(n-1), so to minimize n/phi(n) we should
# use n prime. But n-1 can't be a permutation of n. The second best
# bet is to use semiprimes. For a semiprime n=p*q, phi(n)=(p-1)(q-1).
# So we check if a number is semiprime, if yes calculate phi, finally
# check if phi(n) is a permutation of n and update the minimum if it's
# smaller.
# When n is prime, phi(n)=(n-1), so to minimize n/phi(n) we should use n prime. But n-1 can't be a permutation of n. The second best
# bet is to use semiprimes. For a semiprime n=p*q, phi(n)=(p-1)(q-1). So we check if a number is semiprime, if yes calculate phi, finally
# check if phi(n) is a permutation of n and update the minimum if it's smaller.
semi_p, a, b = is_semiprime(i, primes)
if semi_p is True:
@ -40,13 +34,9 @@ def main():
n = i
min_ = i / p
end = default_timer()
print('Project Euler, Problem 70')
print(f'Answer: {n}')
print(f'Elapsed time: {end - start:.9f} seconds')
if __name__ == '__main__':
main()
p070()