Add more solutions and minor corrections
Added solutions for problem 71, 72, 73, 74 and 75 in C and python and made a few corrections in the code for other problems.
This commit is contained in:
@ -10,8 +10,9 @@
|
||||
#
|
||||
# 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 gcd
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
54
Python/p071.py
Normal file
54
Python/p071.py
Normal file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.
|
||||
#
|
||||
# If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:
|
||||
#
|
||||
# 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
|
||||
#
|
||||
# It can be seen that 2/5 is the fraction immediately to the left of 3/7.
|
||||
#
|
||||
# By listing the set of reduced proper fractions for d ≤ 1,000,000 in ascending order of size, find the numerator
|
||||
# of the fraction immediately to the left of 3/7.
|
||||
|
||||
from math import gcd
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
N = 1000000
|
||||
|
||||
max_ = 0
|
||||
|
||||
# For each denominator q, we need to find the biggest numerator p for which
|
||||
# p/q<a/b, where a/b is 3/7 for this problem. So:
|
||||
# pb<aq
|
||||
# pb<=aq-1
|
||||
# p<=(aq-1)/b
|
||||
# So we can set p=(3*q-1)/7 (using integer division).
|
||||
for i in range(2, N+1):
|
||||
j = (3 * i - 1) // 7
|
||||
|
||||
if j / i > max_:
|
||||
n = j
|
||||
d = i
|
||||
max_ = n / d
|
||||
|
||||
# Reduce the fractions if it's not already reduced.
|
||||
if gcd(i, j) > 1:
|
||||
n /= gcd(i, j)
|
||||
d /= gcd(i, j)
|
||||
|
||||
max_n = n
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 71')
|
||||
print('Answer: {}'.format(max_n))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
39
Python/p072.py
Normal file
39
Python/p072.py
Normal file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.
|
||||
#
|
||||
# If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:
|
||||
#
|
||||
# 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
|
||||
#
|
||||
# It can be seen that there are 21 elements in this set.
|
||||
#
|
||||
# How many elements would be contained in the set of reduced proper fractions for d ≤ 1,000,000?
|
||||
|
||||
from timeit import default_timer
|
||||
from projecteuler import sieve, phi
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
N = 1000001
|
||||
|
||||
count = 0
|
||||
primes = sieve(N)
|
||||
|
||||
# For any denominator d, the number of reduced proper fractions is
|
||||
# the number of fractions n/d where gcd(n, d)=1, which is the definition
|
||||
# of Euler's Totient Function phi. It's sufficient to calculate phi for each
|
||||
# denominator and sum the value.
|
||||
for i in range(2, N):
|
||||
count = count + phi(i, primes)
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 72')
|
||||
print('Answer: {}'.format(count))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
41
Python/p073.py
Normal file
41
Python/p073.py
Normal file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.
|
||||
#
|
||||
# If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:
|
||||
#
|
||||
# 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
|
||||
#
|
||||
# It can be seen that there are 3 fractions between 1/3 and 1/2.
|
||||
#
|
||||
# How many fractions lie between 1/3 and 1/2 in the sorted set of reduced proper fractions for d ≤ 12,000?
|
||||
|
||||
from math import gcd
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
count = 0
|
||||
|
||||
# For each denominator q, we need to find the fractions p/q for which
|
||||
# 1/3<p/q<1/2. For the lower limit, if p=q/3, then p/q=1/3, so we take
|
||||
# p=q/3+1. For the upper limit, if p=q/2 p/q=1/2, so we take p=(q-1)/2.
|
||||
for i in range(2, 12001):
|
||||
limit = (i - 1) // 2 + 1
|
||||
|
||||
for j in range(i//3+1, limit):
|
||||
# Increment the counter if the current fraction is reduced.*/
|
||||
if gcd(j, i) == 1:
|
||||
count = count + 1
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 73')
|
||||
print('Answer: {}'.format(count))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
97
Python/p074.py
Normal file
97
Python/p074.py
Normal file
@ -0,0 +1,97 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145:
|
||||
#
|
||||
# 1! + 4! + 5! = 1 + 24 + 120 = 145
|
||||
#
|
||||
# Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are
|
||||
# only three such loops that exist:
|
||||
#
|
||||
# 169 → 363601 → 1454 → 169
|
||||
# 871 → 45361 → 871
|
||||
# 872 → 45362 → 872
|
||||
#
|
||||
# It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example,
|
||||
#
|
||||
# 69 → 363600 → 1454 → 169 → 363601 (→ 1454)
|
||||
# 78 → 45360 → 871 → 45361 (→ 871)
|
||||
# 540 → 145 (→ 145)
|
||||
#
|
||||
# Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number
|
||||
# below one million is sixty terms.
|
||||
#
|
||||
# How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?
|
||||
|
||||
from math import factorial
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def len_chain(n):
|
||||
global N
|
||||
global chains
|
||||
|
||||
chain = [0] * 60
|
||||
count = 0
|
||||
finished = 0
|
||||
|
||||
value = n
|
||||
chain[count] = value
|
||||
|
||||
while not finished:
|
||||
tmp = 0
|
||||
count = count + 1
|
||||
|
||||
# Generate the next number of the chain by taking
|
||||
# the digits of the current value, calculating the
|
||||
# factorials and adding them.*/
|
||||
while value != 0:
|
||||
tmp = tmp + factorial(value % 10)
|
||||
value = value // 10
|
||||
|
||||
# If the chain length for the new value has already been
|
||||
# calculated before, use the saved value (only chains for
|
||||
# values smaller than N are saved).*/
|
||||
if tmp < N and chains[tmp] != 0:
|
||||
return count + chains[tmp]
|
||||
|
||||
value = tmp
|
||||
|
||||
# If the current value is already present in the chain,
|
||||
# the chain is finished.*/
|
||||
for i in range(count):
|
||||
if chain[i] == value:
|
||||
finished = 1
|
||||
|
||||
chain[count] = value
|
||||
|
||||
chains[n] = count
|
||||
|
||||
return count
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
global N
|
||||
global chains
|
||||
|
||||
N = 1000000
|
||||
|
||||
chains = [0] * N
|
||||
|
||||
count = 0
|
||||
|
||||
# Simple brute force approach, for every number calculate
|
||||
# the length of the chain.
|
||||
for i in range(3, N):
|
||||
if len_chain(i) == 60:
|
||||
count = count + 1
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 74')
|
||||
print('Answer: {}'.format(count))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
80
Python/p075.py
Normal file
80
Python/p075.py
Normal file
@ -0,0 +1,80 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# It turns out that 12 cm is the smallest length of wire that can be bent to form an integer sided right angle triangle in exactly one way,
|
||||
# but there are many more examples.
|
||||
#
|
||||
# 12 cm: (3,4,5)
|
||||
# 24 cm: (6,8,10)
|
||||
# 30 cm: (5,12,13)
|
||||
# 36 cm: (9,12,15)
|
||||
# 40 cm: (8,15,17)
|
||||
# 48 cm: (12,16,20)
|
||||
#
|
||||
# In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right angle triangle, and other lengths allow
|
||||
# more than one solution to be found; for example, using 120 cm it is possible to form exactly three different integer sided right angle triangles.
|
||||
#
|
||||
# 120 cm: (30,40,50), (20,48,52), (24,45,51)
|
||||
#
|
||||
# Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can exactly one integer sided right angle triangle be formed?
|
||||
|
||||
from math import gcd
|
||||
|
||||
from timeit import default_timer
|
||||
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
N = 1500000
|
||||
|
||||
l = [0] * (N+1)
|
||||
|
||||
# Generate all Pythagorean triplets using Euclid's algorithm:
|
||||
# For m>=2 and n<m:
|
||||
# a=m*m-n*n
|
||||
# b=2*m*n
|
||||
# c=m*m+n*n
|
||||
# This gives a primitive triple if gcd(m, n)=1 and exactly one
|
||||
# of m and n is odd. To generate all the triples, generate all
|
||||
# the primitive one and multiply them by i=2,3, ..., n until the
|
||||
# perimeter is larger than the limit. The limit for m is 865, because
|
||||
# when m=866 even with the smaller n (i.e. 1) the perimeter is greater
|
||||
# than the given limit.
|
||||
for m in range(2, 866):
|
||||
for n in range(1, m):
|
||||
if gcd(m, n) == 1 and ((m % 2 == 0 and n % 2 != 0) or (m % 2 != 0 and n % 2 == 0)):
|
||||
a = m * m - n * n
|
||||
b = 2 * m * n
|
||||
c = m * m + n * n
|
||||
|
||||
if(a + b + c <= N):
|
||||
l[a+b+c] = l[a+b+c] + 1
|
||||
|
||||
i = 2
|
||||
tmpa = i * a
|
||||
tmpb = i * b
|
||||
tmpc = i * c
|
||||
|
||||
while(tmpa + tmpb + tmpc <= N):
|
||||
l[tmpa+tmpb+tmpc] = l[tmpa+tmpb+tmpc] + 1
|
||||
|
||||
i = i + 1
|
||||
tmpa = i * a
|
||||
tmpb = i * b
|
||||
tmpc = i * c
|
||||
|
||||
count = 0
|
||||
|
||||
for i in range(N+1):
|
||||
if l[i] == 1:
|
||||
count = count + 1
|
||||
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 75')
|
||||
print('Answer: {}'.format(count))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -324,3 +324,76 @@ def phi_semiprime(n, p, q):
|
||||
return n - p
|
||||
else:
|
||||
return n - (p + q) + 1
|
||||
|
||||
def phi(n, primes):
|
||||
# If n is primes, phi(n)=n-1.
|
||||
if primes[n] == 1:
|
||||
return n - 1
|
||||
|
||||
# If n is semiprime, use above function.
|
||||
semi_p, p, q = is_semiprime(n, primes)
|
||||
|
||||
if semi_p:
|
||||
return phi_semiprime(n, p, q)
|
||||
|
||||
ph = n
|
||||
|
||||
# If 2 is a factor of n, multiply the current ph (which now is n)
|
||||
# by 1-1/2, then divide all factors 2.
|
||||
if n % 2 == 0:
|
||||
ph = ph * (1 - 1 / 2)
|
||||
|
||||
while True:
|
||||
n = n // 2
|
||||
|
||||
if n % 2 != 0:
|
||||
break
|
||||
|
||||
# If 3 is a factor of n, multiply the current ph by 1-1/3,
|
||||
# then divide all factors 3.
|
||||
if n % 3 == 0:
|
||||
ph = ph * (1 - 1 / 3)
|
||||
|
||||
while True:
|
||||
n = n // 3
|
||||
|
||||
if n % 3 != 0:
|
||||
break
|
||||
|
||||
# Any number can have only one prime factor greater than its
|
||||
# square root, so we can stop checking at this point and deal
|
||||
# with the only factor larger than sqrt(n), if present, at the end
|
||||
limit = floor(sqrt(n)) + 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. For each of these possible primes, check if
|
||||
# they are prime, then check if the number divides n, in which
|
||||
# case update the current ph.
|
||||
for i in range(5, limit, 6):
|
||||
if primes[i]:
|
||||
if n % i == 0:
|
||||
ph = ph * (1 - 1 / i)
|
||||
|
||||
while True:
|
||||
n = n // i
|
||||
|
||||
if n % i != 0:
|
||||
break
|
||||
if primes[i+2]:
|
||||
if n % (i + 2) == 0:
|
||||
ph = ph * (1 - 1 / (i + 2))
|
||||
|
||||
while True:
|
||||
n = n // (i + 2)
|
||||
|
||||
if n % (i + 2) != 0:
|
||||
break
|
||||
|
||||
# After dividing all prime factors smaller than sqrt(n), n is either 1
|
||||
# or is equal to the only prime factor greater than sqrt(n). In this
|
||||
# second case, we need to update ph with the last prime factor.
|
||||
if n > 1:
|
||||
ph = ph * (1 - 1 / n)
|
||||
|
||||
return ph
|
||||
|
Reference in New Issue
Block a user