diff --git a/Python/p085.py b/Python/p085.py new file mode 100644 index 0000000..818102e --- /dev/null +++ b/Python/p085.py @@ -0,0 +1,33 @@ +# By counting carefully it can be seen that a rectangular grid measuring 3 by 2 contains eighteen rectangles. +# Although there exists no rectangular grid that contains exactly two million rectangles, find the area of the grid with the nearest solution. + +import sys + +from projecteuler import timing + + +@timing +def p085(): + N = 2000000 + min_diff = sys.maxsize + + for i in range(1, 100): + for j in range(1, i + 1): + # In a 2x3 grid, we can take rectangles of height 2 in 3 ways (two rectangles of heigh + # one and one of height 2). For the width, we can take 6 rectangles (3 of width 1, + # 2 of width 2 and 1 of width 3). The total is 6x3=18 rectangles. + # Extending to m x n, we can take (m+m-1+m-2+...+1)x(n+n-1+n-2+...+1)= + # m(m + 1) / 2 * n(n + 1) / 2 = m(m + 1) * n(n + 1) / 4 rectangles + n = (i * (i + 1) * j * (j + 1)) / 4 + diff = abs(N - n) + + if diff < min_diff: + min_diff = diff + area = i * j + + print('Project Euler, Problem 85') + print(f'Answer: {area}') + + +if __name__ == '__main__': + p085() diff --git a/Python/p086.py b/Python/p086.py new file mode 100644 index 0000000..1f42757 --- /dev/null +++ b/Python/p086.py @@ -0,0 +1,39 @@ +# A spider, S, sits in one corner of a cuboid room, measuring 6 by 5 by 3, and a fly, F, sits in the opposite corner. +# By travelling on the surfaces of the room the shortest "straight line" distance from S to F is 10 and the path is shown on the diagram. +# +# However, there are up to three "shortest" path candidates for any given cuboid and the shortest route doesn't always have integer length. +# +# It can be shown that there are exactly 2060 distinct cuboids, ignoring rotations, with integer dimensions, +# up to a maximum size of M by M by M, for which the shortest route has integer length when M = 100. +# This is the least value of M for which the number of solutions first exceeds two thousand; the number of solutions when M = 99 is 1975. +# +# Find the least value of M such that the number of solutions first exceeds one million. + +from math import sqrt + +from projecteuler import timing + + +@timing +def p086(): + N = 1000000 + + a = 0 + count = 0 + + while count <= N: + a += 1 + + for b in range(1, a + 1): + for c in range(1, b + 1): + d = sqrt(a * a + (b + c) ** 2) + + if d == int(d): + count += 1 + + print('Project Euler, Problem 86') + print(f'Answer: {a}') + + +if __name__ == '__main__': + p086() diff --git a/Python/p087.py b/Python/p087.py new file mode 100644 index 0000000..909f608 --- /dev/null +++ b/Python/p087.py @@ -0,0 +1,44 @@ +# The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is 28. In fact, +# there are exactly four numbers below fifty that can be expressed in such a way: +# +# 28 = 22 + 23 + 24 +# 33 = 32 + 23 + 24 +# 49 = 52 + 23 + 24 +# 47 = 22 + 33 + 24 +# +# How many numbers below fifty million can be expressed as the sum of a prime square, prime cube, and prime fourth power? + +from numpy import zeros + +from projecteuler import sieve, timing + + +@timing +def p087(): + N = 50000000 + SQRT_N = 7071 + RAD3_N = 368 + RAD4_N = 84 + + primes = sieve(SQRT_N + 1) + numbers = zeros(N) + count = 0 + + for i in range(2, SQRT_N + 1): + if primes[i]: + for j in range(2, RAD3_N + 1): + if primes[j]: + for k in range(2, RAD4_N + 1): + if primes[k]: + n = i ** 2 + j ** 3 + k ** 4 + + if n < N and numbers[n] == 0: + count += 1 + numbers[n] = 1 + + print('Project Euler, Problem 87') + print(f'Answer: {count}') + + +if __name__ == '__main__': + p087() diff --git a/Python/p092.py b/Python/p092.py new file mode 100644 index 0000000..a4ae457 --- /dev/null +++ b/Python/p092.py @@ -0,0 +1,57 @@ +# A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before. +# +# For example, +# +# 44 → 32 → 13 → 10 → 1 → 1 +# 85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89 +# +# Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop. What is most amazing is that +# EVERY starting number will eventually arrive at 1 or 89. +# +# How many starting numbers below ten million will arrive at 89? + +from numpy import zeros + +from projecteuler import timing + + +N = 10000000 +chains = zeros(N) + + +def chain(n): + tmp = 0 + + if n == 1: + return 1 + + if n == 89: + return 89 + + if chains[n] != 0: + return chains[n] + + while n > 0: + digit = n % 10 + tmp += digit ** 2 + n //= 10 + + return chain(tmp) + + +@timing +def p092(): + count = 0 + + for i in range(1, N): + chains[i] = chain(i) + + if chains[i] == 89: + count += 1 + + print('Project Euler, Problem 92') + print(f'Answer: {count}') + + +if __name__ == '__main__': + p092() diff --git a/Python/p095.py b/Python/p095.py new file mode 100644 index 0000000..0dd1de4 --- /dev/null +++ b/Python/p095.py @@ -0,0 +1,75 @@ +# The proper divisors of a number are all the divisors excluding the number itself. For example, the proper divisors +# of 28 are 1, 2, 4, 7, and 14. As the sum of these divisors is equal to 28, we call it a perfect number. +# +# Interestingly the sum of the proper divisors of 220 is 284 and the sum of the proper divisors of 284 is 220, +# forming a chain of two numbers. For this reason, 220 and 284 are called an amicable pair. +# +# Perhaps less well known are longer chains. For example, starting with 12496, we form a chain of five numbers: +# +# 12496 → 14288 → 15472 → 14536 → 14264 (→ 12496 → ...) +# +# Since this chain returns to its starting point, it is called an amicable chain. +# +# Find the smallest member of the longest amicable chain with no element exceeding one million. + +from numpy import zeros + +from projecteuler import sum_of_divisors, timing + + +N = 1000000 +divisors = zeros(N + 1) + + +def sociable_chain(i, chain, l, min_): + chain[l] = i + + if i == 1: + return -1 + + if divisors[i] != 0: + n = int(divisors[i]) + else: + n = int(sum_of_divisors(i)) + + if n > N: + return -1 + + if n == chain[0]: + return l + 1 + + for j in range(l, 0, -1): + if n == chain[j]: + return -1 + + if n < min_: + min_ = n + + return sociable_chain(n, chain, l + 1, min_) + + +@timing +def p095(): + chain = zeros(N) + min_ = 0 + l_max = 0 + + for i in range(4, N + 1): + divisors[i] = sum_of_divisors(i) + + if divisors[i] == i: + continue + + min_tmp = i + length = sociable_chain(i, chain, 0, min_tmp) + + if length > l_max: + l_max = length + min_ = min_tmp + + print('Project Euler, Problem 95') + print(f'Answer: {min_}') + + +if __name__ == '__main__': + p095() diff --git a/Python/projecteuler.py b/Python/projecteuler.py index e58bfe4..adda8d9 100644 --- a/Python/projecteuler.py +++ b/Python/projecteuler.py @@ -146,7 +146,8 @@ def sum_of_divisors(n): for i in range(2, limit): if n % i == 0: - sum_ = sum_ + i + sum_ += i + # If n is a perfect square, i=limit is a divisor and has to be counted only once. if n != i * i: sum_ = sum_ + n // i diff --git a/README.md b/README.md index bda198c..f326f7f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,6 @@ These are my solutions in C and Python, not necessarily the best solutions. I've solved most of the first 100 problems, currently working on cleaning the code and uploading it. I will try to solve more problems in the future. # Notes -- Solutions for problems 82 and 145 in Python are really slow. -- Solutions for problems 84, 85, 86, 87, 89, 92, 95, 96, 97. 99, 102, 112, 124 and 357 have been implemented in C but not in Python. +- Solutions for problems 82, 86, 95, and 145 in Python are quite slow. +- Solutions for problems 84, 89, 96, 97. 99, 102, 112, 124 and 357 have been implemented in C but not in Python. - Solutions for problems 88, 90 and 91 have been implemented in Python but not in C.