44
55import functools
66import math
7- from typing import Dict
87
98
109def recursive_lucas_number (n_th_number : int ) -> int :
@@ -25,16 +24,16 @@ def recursive_lucas_number(n_th_number: int) -> int:
2524 """
2625 if not isinstance (n_th_number , int ):
2726 raise TypeError ("recursive_lucas_number accepts only integer arguments." )
28-
27+
2928 # Use memoization to cache results and avoid redundant calculations
30- @functools .lru_cache ( maxsize = None )
29+ @functools .cache
3130 def _recursive_lucas (n : int ) -> int :
3231 if n == 0 :
3332 return 2
3433 if n == 1 :
3534 return 1
3635 return _recursive_lucas (n - 1 ) + _recursive_lucas (n - 2 )
37-
36+
3837 return _recursive_lucas (n_th_number )
3938
4039
@@ -56,16 +55,16 @@ def dynamic_lucas_number(n_th_number: int) -> int:
5655 """
5756 if not isinstance (n_th_number , int ):
5857 raise TypeError ("dynamic_lucas_number accepts only integer arguments." )
59-
58+
6059 if n_th_number == 0 :
6160 return 2
6261 if n_th_number == 1 :
6362 return 1
64-
63+
6564 a , b = 2 , 1
6665 for _ in range (2 , n_th_number + 1 ):
6766 a , b = b , a + b
68-
67+
6968 return b
7069
7170
@@ -87,41 +86,35 @@ def matrix_power_lucas_number(n_th_number: int) -> int:
8786 """
8887 if not isinstance (n_th_number , int ):
8988 raise TypeError ("matrix_power_lucas_number accepts only integer arguments." )
90-
89+
9190 if n_th_number == 0 :
9291 return 2
9392 if n_th_number == 1 :
9493 return 1
95-
94+
9695 def matrix_mult (a : list [list [int ]], b : list [list [int ]]) -> list [list [int ]]:
9796 return [
98- [
99- a [0 ][0 ] * b [0 ][0 ] + a [0 ][1 ] * b [1 ][0 ],
100- a [0 ][0 ] * b [0 ][1 ] + a [0 ][1 ] * b [1 ][1 ],
101- ],
102- [
103- a [1 ][0 ] * b [0 ][0 ] + a [1 ][1 ] * b [1 ][0 ],
104- a [1 ][0 ] * b [0 ][1 ] + a [1 ][1 ] * b [1 ][1 ],
105- ],
97+ [a [0 ][0 ] * b [0 ][0 ] + a [0 ][1 ] * b [1 ][0 ], a [0 ][0 ] * b [0 ][1 ] + a [0 ][1 ] * b [1 ][1 ]],
98+ [a [1 ][0 ] * b [0 ][0 ] + a [1 ][1 ] * b [1 ][0 ], a [1 ][0 ] * b [0 ][1 ] + a [1 ][1 ] * b [1 ][1 ]],
10699 ]
107-
100+
108101 def matrix_power (matrix : list [list [int ]], power : int ) -> list [list [int ]]:
109102 # Start with identity matrix
110103 result : list [list [int ]] = [[1 , 0 ], [0 , 1 ]]
111104 base = matrix
112-
105+
113106 while power > 0 :
114107 if power % 2 == 1 :
115108 result = matrix_mult (result , base )
116109 base = matrix_mult (base , base )
117110 power //= 2
118-
111+
119112 return result
120-
113+
121114 # Lucas number matrix form: [[1, 1], [1, 0]]
122115 base_matrix = [[1 , 1 ], [1 , 0 ]]
123116 powered_matrix = matrix_power (base_matrix , n_th_number - 1 )
124-
117+
125118 # L(n) = powered_matrix[0][0] * L(1) + powered_matrix[0][1] * L(0)
126119 # Where L(1) = 1, L(0) = 2
127120 return powered_matrix [0 ][0 ] * 1 + powered_matrix [0 ][1 ] * 2
@@ -145,23 +138,23 @@ def closed_form_lucas_number(n_th_number: int) -> int:
145138 """
146139 if not isinstance (n_th_number , int ):
147140 raise TypeError ("closed_form_lucas_number accepts only integer arguments." )
148-
141+
149142 if n_th_number == 0 :
150143 return 2
151144 if n_th_number == 1 :
152145 return 1
153-
146+
154147 # Golden ratio
155148 phi = (1 + math .sqrt (5 )) / 2
156149 # Conjugate of golden ratio
157150 psi = (1 - math .sqrt (5 )) / 2
158-
151+
159152 # Lucas number closed form: L(n) = phi^n + psi^n
160153 return round (phi ** n_th_number + psi ** n_th_number )
161154
162155
163156# Global cache for performance optimization
164- _lucas_cache : Dict [int , int ] = {0 : 2 , 1 : 1 }
157+ _lucas_cache : dict [int , int ] = {0 : 2 , 1 : 1 }
165158
166159
167160def cached_lucas_number (n_th_number : int ) -> int :
@@ -182,16 +175,16 @@ def cached_lucas_number(n_th_number: int) -> int:
182175 """
183176 if not isinstance (n_th_number , int ):
184177 raise TypeError ("cached_lucas_number accepts only integer arguments." )
185-
178+
186179 if n_th_number in _lucas_cache :
187180 return _lucas_cache [n_th_number ]
188-
181+
189182 # Calculate using the fastest method for uncached values
190183 if n_th_number < 70 : # For smaller values, closed form is efficient
191184 result = closed_form_lucas_number (n_th_number )
192185 else : # For larger values, matrix exponentiation is more stable
193186 result = matrix_power_lucas_number (n_th_number )
194-
187+
195188 _lucas_cache [n_th_number ] = result
196189 return result
197190
@@ -210,4 +203,4 @@ def cached_lucas_number(n_th_number: int) -> int:
210203 print ("\n Using closed-form formula to calculate lucas series:" )
211204 print (" " .join (str (closed_form_lucas_number (i )) for i in range (n )))
212205 print ("\n Using cached function to calculate lucas series:" )
213- print (" " .join (str (cached_lucas_number (i )) for i in range (n )))
206+ print (" " .join (str (cached_lucas_number (i )) for i in range (n )))
0 commit comments