1616
1717def factoradic_to_int (num : str ) -> int :
1818 """Convert a factoradic to an int."""
19+ if num .startswith ("-" ):
20+ return - factoradic_to_int (num [1 :])
1921 return (
2022 Stream (reversed (num ))
2123 .enumerate (1 )
@@ -28,22 +30,31 @@ def int_to_factoradic(num: int) -> str:
2830 """Convert an int to a factoradic."""
2931 if num < 0 :
3032 return f"-{ int_to_factoradic (abs (num ))} "
31- if num < 2 :
32- return str (num )
3333
34- start = Stream .counting (1 ).take_while (lambda n : factorial (n ) <= num ).last ()
35-
36- digits = (
37- num // f + (num := num % f ) // f
38- for f in Stream .range (start , stop = 0 , step = - 1 ).map (factorial )
34+ start = (
35+ Stream .counting (1 )
36+ .take_while (lambda n : factorial (n ) <= num )
37+ .nth (- 1 , default = 1 )
3938 )
4039
41- return Stream (digits ).map (DIGITS .__getitem__ ).collect ("" .join )
40+ def _divide_num (divisor : int ) -> int :
41+ nonlocal num
42+ result , num = divmod (num , divisor )
43+ return result
44+
45+ return (
46+ Stream .range (start , 0 , - 1 )
47+ .map (factorial )
48+ .map (_divide_num )
49+ .map (DIGITS .__getitem__ )
50+ .collect ("" .join )
51+ )
4252
4353
4454def test () -> int | str :
4555 """Test this."""
46- test_cases : tuple [tuple [int , str ], ...] = (
56+ test_cases : list [tuple [int , str ]] = [
57+ (0 , "0" ),
4758 (1 , "1" ),
4859 (2 , "10" ),
4960 (7 , "101" ),
@@ -55,8 +66,11 @@ def test() -> int | str:
5566 (5039 , "654321" ),
5667 (5040 , "1000000" ),
5768 (1_000_001 , "266251221" ),
58- (36287999 , "9987654321" ),
59- )
69+ (3_628_799 , "987654321" ),
70+ (36_287_999 , "9987654321" ),
71+ ]
72+
73+ test_cases .extend ([(- i , f"-{ f } " ) for i , f in test_cases if i ])
6074
6175 for i , f in test_cases :
6276 if (_ := factoradic_to_int (f )) != i :
0 commit comments