from math import gcd from functools import lru_cache @lru_cache def r(n): assert n > 0 if n == 1: return 1 else: return 10**(n - 1) + r(n - 1) def r_closed_form(n): assert n > 0 return (10**n - 1) // 9 def r_modulo_closed_form(n, m): assert n > 0 and m > 0 return ((pow(10, n, 9 * m) - 1) // 9) % m def a(n): assert gcd(n, 10) == 1 k = 1 while True: if r_modulo_closed_form(k, n) == 0: return k k += 1 def euler_129(): # Comparing naiv to efficient implementations to find potential bugs. for n in range(5, 1000): assert r(n) == r_closed_form(n) for m in range(2, 20): assert (r_closed_form(n) % m) == r_modulo_closed_form(n, m) assert a(7) == 6 assert a(41) == 5 assert a(17) == 16 target = 10**6 delta = 200 for n in range(target, target + delta): if gcd(n, 10) == 1: if (av := a(n)): if av > target: return n return None if __name__ == "__main__": solution = euler_129() print("e129.py: " + str(solution)) assert(solution == 1000023)