Skip to content

Instantly share code, notes, and snippets.

@Siss3l
Last active August 18, 2023 21:39
Show Gist options
  • Save Siss3l/84b4dd68a5a7e3746acaa5242877aa50 to your computer and use it in GitHub Desktop.
Save Siss3l/84b4dd68a5a7e3746acaa5242877aa50 to your computer and use it in GitHub Desktop.
Returns the last nonzero digits of a factorial
"""
This code provides functions to find the last nonzero values of a positive factorial.
"""
def f(n: int, k: int) -> int:
"""
Returns the k last nonzero digits.
.. note::
As f(10**100, 13) is a Googolbang where the 13 last nonzero
digits are 5473738735616 with 25*(10**98)-18 trailing zeros.
:long_url: https://www.wolframalpha.com/input?i=googol!
"""
m, l = 10 ** k, [1, 1]
for i in range(2, m):
if i % 2 == 0 or i % 5 == 0: i = 1
l.append((l[-1] * i) % m)
def nf(j: int) -> int:
a, b = divmod(j, m)
return (pow(l[m - 1], a, m) * l[b]) % m
ans, p = 1, 1
while p <= n:
q = p
while q <= n:
ans = (ans * nf(n // q)) % m; q *= 5
p *= 2
def legendre(n: int, p: int) -> int:
"""
Should be moderate if there are zeros inside the last nonzero digits calculation of Legendre's formula.
"""
ans = 0
while n:
n //= p; ans += n
return ans
ans *= pow(2, legendre(n, 2) - legendre(n, 5), m)
return ans % m
if __name__ == "__main__":
try:
print(f(int(abs(float(__import__("sys").argv[1]))), int(abs(float(__import__("sys").argv[2])))))
except (IndexError, MemoryError, TypeError, ValueError) as e:
print(e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment