diff --git a/dynamic_programming/kadanes_algorithm.py b/dynamic_programming/kadanes_algorithm.py new file mode 100644 index 000000000000..1ed8d17effee --- /dev/null +++ b/dynamic_programming/kadanes_algorithm.py @@ -0,0 +1,36 @@ +""" +Kadane's Algorithm +Find the maximum sum of a contiguous subarray. + +Time Complexity: O(n) +Space Complexity: O(1) +""" + +from typing import List + + +def max_subarray_sum(arr: List[int]) -> int: + """ + Find the maximum sum of a contiguous subarray. + + >>> max_subarray_sum([-2, 1, -3, 4, -1, 2, 1, -5, 4]) + 6 + >>> max_subarray_sum([1]) + 1 + >>> max_subarray_sum([5, 4, -1, 7, 8]) + 23 + """ + if not arr: + raise ValueError("Array must not be empty") + + max_sum = current_sum = arr[0] + for num in arr[1:]: + current_sum = max(num, current_sum + num) + max_sum = max(max_sum, current_sum) + return max_sum + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/maths/abs_max.py b/maths/abs_max.py new file mode 100644 index 000000000000..cbf468ca0c54 --- /dev/null +++ b/maths/abs_max.py @@ -0,0 +1,21 @@ +"""Find the absolute maximum element in a list.""" + + +def abs_max(arr: list[int]) -> int: + """ + Find the element with maximum absolute value. + + >>> abs_max([-10, 20, -30, 40]) + -30 + >>> abs_max([1, 2, 3]) + 3 + """ + if not arr: + raise ValueError("List is empty") + return max(arr, key=abs) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/maths/average.py b/maths/average.py new file mode 100644 index 000000000000..ae4ae9f2a807 --- /dev/null +++ b/maths/average.py @@ -0,0 +1,21 @@ +"""Compute average of a list of numbers.""" + + +def average(numbers: list[float]) -> float: + """ + Compute the arithmetic mean. + + >>> average([1, 2, 3, 4, 5]) + 3.0 + >>> average([10, 20]) + 15.0 + """ + if not numbers: + raise ValueError("List is empty") + return sum(numbers) / len(numbers) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/maths/gcd.py b/maths/gcd.py new file mode 100644 index 000000000000..f4e5cd43f63a --- /dev/null +++ b/maths/gcd.py @@ -0,0 +1,20 @@ +"""Greatest Common Divisor using Euclidean algorithm.""" + + +def gcd(a: int, b: int) -> int: + """ + Find GCD of two numbers. + + >>> gcd(12, 8) + 4 + >>> gcd(54, 24) + 6 + """ + while b: + a, b = b, a % b + return a + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/maths/is_prime.py b/maths/is_prime.py new file mode 100644 index 000000000000..a20f310a988d --- /dev/null +++ b/maths/is_prime.py @@ -0,0 +1,33 @@ +"""Prime number checker.""" + + +def is_prime(n: int) -> bool: + """ + Check if a number is prime. + + >>> is_prime(2) + True + >>> is_prime(17) + True + >>> is_prime(4) + False + >>> is_prime(1) + False + """ + if n < 2: + return False + if n < 4: + return True + if n % 2 == 0 or n % 3 == 0: + return False + i = 5 + while i * i <= n: + if n % i == 0 or n % (i + 2) == 0: + return False + i += 6 + return True + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/maths/lcm.py b/maths/lcm.py new file mode 100644 index 000000000000..9467cc685dc9 --- /dev/null +++ b/maths/lcm.py @@ -0,0 +1,19 @@ +"""Least Common Multiple using GCD.""" + + +def lcm(a: int, b: int) -> int: + """ + Find LCM of two numbers. + + >>> lcm(4, 6) + 12 + >>> lcm(3, 7) + 21 + """ + from math import gcd + return abs(a * b) // gcd(a, b) + + +if __name__ == "__main__": + import doctest + doctest.testmod()