

"""simple docstring"""




import unittest
from timeit import timeit
def      __SCREAMING_SNAKE_CASE		(		lowercase__    ,							lowercase__   ):
					"""simple docstring"""
					A    =      first_num if first_num >= second_num else second_num
					A    =      max_num
					while (common_mult % first_num > 0) or (common_mult % second_num > 0):
										common_mult += max_num
					return common_mult
def      __SCREAMING_SNAKE_CASE		(		lowercase__    ,							lowercase__   ):
					"""simple docstring"""
					return b if a == 0 else greatest_common_divisor(b % a    ,							lowercase__   )
def      __SCREAMING_SNAKE_CASE		(		lowercase__    ,							lowercase__   ):
					"""simple docstring"""
					return first_num // greatest_common_divisor(lowercase__    ,							lowercase__   ) * second_num
def      __SCREAMING_SNAKE_CASE		(		):
					"""simple docstring"""
					A    =      (
					    "from __main__ import least_common_multiple_slow, least_common_multiple_fast"
					)
					print(
					    "least_common_multiple_slow():"    ,							timeit("least_common_multiple_slow(1000, 999)"    ,							setup=lowercase__   )    ,							)
					print(
					    "least_common_multiple_fast():"    ,							timeit("least_common_multiple_fast(1000, 999)"    ,							setup=lowercase__   )    ,							)





class     __UpperCamelCase				(     unittest.TestCase		):
		SCREAMING_SNAKE_CASE              =					(
		    (10, 20),
		    (13, 15),
		    (4, 31),
		    (10, 42),
		    (43, 34),
		    (5, 12),
		    (12, 25),
		    (10, 25),
		    (6, 9),
		)
		SCREAMING_SNAKE_CASE              =					(20, 195, 124, 210, 1_462, 60, 300, 50, 18)


		def       SCREAMING_SNAKE_CASE__     (self				:	Tuple):
							for i, (first_num, second_num) in enumerate(self.test_inputs):
												A    =      least_common_multiple_slow(__SCREAMING_SNAKE_CASE  ,  __SCREAMING_SNAKE_CASE)
												A    =      least_common_multiple_fast(__SCREAMING_SNAKE_CASE  ,  __SCREAMING_SNAKE_CASE)
												with self.subTest(i=__SCREAMING_SNAKE_CASE):
																	self.assertEqual(__SCREAMING_SNAKE_CASE  ,  self.expected_results[i])
																	self.assertEqual(__SCREAMING_SNAKE_CASE  ,  self.expected_results[i])


if __name__ == "__main__":
	benchmark()
	unittest.main()








"""simple docstring"""




import functools
from math import sqrt
from time import time
def      __SCREAMING_SNAKE_CASE		(		lowercase__    ,							*lowercase__    ,							**lowercase__   ):
					"""simple docstring"""
					A    =      time()
					A    =      func(*lowercase__    ,							**lowercase__   )
					A    =      time()
					if int(end - start   ) > 0:
										print(F"""{func.__name__} runtime: {(end - start):0.4f} s"""   )
					else:
										print(F"""{func.__name__} runtime: {(end - start) * 1_000:0.4f} ms"""   )
					return output
def      __SCREAMING_SNAKE_CASE		(		lowercase__   ):
					"""simple docstring"""
					if n < 0:
										raise Exception("n is negative"   )
					if n == 0:
										return [0]
					A    =      [0, 1]
					for _ in range(n - 1   ):
										fib.append(fib[-1] + fib[-2]   )
					return fib
def      __SCREAMING_SNAKE_CASE		(		lowercase__   ):
					"""simple docstring"""

					def fib_recursive_term(lowercase__   ) -> int:
										if i < 0:
															raise Exception("n is negative"   )
										if i < 2:
															return i
										return fib_recursive_term(i - 1   ) + fib_recursive_term(i - 2   )

					if n < 0:
										raise Exception("n is negative"   )
					return [fib_recursive_term(lowercase__   ) for i in range(n + 1   )]
def      __SCREAMING_SNAKE_CASE		(		lowercase__   ):
					"""simple docstring"""

					@functools.cache
					def fib_recursive_term(lowercase__   ) -> int:
										if i < 0:
															raise Exception("n is negative"   )
										if i < 2:
															return i
										return fib_recursive_term(i - 1   ) + fib_recursive_term(i - 2   )

					if n < 0:
										raise Exception("n is negative"   )
					return [fib_recursive_term(lowercase__   ) for i in range(n + 1   )]
def      __SCREAMING_SNAKE_CASE		(		lowercase__   ):
					"""simple docstring"""
					if n < 0:
										raise Exception("n is negative"   )
					# Cache must be outside recursuive function
					# other it will reset every time it calls itself.
					A    =      {0: 0, 1: 1, 2: 1}  # Prefilled cache

					def rec_fn_memoized(lowercase__   ) -> int:
										if num in cache:
															return cache[num]

										A    =      rec_fn_memoized(num - 1   ) + rec_fn_memoized(num - 2   )
										A    =      value
										return value

					return [rec_fn_memoized(lowercase__   ) for i in range(n + 1   )]
def      __SCREAMING_SNAKE_CASE		(		lowercase__   ):
					"""simple docstring"""
					if n < 0:
										raise Exception("n is negative"   )
					if n >= 1_475:
										raise Exception("n is too large"   )
					A    =      sqrt(5   )
					A    =      (1 + sqrt_a) / 2
					return [round(phi**i / sqrt_a   ) for i in range(n + 1   )]


if __name__ == "__main__":
	__A  :					Optional[Any]												=	30
	time_func(fib_iterative, num)
	time_func(fib_recursive, num)  # Around 3s runtime
	time_func(fib_recursive_cached, num)  # Around 0ms runtime
	time_func(fib_memoization, num)
	time_func(fib_binet, num)





