import matplotlib.pyplot as plt INPUT = 33100000 def get_divisors(num): divisors = set() divisors.add(1) divisors.add(num) upper_limit = num lower_limit = 2 while lower_limit < upper_limit: quotient, rest = divmod(num, lower_limit) if rest == 0: divisors.add(lower_limit) divisors.add(quotient) lower_limit += 1 return divisors def present_count(house_number): divisors = get_divisors(house_number) presents = 0 for divisor in divisors: presents += divisor * 10 return presents X = [] Y = [] for x in range(1, 100): if x % 100 == 0: print(x) y = present_count(x) plt.plot(x, y, "bo") plt.annotate(f"{x}", (x, y), xytext=(2, 0), textcoords="offset points") plt.show() print("Estimation...") prev_house_number = None house_number = 1 presents = 10 while True: prev_house_number = house_number house_number = house_number * 2 presents += house_number * 10 print(house_number, presents) if presents > INPUT: break lower_bound = prev_house_number upper_bound = house_number print("Estimation lower bound:", lower_bound) print("Estimation upper bound:", upper_bound) print() current = int(lower_bound + (upper_bound - lower_bound) / 2) loop_count = 0 while True: presents = present_count(current) print("loop", current, lower_bound, upper_bound, presents) if presents < INPUT: lower_bound = current else: upper_bound = current current = int(lower_bound + (upper_bound - lower_bound) / 2) print("finished") # 2097152 too high # 1540098 too high