Solve problem 100 - this also my 100th problem in total
parent
26b11ed519
commit
1248a1b915
|
@ -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)
|
||||
|
Loading…
Reference in New Issue