Skip to content

Commit e51546f

Browse files
fpringlegithub-actions
authored andcommitted
Add solution for Project Euler problem 86 (TheAlgorithms#4025)
* Added solution for Project Euler problem 86 * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
1 parent 997fa96 commit e51546f

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@
729729
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_081/sol1.py)
730730
* Problem 085
731731
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_085/sol1.py)
732+
* Problem 086
733+
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_086/sol1.py)
732734
* Problem 087
733735
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_087/sol1.py)
734736
* Problem 089

project_euler/problem_086/__init__.py

Whitespace-only changes.

project_euler/problem_086/sol1.py

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""
2+
Project Euler Problem 86: https://projecteuler.net/problem=86
3+
4+
A spider, S, sits in one corner of a cuboid room, measuring 6 by 5 by 3, and a fly, F,
5+
sits in the opposite corner. By travelling on the surfaces of the room the shortest
6+
"straight line" distance from S to F is 10 and the path is shown on the diagram.
7+
8+
However, there are up to three "shortest" path candidates for any given cuboid and the
9+
shortest route doesn't always have integer length.
10+
11+
It can be shown that there are exactly 2060 distinct cuboids, ignoring rotations, with
12+
integer dimensions, up to a maximum size of M by M by M, for which the shortest route
13+
has integer length when M = 100. This is the least value of M for which the number of
14+
solutions first exceeds two thousand; the number of solutions when M = 99 is 1975.
15+
16+
Find the least value of M such that the number of solutions first exceeds one million.
17+
18+
Solution:
19+
Label the 3 side-lengths of the cuboid a,b,c such that 1 <= a <= b <= c <= M.
20+
By conceptually "opening up" the cuboid and laying out its faces on a plane,
21+
it can be seen that the shortest distance between 2 opposite corners is
22+
sqrt((a+b)^2 + c^2). This distance is an integer if and only if (a+b),c make up
23+
the first 2 sides of a pythagorean triplet.
24+
25+
The second useful insight is rather than calculate the number of cuboids
26+
with integral shortest distance for each maximum cuboid side-length M,
27+
we can calculate this number iteratively each time we increase M, as follows.
28+
The set of cuboids satisfying this property with maximum side-length M-1 is a
29+
subset of the cuboids satisfying the property with maximum side-length M
30+
(since any cuboids with side lengths <= M-1 are also <= M). To calculate the
31+
number of cuboids in the larger set (corresponding to M) we need only consider
32+
the cuboids which have at least one side of length M. Since we have ordered the
33+
side lengths a <= b <= c, we can assume that c = M. Then we just need to count
34+
the number of pairs a,b satisfying the conditions:
35+
sqrt((a+b)^2 + M^2) is integer
36+
1 <= a <= b <= M
37+
38+
To count the number of pairs (a,b) satisfying these conditions, write d = a+b.
39+
Now we have:
40+
1 <= a <= b <= M => 2 <= d <= 2*M
41+
we can actually make the second equality strict,
42+
since d = 2*M => d^2 + M^2 = 5M^2
43+
=> shortest distance = M * sqrt(5)
44+
=> not integral.
45+
a + b = d => b = d - a
46+
and a <= b
47+
=> a <= d/2
48+
also a <= M
49+
=> a <= min(M, d//2)
50+
51+
a + b = d => a = d - b
52+
and b <= M
53+
=> a >= d - M
54+
also a >= 1
55+
=> a >= max(1, d - M)
56+
57+
So a is in range(max(1, d - M), min(M, d // 2) + 1)
58+
59+
For a given d, the number of cuboids satisfying the required property with c = M
60+
and a + b = d is the length of this range, which is
61+
min(M, d // 2) + 1 - max(1, d - M).
62+
63+
In the code below, d is sum_shortest_sides
64+
and M is max_cuboid_size.
65+
66+
67+
"""
68+
69+
70+
from math import sqrt
71+
72+
73+
def solution(limit: int = 1000000) -> int:
74+
"""
75+
Return the least value of M such that there are more than one million cuboids
76+
of side lengths 1 <= a,b,c <= M such that the shortest distance between two
77+
opposite vertices of the cuboid is integral.
78+
>>> solution(100)
79+
24
80+
>>> solution(1000)
81+
72
82+
>>> solution(2000)
83+
100
84+
>>> solution(20000)
85+
288
86+
"""
87+
num_cuboids: int = 0
88+
max_cuboid_size: int = 0
89+
sum_shortest_sides: int
90+
91+
while num_cuboids <= limit:
92+
max_cuboid_size += 1
93+
for sum_shortest_sides in range(2, 2 * max_cuboid_size + 1):
94+
if sqrt(sum_shortest_sides ** 2 + max_cuboid_size ** 2).is_integer():
95+
num_cuboids += (
96+
min(max_cuboid_size, sum_shortest_sides // 2)
97+
- max(1, sum_shortest_sides - max_cuboid_size)
98+
+ 1
99+
)
100+
101+
return max_cuboid_size
102+
103+
104+
if __name__ == "__main__":
105+
print(f"{solution() = }")

0 commit comments

Comments
 (0)