From 2802f8e9575bdc895b6ba81a11b60e62b5c3db32 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Sun, 11 Aug 2019 21:42:31 -0400 Subject: [PATCH] Improve 66 in Python based on the idea that we can search the Stern-Brocot tree for a solution. --- python/e066.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/python/e066.py b/python/e066.py index a691171..27357db 100644 --- a/python/e066.py +++ b/python/e066.py @@ -62,7 +62,7 @@ def get_fractions(n, x): return (n, d) -def get_minimal_solution(d): +def get_minimal_solution_old(d): for i in range(0, 100): x, y = get_fractions(d, i) if x * x - d * y * y == 1: @@ -73,8 +73,32 @@ def is_square(n): return math.sqrt(n).is_integer() +def get_minimal_solution(d, d1=0, n1=1, d2=1, n2=1): + """ + This is an alternative to the alternate fraction approach explained here + [1]. Instead of calculating the continued fraction we search the + Stern-Brocot tree for fractions (x / y) that satisfy the pell equation. + + If the solution does not satisfy the equation we can searh the respective + branch by calculating the mediant between the current fraction and one of + the previous fractions. + + [1] https://en.wikipedia.org/wiki/Pell's_equation#Fundamental_solution_via_continued_fractions + [2] https://en.wikipedia.org/wiki/Stern–Brocot_tree + """ + + x = n1 + n2 + y = d1 + d2 + p = x * x - d * y * y + if p == 1: + return (x, y) + if p < 1: + return get_minimal_solution(d, d1, n1, y, x) + else: + return get_minimal_solution(d, y, x, d2, n2) + + def euler_066(): - # XXX: This seems really long and complicated. We can do better. x_max = 0 d_max = 0 @@ -84,8 +108,7 @@ def euler_066(): x, y = get_minimal_solution(d) if x > x_max: - x_max = x - d_max = d + x_max, d_max = x, d print("d: {} x: {}".format(d_max, x_max)) s = d_max