From 8fdec345d9e449e84ad5fbf693be43e1a010eba6 Mon Sep 17 00:00:00 2001 From: felixm Date: Mon, 13 May 2024 21:43:19 -0400 Subject: [PATCH] Solve 684. Little proud of the math I did to figure this one out. --- python/e684.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 python/e684.py diff --git a/python/e684.py b/python/e684.py new file mode 100644 index 0000000..7c63b75 --- /dev/null +++ b/python/e684.py @@ -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)