From f885638c74fe6eb3c4f02da2c98feaf4909687db Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Sat, 29 Aug 2026 14:08:22 -0400 Subject: [PATCH] Solve problem 587 --- python/e587.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 python/e587.py diff --git a/python/e587.py b/python/e587.py new file mode 100644 index 0000000..fa686a0 --- /dev/null +++ b/python/e587.py @@ -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