Skip to content

Instantly share code, notes, and snippets.

@Rudxain
Created May 30, 2023 21:05
Show Gist options
  • Save Rudxain/69b90a50d2b87c99b7d0f78512ea8ec3 to your computer and use it in GitHub Desktop.
Save Rudxain/69b90a50d2b87c99b7d0f78512ea8ec3 to your computer and use it in GitHub Desktop.
Discrete inverse factorial, with "floor" and "round" rounding-modes
def factorial(n: int):
if n < 0:
raise ValueError('undefined')
out = 1
while n >= 1:
out *= n
n -= 1
return out
def inv_factorial(n: int, round: bool):
'''
if `round` is `False`, floors instead
'''
if n <= 0:
raise ValueError('undefined')
# solutions of x! = x: 1, 2.
# solutions of x! = 1: 0, 1.
if n <= 2:
return n
i = 2
while True:
n //= i
if n <= (1 if round else i):
return i
i += 1
def tests():
for i, v in enumerate((1, 1, 2, 6, 24, 120)):
assert factorial(i) == v
for i in range(1, 1 << 8, 1):
assert inv_factorial(factorial(i), False) == i
assert inv_factorial(factorial(i), True) == i
tests()
# LICENSE: https://unlicense.org
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment