59 lines
1.1 KiB
Python
59 lines
1.1 KiB
Python
|
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)
|