1717ODD_DIGITS = [1 , 3 , 5 , 7 , 9 ]
1818
1919
20- def reversible_numbers (
20+ def slow_reversible_numbers (
2121 remaining_length : int , remainder : int , digits : list [int ], length : int
2222) -> int :
2323 """
2424 Count the number of reversible numbers of given length.
2525 Iterate over possible digits considering parity of current sum remainder.
26- >>> reversible_numbers (1, 0, [0], 1)
26+ >>> slow_reversible_numbers (1, 0, [0], 1)
2727 0
28- >>> reversible_numbers (2, 0, [0] * 2, 2)
28+ >>> slow_reversible_numbers (2, 0, [0] * 2, 2)
2929 20
30- >>> reversible_numbers (3, 0, [0] * 3, 3)
30+ >>> slow_reversible_numbers (3, 0, [0] * 3, 3)
3131 100
3232 """
3333 if remaining_length == 0 :
@@ -51,7 +51,7 @@ def reversible_numbers(
5151 result = 0
5252 for digit in range (10 ):
5353 digits [length // 2 ] = digit
54- result += reversible_numbers (
54+ result += slow_reversible_numbers (
5555 0 , (remainder + 2 * digit ) // 10 , digits , length
5656 )
5757 return result
@@ -67,7 +67,7 @@ def reversible_numbers(
6767
6868 for digit2 in other_parity_digits :
6969 digits [(length - remaining_length ) // 2 ] = digit2
70- result += reversible_numbers (
70+ result += slow_reversible_numbers (
7171 remaining_length - 2 ,
7272 (remainder + digit1 + digit2 ) // 10 ,
7373 digits ,
@@ -76,6 +76,42 @@ def reversible_numbers(
7676 return result
7777
7878
79+ def slow_solution (max_power : int = 9 ) -> int :
80+ """
81+ To evaluate the solution, use solution()
82+ >>> slow_solution(3)
83+ 120
84+ >>> slow_solution(6)
85+ 18720
86+ >>> slow_solution(7)
87+ 68720
88+ """
89+ result = 0
90+ for length in range (1 , max_power + 1 ):
91+ result += slow_reversible_numbers (length , 0 , [0 ] * length , length )
92+ return result
93+
94+
95+ def reversible_numbers (
96+ remaining_length : int , remainder : int , digits : list [int ], length : int
97+ ) -> int :
98+ """
99+ Count the number of reversible numbers of given length.
100+ Iterate over possible digits considering parity of current sum remainder.
101+ >>> reversible_numbers(1, 0, [0], 1)
102+ 0
103+ >>> reversible_numbers(2, 0, [0] * 2, 2)
104+ 20
105+ >>> reversible_numbers(3, 0, [0] * 3, 3)
106+ 100
107+ """
108+ # There exist no reversible 1, 5, 9, 13 (ie. 4k+1) digit numbers
109+ if (length - 1 ) % 4 == 0 :
110+ return 0
111+
112+ return slow_reversible_numbers (length , 0 , [0 ] * length , length )
113+
114+
79115def solution (max_power : int = 9 ) -> int :
80116 """
81117 To evaluate the solution, use solution()
@@ -92,5 +128,25 @@ def solution(max_power: int = 9) -> int:
92128 return result
93129
94130
131+ def benchmark () -> None :
132+ """
133+ Benchmarks
134+ """
135+ # Running performance benchmarks...
136+ # slow_solution : 292.9300301000003
137+ # solution : 54.90970860000016
138+
139+ from timeit import timeit
140+
141+ print ("Running performance benchmarks..." )
142+
143+ print (f"slow_solution : { timeit ('slow_solution()' , globals = globals (), number = 10 )} " )
144+ print (f"solution : { timeit ('solution()' , globals = globals (), number = 10 )} " )
145+
146+
95147if __name__ == "__main__" :
96- print (f"{ solution () = } " )
148+ print (f"Solution : { solution ()} " )
149+ benchmark ()
150+
151+ # for i in range(1, 15):
152+ # print(f"{i}. {reversible_numbers(i, 0, [0]*i, i)}")
0 commit comments