Skip to content

Commit 2d75c9c

Browse files
afk-Parthpre-commit-ci[bot]cclauss
authored
Create reverse_factorial_recursive.py (#13426)
* Create reverse_factorial_recursive.py Added reverse factorial recursive algorithm with doctests * Update reverse_factorial_recursive.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update reverse_factorial_recursive.py * updating DIRECTORY.md * Refactor docstring and include doctest Updated docstring formatting and added doctest. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: cclauss <cclauss@users.noreply.github.com>
1 parent 2922216 commit 2d75c9c

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@
862862
* [Radix2 Fft](maths/radix2_fft.py)
863863
* [Recursive Digit Sum](maths/recursive_digit_sum.py)
864864
* [Remove Digit](maths/remove_digit.py)
865+
* [Reverse Factorial Recursive](maths/reverse_factorial_recursive.py)
865866
* [Segmented Sieve](maths/segmented_sieve.py)
866867
* Series
867868
* [Arithmetic](maths/series/arithmetic.py)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
def reverse_factorial_recursive(value: int, current_divisor: int = 1) -> int:
2+
"""
3+
Return x such that x! == value, otherwise return -1.
4+
5+
The function divides `value` by 1, 2, 3, ... recursively. If the repeated
6+
division reduces `value` exactly to 1, the factorial root x is
7+
(current_divisor - 1). If the division ever has a remainder, no integer x
8+
exists and the function returns -1.
9+
10+
Parameters
11+
----------
12+
value: The positive integer to test (candidate factorial value).
13+
current_divisor: The current divisor used while reducing `value` (default is 1).
14+
15+
Returns
16+
-------
17+
The factorial root (x) if x! == value, otherwise -1.
18+
19+
Examples
20+
--------
21+
>>> reverse_factorial_recursive(120)
22+
5
23+
>>> reverse_factorial_recursive(24)
24+
4
25+
>>> reverse_factorial_recursive(150)
26+
-1
27+
>>> reverse_factorial_recursive(1)
28+
1
29+
>>> reverse_factorial_recursive(2)
30+
2
31+
"""
32+
if not isinstance(value, int):
33+
raise TypeError("value must be an integer")
34+
if not isinstance(current_divisor, int):
35+
raise TypeError("current_divisor must be an integer")
36+
37+
if value < 1:
38+
raise ValueError("value must be a positive integer")
39+
40+
# Special-case: initial call with value == 1 should return 1 (since 1! = 1).
41+
if value == 1 and current_divisor == 1:
42+
return 1
43+
44+
# If value reduced to 1 during recursion, the factorial root is divisor - 1.
45+
if value == 1:
46+
return current_divisor - 1
47+
48+
# If not divisible by the current divisor, it's not a factorial number.
49+
if value % current_divisor != 0:
50+
return -1
51+
52+
return reverse_factorial_recursive(value // current_divisor, current_divisor + 1)
53+
54+
55+
if __name__ == "__main__":
56+
from doctest import testmod
57+
58+
testmod()

0 commit comments

Comments
 (0)