mirror of
https://github.com/TheAlgorithms/Python.git
synced 2026-03-13 09:50:19 +08:00
Merge branch 'master' into pre-commit-ci-update-config
This commit is contained in:
@@ -159,7 +159,7 @@ We want your work to be readable by others; therefore, we encourage you to note
|
|||||||
starting_value = int(input("Please enter a starting value: ").strip())
|
starting_value = int(input("Please enter a starting value: ").strip())
|
||||||
```
|
```
|
||||||
|
|
||||||
The use of [Python type hints](https://docs.python.org/3/library/typing.html) is encouraged for function parameters and return values. Our automated testing will run [mypy](http://mypy-lang.org) so run that locally before making your submission.
|
The use of [Python type hints](https://docs.python.org/3/library/typing.html) is encouraged for function parameters and return values. Our automated testing will run [mypy](https://mypy-lang.org) so run that locally before making your submission.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def sum_ab(a: int, b: int) -> int:
|
def sum_ab(a: int, b: int) -> int:
|
||||||
|
|||||||
@@ -91,15 +91,15 @@ def fib_iterative(n: int) -> list[int]:
|
|||||||
def fib_recursive(n: int) -> list[int]:
|
def fib_recursive(n: int) -> list[int]:
|
||||||
"""
|
"""
|
||||||
Calculates the first n (0-indexed) Fibonacci numbers using recursion
|
Calculates the first n (0-indexed) Fibonacci numbers using recursion
|
||||||
>>> fib_iterative(0)
|
>>> fib_recursive(0)
|
||||||
[0]
|
[0]
|
||||||
>>> fib_iterative(1)
|
>>> fib_recursive(1)
|
||||||
[0, 1]
|
[0, 1]
|
||||||
>>> fib_iterative(5)
|
>>> fib_recursive(5)
|
||||||
[0, 1, 1, 2, 3, 5]
|
[0, 1, 1, 2, 3, 5]
|
||||||
>>> fib_iterative(10)
|
>>> fib_recursive(10)
|
||||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||||
>>> fib_iterative(-1)
|
>>> fib_recursive(-1)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: n is negative
|
ValueError: n is negative
|
||||||
@@ -119,7 +119,7 @@ def fib_recursive(n: int) -> list[int]:
|
|||||||
>>> fib_recursive_term(-1)
|
>>> fib_recursive_term(-1)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
Exception: n is negative
|
ValueError: n is negative
|
||||||
"""
|
"""
|
||||||
if i < 0:
|
if i < 0:
|
||||||
raise ValueError("n is negative")
|
raise ValueError("n is negative")
|
||||||
@@ -135,15 +135,15 @@ def fib_recursive(n: int) -> list[int]:
|
|||||||
def fib_recursive_cached(n: int) -> list[int]:
|
def fib_recursive_cached(n: int) -> list[int]:
|
||||||
"""
|
"""
|
||||||
Calculates the first n (0-indexed) Fibonacci numbers using recursion
|
Calculates the first n (0-indexed) Fibonacci numbers using recursion
|
||||||
>>> fib_iterative(0)
|
>>> fib_recursive_cached(0)
|
||||||
[0]
|
[0]
|
||||||
>>> fib_iterative(1)
|
>>> fib_recursive_cached(1)
|
||||||
[0, 1]
|
[0, 1]
|
||||||
>>> fib_iterative(5)
|
>>> fib_recursive_cached(5)
|
||||||
[0, 1, 1, 2, 3, 5]
|
[0, 1, 1, 2, 3, 5]
|
||||||
>>> fib_iterative(10)
|
>>> fib_recursive_cached(10)
|
||||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||||
>>> fib_iterative(-1)
|
>>> fib_recursive_cached(-1)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: n is negative
|
ValueError: n is negative
|
||||||
@@ -176,7 +176,7 @@ def fib_memoization(n: int) -> list[int]:
|
|||||||
[0, 1, 1, 2, 3, 5]
|
[0, 1, 1, 2, 3, 5]
|
||||||
>>> fib_memoization(10)
|
>>> fib_memoization(10)
|
||||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||||
>>> fib_iterative(-1)
|
>>> fib_memoization(-1)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: n is negative
|
ValueError: n is negative
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ def greatest_common_divisor(a: int, b: int) -> int:
|
|||||||
3
|
3
|
||||||
>>> greatest_common_divisor(-3, -9)
|
>>> greatest_common_divisor(-3, -9)
|
||||||
3
|
3
|
||||||
|
>>> greatest_common_divisor(0, 0)
|
||||||
|
0
|
||||||
"""
|
"""
|
||||||
return abs(b) if a == 0 else greatest_common_divisor(b % a, a)
|
return abs(b) if a == 0 else greatest_common_divisor(b % a, a)
|
||||||
|
|
||||||
@@ -50,6 +52,8 @@ def gcd_by_iterative(x: int, y: int) -> int:
|
|||||||
1
|
1
|
||||||
>>> gcd_by_iterative(11, 37)
|
>>> gcd_by_iterative(11, 37)
|
||||||
1
|
1
|
||||||
|
>>> gcd_by_iterative(0, 0)
|
||||||
|
0
|
||||||
"""
|
"""
|
||||||
while y: # --> when y=0 then loop will terminate and return x as final GCD.
|
while y: # --> when y=0 then loop will terminate and return x as final GCD.
|
||||||
x, y = y, x % y
|
x, y = y, x % y
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ https://www.hackerearth.com/practice/notes/matrix-exponentiation-1/
|
|||||||
|
|
||||||
|
|
||||||
class Matrix:
|
class Matrix:
|
||||||
def __init__(self, arg):
|
def __init__(self, arg: list[list] | int) -> None:
|
||||||
if isinstance(arg, list): # Initializes a matrix identical to the one provided.
|
if isinstance(arg, list): # Initializes a matrix identical to the one provided.
|
||||||
self.t = arg
|
self.t = arg
|
||||||
self.n = len(arg)
|
self.n = len(arg)
|
||||||
@@ -19,7 +19,7 @@ class Matrix:
|
|||||||
self.n = arg
|
self.n = arg
|
||||||
self.t = [[0 for _ in range(self.n)] for _ in range(self.n)]
|
self.t = [[0 for _ in range(self.n)] for _ in range(self.n)]
|
||||||
|
|
||||||
def __mul__(self, b):
|
def __mul__(self, b: Matrix) -> Matrix:
|
||||||
matrix = Matrix(self.n)
|
matrix = Matrix(self.n)
|
||||||
for i in range(self.n):
|
for i in range(self.n):
|
||||||
for j in range(self.n):
|
for j in range(self.n):
|
||||||
@@ -28,7 +28,7 @@ class Matrix:
|
|||||||
return matrix
|
return matrix
|
||||||
|
|
||||||
|
|
||||||
def modular_exponentiation(a, b):
|
def modular_exponentiation(a: Matrix, b: int) -> Matrix:
|
||||||
matrix = Matrix([[1, 0], [0, 1]])
|
matrix = Matrix([[1, 0], [0, 1]])
|
||||||
while b > 0:
|
while b > 0:
|
||||||
if b & 1:
|
if b & 1:
|
||||||
@@ -38,7 +38,7 @@ def modular_exponentiation(a, b):
|
|||||||
return matrix
|
return matrix
|
||||||
|
|
||||||
|
|
||||||
def fibonacci_with_matrix_exponentiation(n, f1, f2):
|
def fibonacci_with_matrix_exponentiation(n: int, f1: int, f2: int) -> int:
|
||||||
"""
|
"""
|
||||||
Returns the nth number of the Fibonacci sequence that
|
Returns the nth number of the Fibonacci sequence that
|
||||||
starts with f1 and f2
|
starts with f1 and f2
|
||||||
@@ -64,7 +64,7 @@ def fibonacci_with_matrix_exponentiation(n, f1, f2):
|
|||||||
return f2 * matrix.t[0][0] + f1 * matrix.t[0][1]
|
return f2 * matrix.t[0][0] + f1 * matrix.t[0][1]
|
||||||
|
|
||||||
|
|
||||||
def simple_fibonacci(n, f1, f2):
|
def simple_fibonacci(n: int, f1: int, f2: int) -> int:
|
||||||
"""
|
"""
|
||||||
Returns the nth number of the Fibonacci sequence that
|
Returns the nth number of the Fibonacci sequence that
|
||||||
starts with f1 and f2
|
starts with f1 and f2
|
||||||
@@ -95,7 +95,7 @@ def simple_fibonacci(n, f1, f2):
|
|||||||
return f2
|
return f2
|
||||||
|
|
||||||
|
|
||||||
def matrix_exponentiation_time():
|
def matrix_exponentiation_time() -> float:
|
||||||
setup = """
|
setup = """
|
||||||
from random import randint
|
from random import randint
|
||||||
from __main__ import fibonacci_with_matrix_exponentiation
|
from __main__ import fibonacci_with_matrix_exponentiation
|
||||||
@@ -106,7 +106,7 @@ from __main__ import fibonacci_with_matrix_exponentiation
|
|||||||
return exec_time
|
return exec_time
|
||||||
|
|
||||||
|
|
||||||
def simple_fibonacci_time():
|
def simple_fibonacci_time() -> float:
|
||||||
setup = """
|
setup = """
|
||||||
from random import randint
|
from random import randint
|
||||||
from __main__ import simple_fibonacci
|
from __main__ import simple_fibonacci
|
||||||
@@ -119,7 +119,7 @@ from __main__ import simple_fibonacci
|
|||||||
return exec_time
|
return exec_time
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
matrix_exponentiation_time()
|
matrix_exponentiation_time()
|
||||||
simple_fibonacci_time()
|
simple_fibonacci_time()
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,13 @@ def modular_division(a: int, b: int, n: int) -> int:
|
|||||||
4
|
4
|
||||||
|
|
||||||
"""
|
"""
|
||||||
assert n > 1
|
if n <= 1:
|
||||||
assert a > 0
|
raise ValueError("Modulus n must be greater than 1")
|
||||||
assert greatest_common_divisor(a, n) == 1
|
if a <= 0:
|
||||||
|
raise ValueError("Divisor a must be a positive integer")
|
||||||
|
if greatest_common_divisor(a, n) != 1:
|
||||||
|
raise ValueError("a and n must be coprime (gcd(a, n) = 1)")
|
||||||
|
|
||||||
(_d, _t, s) = extended_gcd(n, a) # Implemented below
|
(_d, _t, s) = extended_gcd(n, a) # Implemented below
|
||||||
x = (b * s) % n
|
x = (b * s) % n
|
||||||
return x
|
return x
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ python bogo_sort.py
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
def bogo_sort(collection):
|
def bogo_sort(collection: list) -> list:
|
||||||
"""Pure implementation of the bogosort algorithm in Python
|
"""Pure implementation of the bogosort algorithm in Python
|
||||||
:param collection: some mutable ordered collection with heterogeneous
|
:param collection: some mutable ordered collection with heterogeneous
|
||||||
comparable items inside
|
comparable items inside
|
||||||
@@ -30,7 +30,7 @@ def bogo_sort(collection):
|
|||||||
[-45, -5, -2]
|
[-45, -5, -2]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def is_sorted(collection):
|
def is_sorted(collection: list) -> bool:
|
||||||
for i in range(len(collection) - 1):
|
for i in range(len(collection) - 1):
|
||||||
if collection[i] > collection[i + 1]:
|
if collection[i] > collection[i + 1]:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ def bubble_sort_iterative(collection: list[Any]) -> list[Any]:
|
|||||||
|
|
||||||
:param collection: some mutable ordered collection with heterogeneous
|
:param collection: some mutable ordered collection with heterogeneous
|
||||||
comparable items inside
|
comparable items inside
|
||||||
:return: the same collection ordered by ascending
|
:return: the same collection ordered in ascending order
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> bubble_sort_iterative([0, 5, 2, 3, 2])
|
>>> bubble_sort_iterative([0, 5, 2, 3, 2])
|
||||||
@@ -17,6 +17,12 @@ def bubble_sort_iterative(collection: list[Any]) -> list[Any]:
|
|||||||
[-45, -5, -2]
|
[-45, -5, -2]
|
||||||
>>> bubble_sort_iterative([-23, 0, 6, -4, 34])
|
>>> bubble_sort_iterative([-23, 0, 6, -4, 34])
|
||||||
[-23, -4, 0, 6, 34]
|
[-23, -4, 0, 6, 34]
|
||||||
|
>>> bubble_sort_iterative([1, 2, 3, 4])
|
||||||
|
[1, 2, 3, 4]
|
||||||
|
>>> bubble_sort_iterative([3, 3, 3, 3])
|
||||||
|
[3, 3, 3, 3]
|
||||||
|
>>> bubble_sort_iterative([56])
|
||||||
|
[56]
|
||||||
>>> bubble_sort_iterative([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
|
>>> bubble_sort_iterative([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
|
||||||
True
|
True
|
||||||
>>> bubble_sort_iterative([]) == sorted([])
|
>>> bubble_sort_iterative([]) == sorted([])
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ def count_vowels(s: str) -> int:
|
|||||||
1
|
1
|
||||||
"""
|
"""
|
||||||
if not isinstance(s, str):
|
if not isinstance(s, str):
|
||||||
raise ValueError("Input must be a string")
|
raise TypeError("Input must be a string")
|
||||||
|
|
||||||
vowels = "aeiouAEIOU"
|
vowels = "aeiouAEIOU"
|
||||||
return sum(1 for char in s if char in vowels)
|
return sum(1 for char in s if char in vowels)
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ test_data = {
|
|||||||
"AB": False,
|
"AB": False,
|
||||||
}
|
}
|
||||||
# Ensure our test data is valid
|
# Ensure our test data is valid
|
||||||
assert all((key == key[::-1]) is value for key, value in test_data.items())
|
assert all((key == key[::-1]) == value for key, value in test_data.items())
|
||||||
|
|
||||||
|
|
||||||
def is_palindrome(s: str) -> bool:
|
def is_palindrome(s: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Return True if s is a palindrome otherwise return False.
|
Return True if s is a palindrome otherwise return False.
|
||||||
|
|
||||||
>>> all(is_palindrome(key) is value for key, value in test_data.items())
|
>>> all(is_palindrome(key) == value for key, value in test_data.items())
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ def is_palindrome_traversal(s: str) -> bool:
|
|||||||
"""
|
"""
|
||||||
Return True if s is a palindrome otherwise return False.
|
Return True if s is a palindrome otherwise return False.
|
||||||
|
|
||||||
>>> all(is_palindrome_traversal(key) is value for key, value in test_data.items())
|
>>> all(is_palindrome_traversal(key) == value for key, value in test_data.items())
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
end = len(s) // 2
|
end = len(s) // 2
|
||||||
@@ -60,7 +60,7 @@ def is_palindrome_recursive(s: str) -> bool:
|
|||||||
"""
|
"""
|
||||||
Return True if s is a palindrome otherwise return False.
|
Return True if s is a palindrome otherwise return False.
|
||||||
|
|
||||||
>>> all(is_palindrome_recursive(key) is value for key, value in test_data.items())
|
>>> all(is_palindrome_recursive(key) == value for key, value in test_data.items())
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
if len(s) <= 1:
|
if len(s) <= 1:
|
||||||
@@ -75,14 +75,14 @@ def is_palindrome_slice(s: str) -> bool:
|
|||||||
"""
|
"""
|
||||||
Return True if s is a palindrome otherwise return False.
|
Return True if s is a palindrome otherwise return False.
|
||||||
|
|
||||||
>>> all(is_palindrome_slice(key) is value for key, value in test_data.items())
|
>>> all(is_palindrome_slice(key) == value for key, value in test_data.items())
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
return s == s[::-1]
|
return s == s[::-1]
|
||||||
|
|
||||||
|
|
||||||
def benchmark_function(name: str) -> None:
|
def benchmark_function(name: str) -> None:
|
||||||
stmt = f"all({name}(key) is value for key, value in test_data.items())"
|
stmt = f"all({name}(key) == value for key, value in test_data.items())"
|
||||||
setup = f"from __main__ import test_data, {name}"
|
setup = f"from __main__ import test_data, {name}"
|
||||||
number = 500000
|
number = 500000
|
||||||
result = timeit(stmt=stmt, setup=setup, number=number)
|
result = timeit(stmt=stmt, setup=setup, number=number)
|
||||||
@@ -91,8 +91,8 @@ def benchmark_function(name: str) -> None:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
for key, value in test_data.items():
|
for key, value in test_data.items():
|
||||||
assert is_palindrome(key) is is_palindrome_recursive(key)
|
assert is_palindrome(key) == is_palindrome_recursive(key)
|
||||||
assert is_palindrome(key) is is_palindrome_slice(key)
|
assert is_palindrome(key) == is_palindrome_slice(key)
|
||||||
print(f"{key:21} {value}")
|
print(f"{key:21} {value}")
|
||||||
print("a man a plan a canal panama")
|
print("a man a plan a canal panama")
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
def reverse_letters(sentence: str, length: int = 0) -> str:
|
def reverse_letters(sentence: str, length: int = 0) -> str:
|
||||||
"""
|
"""
|
||||||
Reverse all words that are longer than the given length of characters in a sentence.
|
Reverse all words that are longer than the given length of characters in a sentence.
|
||||||
If unspecified, length is taken as 0
|
If ``length`` is not specified, it defaults to 0.
|
||||||
|
|
||||||
>>> reverse_letters("Hey wollef sroirraw", 3)
|
>>> reverse_letters("Hey wollef sroirraw", 3)
|
||||||
'Hey fellow warriors'
|
'Hey fellow warriors'
|
||||||
@@ -13,7 +13,7 @@ def reverse_letters(sentence: str, length: int = 0) -> str:
|
|||||||
'racecar'
|
'racecar'
|
||||||
"""
|
"""
|
||||||
return " ".join(
|
return " ".join(
|
||||||
"".join(word[::-1]) if len(word) > length else word for word in sentence.split()
|
word[::-1] if len(word) > length else word for word in sentence.split()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user