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) +