From 1248a1b915a52e5ed99e60464c15c85cee01f5fe Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Mon, 26 Apr 2021 12:22:15 -0400 Subject: [PATCH] Solve problem 100 - this also my 100th problem in total --- python/e100.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 python/e100.py diff --git a/python/e100.py b/python/e100.py new file mode 100644 index 0000000..199e0b0 --- /dev/null +++ b/python/e100.py @@ -0,0 +1,47 @@ +from fractions import Fraction + + +def euler_100(): + F_ONE_HALF = Fraction(1, 2) + prev_blue_discs, blue_discs = 10, 10 + while True: + # Brute force search blue discs + blue_discs += 1 + + # Binary search red discs + red_upper = blue_discs // 2 + red_lower = 1 + while red_upper != red_lower: + red_discs = red_lower + (red_upper - red_lower) // 2 + total_discs = blue_discs + red_discs + f1 = Fraction(blue_discs, total_discs) + f2 = Fraction(blue_discs - 1, total_discs - 1) + f = f1 * f2 + if f == F_ONE_HALF: + # End criterion by Euler Problem + if total_discs > 10**12: + return blue_discs + + # The ration between two solutions seems to be constant so we + # can get the next larger candidate for blue_discs much + # quicker. + ratio = blue_discs / prev_blue_discs + # print("blue_discs={} ratio={}".format(blue_discs, ratio)) + prev_blue_discs = blue_discs + blue_discs = int(blue_discs * ratio) + break + elif f < F_ONE_HALF: + red_upper = red_discs + else: + red_lower = red_discs + + # No solution for current number of blue discs + if abs(red_upper - red_lower) <= 1: + break + + +if __name__ == "__main__": + solution = euler_100() + print("e100.py: " + str(solution)) + assert(solution == 756872327473) +