mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-26 10:58:40 +00:00
Merge branch 'TheAlgorithms:master' into fix-mypy-errs-5
This commit is contained in:
commit
4823467ab6
@ -16,6 +16,7 @@ fib_memoization runtime: 0.0107 ms
|
|||||||
fib_binet runtime: 0.0174 ms
|
fib_binet runtime: 0.0174 ms
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from functools import lru_cache
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
@ -92,6 +93,39 @@ def fib_recursive(n: int) -> list[int]:
|
|||||||
return [fib_recursive_term(i) for i in range(n + 1)]
|
return [fib_recursive_term(i) for i in range(n + 1)]
|
||||||
|
|
||||||
|
|
||||||
|
def fib_recursive_cached(n: int) -> list[int]:
|
||||||
|
"""
|
||||||
|
Calculates the first n (0-indexed) Fibonacci numbers using recursion
|
||||||
|
>>> fib_iterative(0)
|
||||||
|
[0]
|
||||||
|
>>> fib_iterative(1)
|
||||||
|
[0, 1]
|
||||||
|
>>> fib_iterative(5)
|
||||||
|
[0, 1, 1, 2, 3, 5]
|
||||||
|
>>> fib_iterative(10)
|
||||||
|
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||||
|
>>> fib_iterative(-1)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
Exception: n is negative
|
||||||
|
"""
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def fib_recursive_term(i: int) -> int:
|
||||||
|
"""
|
||||||
|
Calculates the i-th (0-indexed) Fibonacci number using recursion
|
||||||
|
"""
|
||||||
|
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(i) for i in range(n + 1)]
|
||||||
|
|
||||||
|
|
||||||
def fib_memoization(n: int) -> list[int]:
|
def fib_memoization(n: int) -> list[int]:
|
||||||
"""
|
"""
|
||||||
Calculates the first n (0-indexed) Fibonacci numbers using memoization
|
Calculates the first n (0-indexed) Fibonacci numbers using memoization
|
||||||
@ -163,8 +197,9 @@ def fib_binet(n: int) -> list[int]:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
num = 20
|
num = 30
|
||||||
time_func(fib_iterative, num)
|
time_func(fib_iterative, num)
|
||||||
time_func(fib_recursive, 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_memoization, num)
|
||||||
time_func(fib_binet, num)
|
time_func(fib_binet, num)
|
||||||
|
109
maths/gcd_of_n_numbers.py
Normal file
109
maths/gcd_of_n_numbers.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
"""
|
||||||
|
Gcd of N Numbers
|
||||||
|
Reference: https://en.wikipedia.org/wiki/Greatest_common_divisor
|
||||||
|
"""
|
||||||
|
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
|
||||||
|
def get_factors(
|
||||||
|
number: int, factors: Counter | None = None, factor: int = 2
|
||||||
|
) -> Counter:
|
||||||
|
"""
|
||||||
|
this is a recursive function for get all factors of number
|
||||||
|
>>> get_factors(45)
|
||||||
|
Counter({3: 2, 5: 1})
|
||||||
|
>>> get_factors(2520)
|
||||||
|
Counter({2: 3, 3: 2, 5: 1, 7: 1})
|
||||||
|
>>> get_factors(23)
|
||||||
|
Counter({23: 1})
|
||||||
|
>>> get_factors(0)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
TypeError: number must be integer and greater than zero
|
||||||
|
>>> get_factors(-1)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
TypeError: number must be integer and greater than zero
|
||||||
|
>>> get_factors(1.5)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
TypeError: number must be integer and greater than zero
|
||||||
|
|
||||||
|
factor can be all numbers from 2 to number that we check if number % factor == 0
|
||||||
|
if it is equal to zero, we check again with number // factor
|
||||||
|
else we increase factor by one
|
||||||
|
"""
|
||||||
|
|
||||||
|
match number:
|
||||||
|
case int(number) if number == 1:
|
||||||
|
return Counter({1: 1})
|
||||||
|
case int(num) if number > 0:
|
||||||
|
number = num
|
||||||
|
case _:
|
||||||
|
raise TypeError("number must be integer and greater than zero")
|
||||||
|
|
||||||
|
factors = factors or Counter()
|
||||||
|
|
||||||
|
if number == factor: # break condition
|
||||||
|
# all numbers are factors of itself
|
||||||
|
factors[factor] += 1
|
||||||
|
return factors
|
||||||
|
|
||||||
|
if number % factor > 0:
|
||||||
|
# if it is greater than zero
|
||||||
|
# so it is not a factor of number and we check next number
|
||||||
|
return get_factors(number, factors, factor + 1)
|
||||||
|
|
||||||
|
factors[factor] += 1
|
||||||
|
# else we update factors (that is Counter(dict-like) type) and check again
|
||||||
|
return get_factors(number // factor, factors, factor)
|
||||||
|
|
||||||
|
|
||||||
|
def get_greatest_common_divisor(*numbers: int) -> int:
|
||||||
|
"""
|
||||||
|
get gcd of n numbers:
|
||||||
|
>>> get_greatest_common_divisor(18, 45)
|
||||||
|
9
|
||||||
|
>>> get_greatest_common_divisor(23, 37)
|
||||||
|
1
|
||||||
|
>>> get_greatest_common_divisor(2520, 8350)
|
||||||
|
10
|
||||||
|
>>> get_greatest_common_divisor(-10, 20)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
Exception: numbers must be integer and greater than zero
|
||||||
|
>>> get_greatest_common_divisor(1.5, 2)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
Exception: numbers must be integer and greater than zero
|
||||||
|
>>> get_greatest_common_divisor(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||||
|
1
|
||||||
|
>>> get_greatest_common_divisor("1", 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
Exception: numbers must be integer and greater than zero
|
||||||
|
"""
|
||||||
|
|
||||||
|
# we just need factors, not numbers itself
|
||||||
|
try:
|
||||||
|
same_factors, *factors = map(get_factors, numbers)
|
||||||
|
except TypeError as e:
|
||||||
|
raise Exception("numbers must be integer and greater than zero") from e
|
||||||
|
|
||||||
|
for factor in factors:
|
||||||
|
same_factors &= factor
|
||||||
|
# get common factor between all
|
||||||
|
# `&` return common elements with smaller value (for Counter type)
|
||||||
|
|
||||||
|
# now, same_factors is something like {2: 2, 3: 4} that means 2 * 2 * 3 * 3 * 3 * 3
|
||||||
|
mult = 1
|
||||||
|
# power each factor and multiply
|
||||||
|
# for {2: 2, 3: 4}, it is [4, 81] and then 324
|
||||||
|
for m in [factor**power for factor, power in same_factors.items()]:
|
||||||
|
mult *= m
|
||||||
|
return mult
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(get_greatest_common_divisor(18, 45)) # 9
|
Loading…
x
Reference in New Issue
Block a user