Solve 684. Little proud of the math I did to figure this one out.
This commit is contained in:
54
python/e684.py
Normal file
54
python/e684.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
def r_modulo_closed_form(n, m):
|
||||||
|
# From e132.py
|
||||||
|
assert n > 0 and m > 0
|
||||||
|
return ((pow(10, n, 9 * m) - 1) // 9) % m
|
||||||
|
|
||||||
|
|
||||||
|
def s(n, mod):
|
||||||
|
a = n % 9
|
||||||
|
b = n // 9
|
||||||
|
r = (a + 1) * pow(10, b, mod) - 1
|
||||||
|
return r % mod
|
||||||
|
|
||||||
|
|
||||||
|
def s_big(n, mod):
|
||||||
|
# s = (n % 9 + 1) * 10^(n/9) - 1
|
||||||
|
# S = sum(k=0, n/9) (1 * 10^k + 2 * 10^k + ... + 9 * 10^k) - n
|
||||||
|
# = 45 * sum(k=0, n/9) 10^k - n
|
||||||
|
# = 45 * r(n/9) - n
|
||||||
|
# Plus some extra math to make n % 9 == 8 so that the above works.
|
||||||
|
|
||||||
|
r = -1
|
||||||
|
while n % 9 != 8:
|
||||||
|
n += 1
|
||||||
|
r -= s(n, mod)
|
||||||
|
|
||||||
|
r += (r_modulo_closed_form(n // 9 + 1, mod) * 45) % mod
|
||||||
|
r -= n
|
||||||
|
return r % mod
|
||||||
|
|
||||||
|
|
||||||
|
def s_big_naiv(n, mod):
|
||||||
|
r = 0
|
||||||
|
for i in range(1, n + 1):
|
||||||
|
r += s(i, mod)
|
||||||
|
if mod is not None:
|
||||||
|
r %= mod
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def euler_684():
|
||||||
|
assert s_big_naiv(20, 11) == s_big(20, 11)
|
||||||
|
r = 0
|
||||||
|
mod = 1_000_000_007
|
||||||
|
a, b = 0, 1
|
||||||
|
for _ in range(2, 91):
|
||||||
|
a, b = b, a + b
|
||||||
|
r += s_big(b, mod)
|
||||||
|
return r % mod
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
solution = euler_684()
|
||||||
|
print("e684.py: " + str(solution))
|
||||||
|
assert(solution == 922058210)
|
||||||
Reference in New Issue
Block a user