Solve problem 587

This commit is contained in:
2026-08-29 14:08:22 -04:00
parent db2ac78ab8
commit f885638c74
+61
View File
@@ -0,0 +1,61 @@
from math import sqrt, pi, atan
def get_intersection(n: int) -> tuple[int, int]:
"""Compute the point where the line intersects the circle for a given
number of circles `n`.
Equation for circle: y = 1 - sqrt(2*x - x**2)
Equation for line: y = (1/n) * x
"""
# Computed via Wolfram alpha; could be derived by setting the curves equal,
# isolating the root, and then applying the quadratic formula.
x_int = (-sqrt(2) * n ** (3 / 2) + n**2 + n) / (n**2 + 1)
y_int = x_int / n
return (x_int, y_int)
def get_ratio_orange(n: int) -> float:
"""Compute the ratio between the orange and the blue section. The blue
section is the L-section meaning the area outside of the quarter circle.
The orange area is the concave triangle created by the diagonal line."""
x, y = get_intersection(n)
area_blue = 1 - (pi / 4)
theta = atan((1 - x) / (1 - y)) # angle of concave triangle circle part
area_sector = theta / 2 # area of sector of concave triangle circle part
# area_orange = area triangle + area_rectangle + area_triangle - area_sector
area_orange = (0.5 * x * y) + ((1 - x) * y) + (0.5 * (1 - x) * (1 - y))
area_orange -= area_sector
return area_orange / area_blue
def get_less_than(percentage: float) -> int:
ratio = percentage / 100
n_min, n_max = 1, 10000
while n_max - n_min > 1:
n_mid = (n_max + n_min) // 2
ratio_n = get_ratio_orange(n_mid)
if ratio_n < ratio:
n_max = n_mid
else:
n_min = n_mid
return n_max
def euler_587():
assert get_ratio_orange(1) == 0.5
assert abs(get_ratio_orange(2) - 0.3646) <= 0.0001
assert get_less_than(10) == 15
return get_less_than(0.1)
if __name__ == "__main__":
solution = euler_587()
print(f"e587.py: {solution}")
assert solution == 2240