Add more solutions
Added solutions for problems 61, 62, 63, 65 and 65 in C and python.
This commit is contained in:
180
Python/p061.py
Normal file
180
Python/p061.py
Normal file
@ -0,0 +1,180 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated
|
||||
# by the following formulae:
|
||||
#
|
||||
# Triangle P3,n=n(n+1)/2 1, 3, 6, 10, 15, ...
|
||||
# Square P4,n=n2 1, 4, 9, 16, 25, ...
|
||||
# Pentagonal P5,n=n(3n−1)/2 1, 5, 12, 22, 35, ...
|
||||
# Hexagonal P6,n=n(2n−1) 1, 6, 15, 28, 45, ...
|
||||
# Heptagonal P7,n=n(5n−3)/2 1, 7, 18, 34, 55, ...
|
||||
# Octagonal P8,n=n(3n−2) 1, 8, 21, 40, 65, ...
|
||||
#
|
||||
# The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three interesting properties.
|
||||
#
|
||||
# The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).
|
||||
# Each polygonal type: triangle (P3,127=8128), square (P4,91=8281), and pentagonal (P5,44=2882), is represented by a different number in the set.
|
||||
# This is the only set of 4-digit numbers with this property.
|
||||
#
|
||||
# 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 numpy import zeros
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
# 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 polygonal
|
||||
global chain
|
||||
global flags
|
||||
global sum_
|
||||
|
||||
# Use one polygonal number per type, starting from triangular.
|
||||
for i in range(6):
|
||||
# If the current type has not been used yet, try it.
|
||||
if flags[i] == 0:
|
||||
# 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.
|
||||
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.
|
||||
if j % 100 > 9 and polygonal[i, j] == 1:
|
||||
# If it's the first number, just add it as first step in the chain.
|
||||
if step == 0:
|
||||
chain[step] = j
|
||||
sum_ = sum_ + j
|
||||
|
||||
# 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.
|
||||
sum_ = 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.
|
||||
elif step == 5 and j % 100 == chain[0] // 100 and j // 100 == chain[step-1] % 100:
|
||||
chain[step] = j
|
||||
sum_ = sum_ + j
|
||||
return 1
|
||||
# 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_ = sum_ + j
|
||||
|
||||
if find_set(step+1):
|
||||
return 1
|
||||
|
||||
# If a solution was not found, backtrack.
|
||||
sum_ = sum_ - j
|
||||
|
||||
# Remove the flag for the current polygonal type.
|
||||
flags[i] = 0
|
||||
|
||||
return 0
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
global polygonal
|
||||
global chain
|
||||
global flags
|
||||
global sum_
|
||||
|
||||
polygonal = zeros((6, 10000), int)
|
||||
chain = [0] * 6
|
||||
flags = [0] * 6
|
||||
sum_ = 0
|
||||
i = 1
|
||||
n = 1
|
||||
|
||||
# Generate all triangle numbers smaller than 10000
|
||||
while True:
|
||||
polygonal[0, n] = 1
|
||||
i = i + 1
|
||||
n = i * (i + 1) // 2
|
||||
|
||||
if n >= 10000:
|
||||
break
|
||||
|
||||
i = 1
|
||||
n = 1
|
||||
|
||||
# Generate all square numbers smaller than 10000
|
||||
while True:
|
||||
polygonal[1, n] = 1
|
||||
i = i + 1
|
||||
n = i * i
|
||||
|
||||
if n >= 10000:
|
||||
break
|
||||
|
||||
i = 1
|
||||
n = 1
|
||||
|
||||
# Generate all pentagonal numbers smaller than 10000
|
||||
while True:
|
||||
polygonal[2, n] = 1
|
||||
i = i + 1
|
||||
n = i * (3 * i - 1) // 2
|
||||
|
||||
if n >= 10000:
|
||||
break
|
||||
|
||||
i = 1
|
||||
n = 1
|
||||
|
||||
# Generate all hexagonal numbers smaller than 10000
|
||||
while True:
|
||||
polygonal[3, n] = 1
|
||||
i = i + 1
|
||||
n = i * (2 * i - 1)
|
||||
|
||||
if n >= 10000:
|
||||
break
|
||||
|
||||
i = 1
|
||||
n = 1
|
||||
|
||||
# Generate all heptagonal numbers smaller than 10000
|
||||
while True:
|
||||
polygonal[4, n] = 1
|
||||
i = i + 1
|
||||
n = i * (5 * i - 3) // 2
|
||||
|
||||
if n >= 10000:
|
||||
break
|
||||
|
||||
i = 1
|
||||
n = 1
|
||||
# Generate all octagonal numbers smaller than 10000
|
||||
while True:
|
||||
polygonal[5, n] = 1
|
||||
i = i + 1
|
||||
n = i * (3 * i - 2)
|
||||
|
||||
if n >= 10000:
|
||||
break
|
||||
|
||||
# Find the requested set of numbers
|
||||
if find_set(0) == 0:
|
||||
print('Set not found')
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 61')
|
||||
print('Answer: {}'.format(sum_))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
53
Python/p062.py
Normal file
53
Python/p062.py
Normal file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# The cube, 41063625 (345^3), can be permuted to produce two other cubes: 56623104 (384^3) and 66430125 (405^3).
|
||||
# In fact, 41063625 is the smallest cube which has exactly three permutations of its digits which are also cube.
|
||||
#
|
||||
# Find the smallest cube for which exactly five permutations of its digits are cube.
|
||||
|
||||
from numpy import zeros
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
N = 10000
|
||||
|
||||
cubes = zeros(N, int)
|
||||
|
||||
# Calculate i^3 for all i smaller than 10000
|
||||
for i in range(N):
|
||||
cubes[i] = i * i * i
|
||||
|
||||
# For each cube, check if there are four other cubes which are also
|
||||
# a permutation of the first cube.
|
||||
for i in range(N-5):
|
||||
count = 1
|
||||
|
||||
# Stop when the limit has been reached, when 5 values have been found or
|
||||
# when j^3 has more digits than i^3 (if they don't have the same digits,
|
||||
# they can't be permutations).
|
||||
j = i + 1
|
||||
|
||||
while j < N and len(str(cubes[j])) == len(str(cubes[i])):
|
||||
if ''.join(sorted(str(cubes[i]))) == ''.join(sorted(str(cubes[j]))):
|
||||
count = count + 1
|
||||
|
||||
if count == 5:
|
||||
break
|
||||
|
||||
j = j + 1
|
||||
|
||||
if count == 5:
|
||||
break
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 62')
|
||||
print('Answer: {}'.format(cubes[i]))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
38
Python/p063.py
Normal file
38
Python/p063.py
Normal file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# The 5-digit number, 16807=7^5, is also a fifth power. Similarly, the 9-digit number, 134217728=8^9, is a ninth power.
|
||||
#
|
||||
# How many n-digit positive integers exist which are also an nth power?
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
i = 1
|
||||
count = 0
|
||||
finished = 0
|
||||
|
||||
while not finished:
|
||||
# When j=10, j^i will have i+1 digits (e.g. if i=3, 10^3=1000).
|
||||
for j in range(1, 10):
|
||||
p = j ** i
|
||||
|
||||
if len(str(p)) == i:
|
||||
count = count + 1
|
||||
|
||||
# When 9^i has less than i digits, all the numbers have been found.
|
||||
if len(str(p)) < i:
|
||||
finished = 1
|
||||
|
||||
i = i + 1
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 63')
|
||||
print('Answer: {}'.format(count))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
78
Python/p064.py
Normal file
78
Python/p064.py
Normal file
@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# All square roots are periodic when written as continued fractions and can be written in the form:
|
||||
#
|
||||
# √N=a0+1/(a1+1/(a2+1/(a3+…
|
||||
#
|
||||
# For example, let us consider √23:
|
||||
#
|
||||
# √23=4+√23−4=4+1/(1/(√23−4))=4+1/(1+(√23−3)/7)
|
||||
#
|
||||
# If we continue we would get the following expansion:
|
||||
#
|
||||
# √23=4+1/(1+1/(3+1/(1+1/(8+…
|
||||
#
|
||||
# The process can be summarised as follows:
|
||||
# a0=4,1/(√23−4)=(√23+4)/7=1+(√23−3)/7
|
||||
# a1=1,7/(√23−3)=7(√23+3)/14=3+(√23−3)/2
|
||||
# a2=3,2/(√23−3)=2(√23+3)/14=1+(√23−4)/7
|
||||
# a3=1,7/(√23−4)=7(√23+4)/7=8+√23−4
|
||||
# a4=8,1/(√23−4)=(√23+4)/7=1+(√23−3)/7
|
||||
# a5=1,7/(√23−3)=7(√23+3)/14=3+(√23−3)/2
|
||||
# a6=3,2/(√23−3)=2(√23+3)/14=1+(√23−4)/7
|
||||
# a7=1,7/(√23−4)=7(√23+4)/7=8+√23−4
|
||||
#
|
||||
# It can be seen that the sequence is repeating. For conciseness, we use the notation √23=[4;(1,3,1,8)], to indicate that the block (1,3,1,8)
|
||||
# repeats indefinitely.
|
||||
#
|
||||
# The first ten continued fraction representations of (irrational) square roots are:
|
||||
#
|
||||
# √2=[1;(2)], period=1
|
||||
# √3=[1;(1,2)], period=2
|
||||
# √5=[2;(4)], period=1
|
||||
# √6=[2;(2,4)], period=2
|
||||
# √7=[2;(1,1,1,4)], period=4
|
||||
# √8=[2;(1,4)], period=2
|
||||
# √10=[3;(6)], period=1
|
||||
# √11=[3;(3,6)], period=2
|
||||
# √12=[3;(2,6)], period=2
|
||||
# √13=[3;(1,1,1,1,6)], period=5
|
||||
#
|
||||
# Exactly four continued fractions, for N≤13, have an odd period.
|
||||
#
|
||||
# How many continued fractions for N≤10000 have an odd period?
|
||||
|
||||
from math import floor, sqrt
|
||||
|
||||
from timeit import default_timer
|
||||
from projecteuler import period_cf
|
||||
|
||||
def is_square(n):
|
||||
p = sqrt(n)
|
||||
m = int(p)
|
||||
|
||||
if p == m:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
count = 0
|
||||
|
||||
for i in range(2, 10000):
|
||||
# Perfect squares are obviously not represented as continued fractions.
|
||||
# For all other numbers, calculate their period and check if it's odd.
|
||||
if not is_square(i) and period_cf(i) % 2 != 0:
|
||||
count = count + 1
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 64')
|
||||
print('Answer: {}'.format(count))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
78
Python/p065.py
Normal file
78
Python/p065.py
Normal file
@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# The square root of 2 can be written as an infinite continued fraction.
|
||||
#
|
||||
# √2=1+1/(2+1/(2+1/(2+1/(2+...
|
||||
#
|
||||
# The infinite continued fraction can be written, √2=[1;(2)], (2) indicates that 2 repeats ad infinitum. In a similar way, √23=[4;(1,3,1,8)].
|
||||
# It turns out that the sequence of partial values of continued fractions for square roots provide the best rational approximations.
|
||||
# Let us consider the convergents for √22.
|
||||
#
|
||||
# 1+1/2=3/2
|
||||
# 1+1/(2+1/2)=7/5
|
||||
# 1+1/(2+1/(2+1/2))=17/12
|
||||
# 1+1/(2+1/(2+1/(2+1/2)))=41/29
|
||||
#
|
||||
# Hence the sequence of the first ten convergents for √2 are:
|
||||
#
|
||||
# 1,3/2,7/5,17/12,41/29,99/70,239/169,577/408,1393/985,3363/2378,...
|
||||
#
|
||||
# What is most surprising is that the important mathematical constant,
|
||||
#
|
||||
# e=[2;1,2,1,1,4,1,1,6,1,...,1,2k,1,...].
|
||||
#
|
||||
# The first ten terms in the sequence of convergents for e are:
|
||||
#
|
||||
# 2,3,8/3,11/4,19/7,87/32,106/39,193/71,1264/465,1457/536,...
|
||||
#
|
||||
# The sum of digits in the numerator of the 10th convergent is 1+4+5+7=17.
|
||||
#
|
||||
# Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
ai = [1, 2, 1]
|
||||
count = 4
|
||||
|
||||
n0 = 3
|
||||
n1 = 8
|
||||
n2 = 11
|
||||
|
||||
# For a continued fractions [a_0; a_1, a_2, ...], the numerator of the
|
||||
# next convergent N_n=a_n*N_(n-1)+N_(n-2). The first three values for e are
|
||||
# 3, 8 and 11, the next ones are easily calculated, considering that a_n
|
||||
# follows a simple pattern:
|
||||
# a_1=1, a_2=2, a_3=1
|
||||
# a_4=1, a_5=4, a_6=1
|
||||
# a_7=1, a_8=6, a_9=1
|
||||
# and so on.
|
||||
while count < 100:
|
||||
ai[1] = ai[1] + 2
|
||||
|
||||
for i in range(3):
|
||||
n0 = n1
|
||||
n1 = n2
|
||||
n2 = n1 * ai[i] + n0
|
||||
count = count + 1
|
||||
|
||||
if count >= 100:
|
||||
break
|
||||
|
||||
sum_ = 0
|
||||
|
||||
while n2 != 0:
|
||||
sum_ = sum_ + n2 % 10
|
||||
n2 = n2 // 10
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 65')
|
||||
print('Answer: {}'.format(sum_))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -179,3 +179,35 @@ def is_pentagonal(n):
|
||||
|
||||
return i.is_integer()
|
||||
|
||||
# Function implementing the iterative algorithm taken from Wikipedia
|
||||
# to find the continued fraction for sqrt(S). The algorithm is as
|
||||
# follows:
|
||||
#
|
||||
# m_0=0
|
||||
# d_0=1
|
||||
# a_0=floor(sqrt(n))
|
||||
# m_(n+1)=d_n*a_n-m_n
|
||||
# d_(n+1)=(S-m_(n+1)^2)/d_n
|
||||
# a_(n+1)=floor((sqrt(S)+m_(n+1))/d_(n+1))=floor((a_0+m_(n+1))/d_(n+1))
|
||||
# if a_i=2*a_0, the algorithm ends.
|
||||
def period_cf(n):
|
||||
mn = 0
|
||||
dn = 1
|
||||
count = 0
|
||||
|
||||
a0 = floor(sqrt(n))
|
||||
an = a0
|
||||
|
||||
while True:
|
||||
mn1 = dn * an - mn
|
||||
dn1 = (n - mn1 * mn1) // dn
|
||||
an1 = floor((a0+mn1)/dn1)
|
||||
mn = mn1
|
||||
dn = dn1
|
||||
an = an1
|
||||
count = count + 1
|
||||
|
||||
if an == 2 * a0:
|
||||
break
|
||||
|
||||
return count
|
||||
|
Reference in New Issue
Block a user