mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-07-06 18:49:26 +08:00
move-files-and-2-renames (#4285)
This commit is contained in:
50
maths/binary_exponentiation_2.py
Normal file
50
maths/binary_exponentiation_2.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""
|
||||
* Binary Exponentiation with Multiplication
|
||||
* This is a method to find a*b in a time complexity of O(log b)
|
||||
* This is one of the most commonly used methods of finding result of multiplication.
|
||||
* Also useful in cases where solution to (a*b)%c is required,
|
||||
* where a,b,c can be numbers over the computers calculation limits.
|
||||
* Done using iteration, can also be done using recursion
|
||||
|
||||
* @author chinmoy159
|
||||
* @version 1.0 dated 10/08/2017
|
||||
"""
|
||||
|
||||
|
||||
def b_expo(a, b):
|
||||
res = 0
|
||||
while b > 0:
|
||||
if b & 1:
|
||||
res += a
|
||||
|
||||
a += a
|
||||
b >>= 1
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def b_expo_mod(a, b, c):
|
||||
res = 0
|
||||
while b > 0:
|
||||
if b & 1:
|
||||
res = ((res % c) + (a % c)) % c
|
||||
|
||||
a += a
|
||||
b >>= 1
|
||||
|
||||
return res
|
||||
|
||||
|
||||
"""
|
||||
* Wondering how this method works !
|
||||
* It's pretty simple.
|
||||
* Let's say you need to calculate a ^ b
|
||||
* RULE 1 : a * b = (a+a) * (b/2) ---- example : 4 * 4 = (4+4) * (4/2) = 8 * 2
|
||||
* RULE 2 : IF b is ODD, then ---- a * b = a + (a * (b - 1)) :: where (b - 1) is even.
|
||||
* Once b is even, repeat the process to get a * b
|
||||
* Repeat the process till b = 1 OR b = 0, because a*1 = a AND a*0 = 0
|
||||
*
|
||||
* As far as the modulo is concerned,
|
||||
* the fact : (a+b) % c = ((a%c) + (b%c)) % c
|
||||
* Now apply RULE 1 OR 2, whichever is required.
|
||||
"""
|
50
maths/binary_exponentiation_3.py
Normal file
50
maths/binary_exponentiation_3.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""
|
||||
* Binary Exponentiation for Powers
|
||||
* This is a method to find a^b in a time complexity of O(log b)
|
||||
* This is one of the most commonly used methods of finding powers.
|
||||
* Also useful in cases where solution to (a^b)%c is required,
|
||||
* where a,b,c can be numbers over the computers calculation limits.
|
||||
* Done using iteration, can also be done using recursion
|
||||
|
||||
* @author chinmoy159
|
||||
* @version 1.0 dated 10/08/2017
|
||||
"""
|
||||
|
||||
|
||||
def b_expo(a, b):
|
||||
res = 1
|
||||
while b > 0:
|
||||
if b & 1:
|
||||
res *= a
|
||||
|
||||
a *= a
|
||||
b >>= 1
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def b_expo_mod(a, b, c):
|
||||
res = 1
|
||||
while b > 0:
|
||||
if b & 1:
|
||||
res = ((res % c) * (a % c)) % c
|
||||
|
||||
a *= a
|
||||
b >>= 1
|
||||
|
||||
return res
|
||||
|
||||
|
||||
"""
|
||||
* Wondering how this method works !
|
||||
* It's pretty simple.
|
||||
* Let's say you need to calculate a ^ b
|
||||
* RULE 1 : a ^ b = (a*a) ^ (b/2) ---- example : 4 ^ 4 = (4*4) ^ (4/2) = 16 ^ 2
|
||||
* RULE 2 : IF b is ODD, then ---- a ^ b = a * (a ^ (b - 1)) :: where (b - 1) is even.
|
||||
* Once b is even, repeat the process to get a ^ b
|
||||
* Repeat the process till b = 1 OR b = 0, because a^1 = a AND a^0 = 1
|
||||
*
|
||||
* As far as the modulo is concerned,
|
||||
* the fact : (a*b) % c = ((a%c) * (b%c)) % c
|
||||
* Now apply RULE 1 OR 2 whichever is required.
|
||||
"""
|
47
maths/euclidean_gcd.py
Normal file
47
maths/euclidean_gcd.py
Normal file
@ -0,0 +1,47 @@
|
||||
""" https://en.wikipedia.org/wiki/Euclidean_algorithm """
|
||||
|
||||
|
||||
def euclidean_gcd(a: int, b: int) -> int:
|
||||
"""
|
||||
Examples:
|
||||
>>> euclidean_gcd(3, 5)
|
||||
1
|
||||
|
||||
>>> euclidean_gcd(6, 3)
|
||||
3
|
||||
"""
|
||||
while b:
|
||||
a, b = b, a % b
|
||||
return a
|
||||
|
||||
|
||||
def euclidean_gcd_recursive(a: int, b: int) -> int:
|
||||
"""
|
||||
Recursive method for euclicedan gcd algorithm
|
||||
|
||||
Examples:
|
||||
>>> euclidean_gcd_recursive(3, 5)
|
||||
1
|
||||
|
||||
>>> euclidean_gcd_recursive(6, 3)
|
||||
3
|
||||
"""
|
||||
return a if b == 0 else euclidean_gcd_recursive(b, a % b)
|
||||
|
||||
|
||||
def main():
|
||||
print(f"euclidean_gcd(3, 5) = {euclidean_gcd(3, 5)}")
|
||||
print(f"euclidean_gcd(5, 3) = {euclidean_gcd(5, 3)}")
|
||||
print(f"euclidean_gcd(1, 3) = {euclidean_gcd(1, 3)}")
|
||||
print(f"euclidean_gcd(3, 6) = {euclidean_gcd(3, 6)}")
|
||||
print(f"euclidean_gcd(6, 3) = {euclidean_gcd(6, 3)}")
|
||||
|
||||
print(f"euclidean_gcd_recursive(3, 5) = {euclidean_gcd_recursive(3, 5)}")
|
||||
print(f"euclidean_gcd_recursive(5, 3) = {euclidean_gcd_recursive(5, 3)}")
|
||||
print(f"euclidean_gcd_recursive(1, 3) = {euclidean_gcd_recursive(1, 3)}")
|
||||
print(f"euclidean_gcd_recursive(3, 6) = {euclidean_gcd_recursive(3, 6)}")
|
||||
print(f"euclidean_gcd_recursive(6, 3) = {euclidean_gcd_recursive(6, 3)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
126
maths/integration_by_simpson_approx.py
Normal file
126
maths/integration_by_simpson_approx.py
Normal file
@ -0,0 +1,126 @@
|
||||
"""
|
||||
Author : Syed Faizan ( 3rd Year IIIT Pune )
|
||||
Github : faizan2700
|
||||
|
||||
Purpose : You have one function f(x) which takes float integer and returns
|
||||
float you have to integrate the function in limits a to b.
|
||||
The approximation proposed by Thomas Simpsons in 1743 is one way to calculate
|
||||
integration.
|
||||
|
||||
( read article : https://cp-algorithms.com/num_methods/simpson-integration.html )
|
||||
|
||||
simpson_integration() takes function,lower_limit=a,upper_limit=b,precision and
|
||||
returns the integration of function in given limit.
|
||||
"""
|
||||
|
||||
# constants
|
||||
# the more the number of steps the more accurate
|
||||
N_STEPS = 1000
|
||||
|
||||
|
||||
def f(x: float) -> float:
|
||||
return x * x
|
||||
|
||||
|
||||
"""
|
||||
Summary of Simpson Approximation :
|
||||
|
||||
By simpsons integration :
|
||||
1. integration of fxdx with limit a to b is =
|
||||
f(x0) + 4 * f(x1) + 2 * f(x2) + 4 * f(x3) + 2 * f(x4)..... + f(xn)
|
||||
where x0 = a
|
||||
xi = a + i * h
|
||||
xn = b
|
||||
"""
|
||||
|
||||
|
||||
def simpson_integration(function, a: float, b: float, precision: int = 4) -> float:
|
||||
|
||||
"""
|
||||
Args:
|
||||
function : the function which's integration is desired
|
||||
a : the lower limit of integration
|
||||
b : upper limit of integraion
|
||||
precision : precision of the result,error required default is 4
|
||||
|
||||
Returns:
|
||||
result : the value of the approximated integration of function in range a to b
|
||||
|
||||
Raises:
|
||||
AssertionError: function is not callable
|
||||
AssertionError: a is not float or integer
|
||||
AssertionError: function should return float or integer
|
||||
AssertionError: b is not float or integer
|
||||
AssertionError: precision is not positive integer
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,1,2,3)
|
||||
2.333
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,'wrong_input',2,3)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: a should be float or integer your input : wrong_input
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,1,'wrong_input',3)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: b should be float or integer your input : wrong_input
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,1,2,'wrong_input')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: precision should be positive integer your input : wrong_input
|
||||
>>> simpson_integration('wrong_input',2,3,4)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: the function(object) passed should be callable your input : ...
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,3.45,3.2,1)
|
||||
-2.8
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,3.45,3.2,0)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: precision should be positive integer your input : 0
|
||||
|
||||
>>> simpson_integration(lambda x : x*x,3.45,3.2,-1)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: precision should be positive integer your input : -1
|
||||
|
||||
"""
|
||||
assert callable(
|
||||
function
|
||||
), f"the function(object) passed should be callable your input : {function}"
|
||||
assert isinstance(a, float) or isinstance(
|
||||
a, int
|
||||
), f"a should be float or integer your input : {a}"
|
||||
assert isinstance(function(a), float) or isinstance(function(a), int), (
|
||||
"the function should return integer or float return type of your function, "
|
||||
f"{type(a)}"
|
||||
)
|
||||
assert isinstance(b, float) or isinstance(
|
||||
b, int
|
||||
), f"b should be float or integer your input : {b}"
|
||||
assert (
|
||||
isinstance(precision, int) and precision > 0
|
||||
), f"precision should be positive integer your input : {precision}"
|
||||
|
||||
# just applying the formula of simpson for approximate integraion written in
|
||||
# mentioned article in first comment of this file and above this function
|
||||
|
||||
h = (b - a) / N_STEPS
|
||||
result = function(a) + function(b)
|
||||
|
||||
for i in range(1, N_STEPS):
|
||||
a1 = a + h * i
|
||||
result += function(a1) * (4 if i % 2 else 2)
|
||||
|
||||
result *= h / 3
|
||||
return round(result, precision)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
23
maths/largest_subarray_sum.py
Normal file
23
maths/largest_subarray_sum.py
Normal file
@ -0,0 +1,23 @@
|
||||
from sys import maxsize
|
||||
|
||||
|
||||
def max_sub_array_sum(a: list, size: int = 0):
|
||||
"""
|
||||
>>> max_sub_array_sum([-13, -3, -25, -20, -3, -16, -23, -12, -5, -22, -15, -4, -7])
|
||||
-3
|
||||
"""
|
||||
size = size or len(a)
|
||||
max_so_far = -maxsize - 1
|
||||
max_ending_here = 0
|
||||
for i in range(0, size):
|
||||
max_ending_here = max_ending_here + a[i]
|
||||
if max_so_far < max_ending_here:
|
||||
max_so_far = max_ending_here
|
||||
if max_ending_here < 0:
|
||||
max_ending_here = 0
|
||||
return max_so_far
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = [-13, -3, -25, -20, 1, -16, -23, -12, -5, -22, -15, -4, -7]
|
||||
print(("Maximum contiguous sum is", max_sub_array_sum(a, len(a))))
|
45
maths/max_sum_sliding_window.py
Normal file
45
maths/max_sum_sliding_window.py
Normal file
@ -0,0 +1,45 @@
|
||||
"""
|
||||
Given an array of integer elements and an integer 'k', we are required to find the
|
||||
maximum sum of 'k' consecutive elements in the array.
|
||||
|
||||
Instead of using a nested for loop, in a Brute force approach we will use a technique
|
||||
called 'Window sliding technique' where the nested loops can be converted to a single
|
||||
loop to reduce time complexity.
|
||||
"""
|
||||
from typing import List
|
||||
|
||||
|
||||
def max_sum_in_array(array: List[int], k: int) -> int:
|
||||
"""
|
||||
Returns the maximum sum of k consecutive elements
|
||||
>>> arr = [1, 4, 2, 10, 2, 3, 1, 0, 20]
|
||||
>>> k = 4
|
||||
>>> max_sum_in_array(arr, k)
|
||||
24
|
||||
>>> k = 10
|
||||
>>> max_sum_in_array(arr,k)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Invalid Input
|
||||
>>> arr = [1, 4, 2, 10, 2, 13, 1, 0, 2]
|
||||
>>> k = 4
|
||||
>>> max_sum_in_array(arr, k)
|
||||
27
|
||||
"""
|
||||
if len(array) < k or k < 0:
|
||||
raise ValueError("Invalid Input")
|
||||
max_sum = current_sum = sum(array[:k])
|
||||
for i in range(len(array) - k):
|
||||
current_sum = current_sum - array[i] + array[i + k]
|
||||
max_sum = max(max_sum, current_sum)
|
||||
return max_sum
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from doctest import testmod
|
||||
from random import randint
|
||||
|
||||
testmod()
|
||||
array = [randint(-1000, 1000) for i in range(100)]
|
||||
k = randint(0, 110)
|
||||
print(f"The maximum sum of {k} consecutive elements is {max_sum_in_array(array,k)}")
|
33
maths/median_of_two_arrays.py
Normal file
33
maths/median_of_two_arrays.py
Normal file
@ -0,0 +1,33 @@
|
||||
from typing import List
|
||||
|
||||
|
||||
def median_of_two_arrays(nums1: List[float], nums2: List[float]) -> float:
|
||||
"""
|
||||
>>> median_of_two_arrays([1, 2], [3])
|
||||
2
|
||||
>>> median_of_two_arrays([0, -1.1], [2.5, 1])
|
||||
0.5
|
||||
>>> median_of_two_arrays([], [2.5, 1])
|
||||
1.75
|
||||
>>> median_of_two_arrays([], [0])
|
||||
0
|
||||
>>> median_of_two_arrays([], [])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
IndexError: list index out of range
|
||||
"""
|
||||
all_numbers = sorted(nums1 + nums2)
|
||||
div, mod = divmod(len(all_numbers), 2)
|
||||
if mod == 1:
|
||||
return all_numbers[div]
|
||||
else:
|
||||
return (all_numbers[div] + all_numbers[div - 1]) / 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
array_1 = [float(x) for x in input("Enter the elements of first array: ").split()]
|
||||
array_2 = [float(x) for x in input("Enter the elements of second array: ").split()]
|
||||
print(f"The median of two arrays is: {median_of_two_arrays(array_1, array_2)}")
|
644
maths/primelib.py
Normal file
644
maths/primelib.py
Normal file
@ -0,0 +1,644 @@
|
||||
"""
|
||||
Created on Thu Oct 5 16:44:23 2017
|
||||
|
||||
@author: Christian Bender
|
||||
|
||||
This Python library contains some useful functions to deal with
|
||||
prime numbers and whole numbers.
|
||||
|
||||
Overview:
|
||||
|
||||
isPrime(number)
|
||||
sieveEr(N)
|
||||
getPrimeNumbers(N)
|
||||
primeFactorization(number)
|
||||
greatestPrimeFactor(number)
|
||||
smallestPrimeFactor(number)
|
||||
getPrime(n)
|
||||
getPrimesBetween(pNumber1, pNumber2)
|
||||
|
||||
----
|
||||
|
||||
isEven(number)
|
||||
isOdd(number)
|
||||
gcd(number1, number2) // greatest common divisor
|
||||
kgV(number1, number2) // least common multiple
|
||||
getDivisors(number) // all divisors of 'number' inclusive 1, number
|
||||
isPerfectNumber(number)
|
||||
|
||||
NEW-FUNCTIONS
|
||||
|
||||
simplifyFraction(numerator, denominator)
|
||||
factorial (n) // n!
|
||||
fib (n) // calculate the n-th fibonacci term.
|
||||
|
||||
-----
|
||||
|
||||
goldbach(number) // Goldbach's assumption
|
||||
|
||||
"""
|
||||
|
||||
from math import sqrt
|
||||
|
||||
|
||||
def isPrime(number):
|
||||
"""
|
||||
input: positive integer 'number'
|
||||
returns true if 'number' is prime otherwise false.
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int) and (
|
||||
number >= 0
|
||||
), "'number' must been an int and positive"
|
||||
|
||||
status = True
|
||||
|
||||
# 0 and 1 are none primes.
|
||||
if number <= 1:
|
||||
status = False
|
||||
|
||||
for divisor in range(2, int(round(sqrt(number))) + 1):
|
||||
|
||||
# if 'number' divisible by 'divisor' then sets 'status'
|
||||
# of false and break up the loop.
|
||||
if number % divisor == 0:
|
||||
status = False
|
||||
break
|
||||
|
||||
# precondition
|
||||
assert isinstance(status, bool), "'status' must been from type bool"
|
||||
|
||||
return status
|
||||
|
||||
|
||||
# ------------------------------------------
|
||||
|
||||
|
||||
def sieveEr(N):
|
||||
"""
|
||||
input: positive integer 'N' > 2
|
||||
returns a list of prime numbers from 2 up to N.
|
||||
|
||||
This function implements the algorithm called
|
||||
sieve of erathostenes.
|
||||
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(N, int) and (N > 2), "'N' must been an int and > 2"
|
||||
|
||||
# beginList: contains all natural numbers from 2 up to N
|
||||
beginList = [x for x in range(2, N + 1)]
|
||||
|
||||
ans = [] # this list will be returns.
|
||||
|
||||
# actual sieve of erathostenes
|
||||
for i in range(len(beginList)):
|
||||
|
||||
for j in range(i + 1, len(beginList)):
|
||||
|
||||
if (beginList[i] != 0) and (beginList[j] % beginList[i] == 0):
|
||||
beginList[j] = 0
|
||||
|
||||
# filters actual prime numbers.
|
||||
ans = [x for x in beginList if x != 0]
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, list), "'ans' must been from type list"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# --------------------------------
|
||||
|
||||
|
||||
def getPrimeNumbers(N):
|
||||
"""
|
||||
input: positive integer 'N' > 2
|
||||
returns a list of prime numbers from 2 up to N (inclusive)
|
||||
This function is more efficient as function 'sieveEr(...)'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(N, int) and (N > 2), "'N' must been an int and > 2"
|
||||
|
||||
ans = []
|
||||
|
||||
# iterates over all numbers between 2 up to N+1
|
||||
# if a number is prime then appends to list 'ans'
|
||||
for number in range(2, N + 1):
|
||||
|
||||
if isPrime(number):
|
||||
|
||||
ans.append(number)
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, list), "'ans' must been from type list"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# -----------------------------------------
|
||||
|
||||
|
||||
def primeFactorization(number):
|
||||
"""
|
||||
input: positive integer 'number'
|
||||
returns a list of the prime number factors of 'number'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int) and number >= 0, "'number' must been an int and >= 0"
|
||||
|
||||
ans = [] # this list will be returns of the function.
|
||||
|
||||
# potential prime number factors.
|
||||
|
||||
factor = 2
|
||||
|
||||
quotient = number
|
||||
|
||||
if number == 0 or number == 1:
|
||||
|
||||
ans.append(number)
|
||||
|
||||
# if 'number' not prime then builds the prime factorization of 'number'
|
||||
elif not isPrime(number):
|
||||
|
||||
while quotient != 1:
|
||||
|
||||
if isPrime(factor) and (quotient % factor == 0):
|
||||
ans.append(factor)
|
||||
quotient /= factor
|
||||
else:
|
||||
factor += 1
|
||||
|
||||
else:
|
||||
ans.append(number)
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, list), "'ans' must been from type list"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# -----------------------------------------
|
||||
|
||||
|
||||
def greatestPrimeFactor(number):
|
||||
"""
|
||||
input: positive integer 'number' >= 0
|
||||
returns the greatest prime number factor of 'number'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int) and (
|
||||
number >= 0
|
||||
), "'number' bust been an int and >= 0"
|
||||
|
||||
ans = 0
|
||||
|
||||
# prime factorization of 'number'
|
||||
primeFactors = primeFactorization(number)
|
||||
|
||||
ans = max(primeFactors)
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, int), "'ans' must been from type int"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# ----------------------------------------------
|
||||
|
||||
|
||||
def smallestPrimeFactor(number):
|
||||
"""
|
||||
input: integer 'number' >= 0
|
||||
returns the smallest prime number factor of 'number'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int) and (
|
||||
number >= 0
|
||||
), "'number' bust been an int and >= 0"
|
||||
|
||||
ans = 0
|
||||
|
||||
# prime factorization of 'number'
|
||||
primeFactors = primeFactorization(number)
|
||||
|
||||
ans = min(primeFactors)
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, int), "'ans' must been from type int"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# ----------------------
|
||||
|
||||
|
||||
def isEven(number):
|
||||
"""
|
||||
input: integer 'number'
|
||||
returns true if 'number' is even, otherwise false.
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int), "'number' must been an int"
|
||||
assert isinstance(number % 2 == 0, bool), "compare bust been from type bool"
|
||||
|
||||
return number % 2 == 0
|
||||
|
||||
|
||||
# ------------------------
|
||||
|
||||
|
||||
def isOdd(number):
|
||||
"""
|
||||
input: integer 'number'
|
||||
returns true if 'number' is odd, otherwise false.
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int), "'number' must been an int"
|
||||
assert isinstance(number % 2 != 0, bool), "compare bust been from type bool"
|
||||
|
||||
return number % 2 != 0
|
||||
|
||||
|
||||
# ------------------------
|
||||
|
||||
|
||||
def goldbach(number):
|
||||
"""
|
||||
Goldbach's assumption
|
||||
input: a even positive integer 'number' > 2
|
||||
returns a list of two prime numbers whose sum is equal to 'number'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(number, int) and (number > 2) and isEven(number)
|
||||
), "'number' must been an int, even and > 2"
|
||||
|
||||
ans = [] # this list will returned
|
||||
|
||||
# creates a list of prime numbers between 2 up to 'number'
|
||||
primeNumbers = getPrimeNumbers(number)
|
||||
lenPN = len(primeNumbers)
|
||||
|
||||
# run variable for while-loops.
|
||||
i = 0
|
||||
j = None
|
||||
|
||||
# exit variable. for break up the loops
|
||||
loop = True
|
||||
|
||||
while i < lenPN and loop:
|
||||
|
||||
j = i + 1
|
||||
|
||||
while j < lenPN and loop:
|
||||
|
||||
if primeNumbers[i] + primeNumbers[j] == number:
|
||||
loop = False
|
||||
ans.append(primeNumbers[i])
|
||||
ans.append(primeNumbers[j])
|
||||
|
||||
j += 1
|
||||
|
||||
i += 1
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(ans, list)
|
||||
and (len(ans) == 2)
|
||||
and (ans[0] + ans[1] == number)
|
||||
and isPrime(ans[0])
|
||||
and isPrime(ans[1])
|
||||
), "'ans' must contains two primes. And sum of elements must been eq 'number'"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# ----------------------------------------------
|
||||
|
||||
|
||||
def gcd(number1, number2):
|
||||
"""
|
||||
Greatest common divisor
|
||||
input: two positive integer 'number1' and 'number2'
|
||||
returns the greatest common divisor of 'number1' and 'number2'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(number1, int)
|
||||
and isinstance(number2, int)
|
||||
and (number1 >= 0)
|
||||
and (number2 >= 0)
|
||||
), "'number1' and 'number2' must been positive integer."
|
||||
|
||||
rest = 0
|
||||
|
||||
while number2 != 0:
|
||||
|
||||
rest = number1 % number2
|
||||
number1 = number2
|
||||
number2 = rest
|
||||
|
||||
# precondition
|
||||
assert isinstance(number1, int) and (
|
||||
number1 >= 0
|
||||
), "'number' must been from type int and positive"
|
||||
|
||||
return number1
|
||||
|
||||
|
||||
# ----------------------------------------------------
|
||||
|
||||
|
||||
def kgV(number1, number2):
|
||||
"""
|
||||
Least common multiple
|
||||
input: two positive integer 'number1' and 'number2'
|
||||
returns the least common multiple of 'number1' and 'number2'
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(number1, int)
|
||||
and isinstance(number2, int)
|
||||
and (number1 >= 1)
|
||||
and (number2 >= 1)
|
||||
), "'number1' and 'number2' must been positive integer."
|
||||
|
||||
ans = 1 # actual answer that will be return.
|
||||
|
||||
# for kgV (x,1)
|
||||
if number1 > 1 and number2 > 1:
|
||||
|
||||
# builds the prime factorization of 'number1' and 'number2'
|
||||
primeFac1 = primeFactorization(number1)
|
||||
primeFac2 = primeFactorization(number2)
|
||||
|
||||
elif number1 == 1 or number2 == 1:
|
||||
|
||||
primeFac1 = []
|
||||
primeFac2 = []
|
||||
ans = max(number1, number2)
|
||||
|
||||
count1 = 0
|
||||
count2 = 0
|
||||
|
||||
done = [] # captured numbers int both 'primeFac1' and 'primeFac2'
|
||||
|
||||
# iterates through primeFac1
|
||||
for n in primeFac1:
|
||||
|
||||
if n not in done:
|
||||
|
||||
if n in primeFac2:
|
||||
|
||||
count1 = primeFac1.count(n)
|
||||
count2 = primeFac2.count(n)
|
||||
|
||||
for i in range(max(count1, count2)):
|
||||
ans *= n
|
||||
|
||||
else:
|
||||
|
||||
count1 = primeFac1.count(n)
|
||||
|
||||
for i in range(count1):
|
||||
ans *= n
|
||||
|
||||
done.append(n)
|
||||
|
||||
# iterates through primeFac2
|
||||
for n in primeFac2:
|
||||
|
||||
if n not in done:
|
||||
|
||||
count2 = primeFac2.count(n)
|
||||
|
||||
for i in range(count2):
|
||||
ans *= n
|
||||
|
||||
done.append(n)
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, int) and (
|
||||
ans >= 0
|
||||
), "'ans' must been from type int and positive"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# ----------------------------------
|
||||
|
||||
|
||||
def getPrime(n):
|
||||
"""
|
||||
Gets the n-th prime number.
|
||||
input: positive integer 'n' >= 0
|
||||
returns the n-th prime number, beginning at index 0
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(n, int) and (n >= 0), "'number' must been a positive int"
|
||||
|
||||
index = 0
|
||||
ans = 2 # this variable holds the answer
|
||||
|
||||
while index < n:
|
||||
|
||||
index += 1
|
||||
|
||||
ans += 1 # counts to the next number
|
||||
|
||||
# if ans not prime then
|
||||
# runs to the next prime number.
|
||||
while not isPrime(ans):
|
||||
ans += 1
|
||||
|
||||
# precondition
|
||||
assert isinstance(ans, int) and isPrime(
|
||||
ans
|
||||
), "'ans' must been a prime number and from type int"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# ---------------------------------------------------
|
||||
|
||||
|
||||
def getPrimesBetween(pNumber1, pNumber2):
|
||||
"""
|
||||
input: prime numbers 'pNumber1' and 'pNumber2'
|
||||
pNumber1 < pNumber2
|
||||
returns a list of all prime numbers between 'pNumber1' (exclusive)
|
||||
and 'pNumber2' (exclusive)
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isPrime(pNumber1) and isPrime(pNumber2) and (pNumber1 < pNumber2)
|
||||
), "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'"
|
||||
|
||||
number = pNumber1 + 1 # jump to the next number
|
||||
|
||||
ans = [] # this list will be returns.
|
||||
|
||||
# if number is not prime then
|
||||
# fetch the next prime number.
|
||||
while not isPrime(number):
|
||||
number += 1
|
||||
|
||||
while number < pNumber2:
|
||||
|
||||
ans.append(number)
|
||||
|
||||
number += 1
|
||||
|
||||
# fetch the next prime number.
|
||||
while not isPrime(number):
|
||||
number += 1
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(ans, list) and ans[0] != pNumber1 and ans[len(ans) - 1] != pNumber2
|
||||
), "'ans' must been a list without the arguments"
|
||||
|
||||
# 'ans' contains not 'pNumber1' and 'pNumber2' !
|
||||
return ans
|
||||
|
||||
|
||||
# ----------------------------------------------------
|
||||
|
||||
|
||||
def getDivisors(n):
|
||||
"""
|
||||
input: positive integer 'n' >= 1
|
||||
returns all divisors of n (inclusive 1 and 'n')
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(n, int) and (n >= 1), "'n' must been int and >= 1"
|
||||
|
||||
ans = [] # will be returned.
|
||||
|
||||
for divisor in range(1, n + 1):
|
||||
|
||||
if n % divisor == 0:
|
||||
ans.append(divisor)
|
||||
|
||||
# precondition
|
||||
assert ans[0] == 1 and ans[len(ans) - 1] == n, "Error in function getDivisiors(...)"
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# ----------------------------------------------------
|
||||
|
||||
|
||||
def isPerfectNumber(number):
|
||||
"""
|
||||
input: positive integer 'number' > 1
|
||||
returns true if 'number' is a perfect number otherwise false.
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(number, int) and (
|
||||
number > 1
|
||||
), "'number' must been an int and >= 1"
|
||||
|
||||
divisors = getDivisors(number)
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(divisors, list)
|
||||
and (divisors[0] == 1)
|
||||
and (divisors[len(divisors) - 1] == number)
|
||||
), "Error in help-function getDivisiors(...)"
|
||||
|
||||
# summed all divisors up to 'number' (exclusive), hence [:-1]
|
||||
return sum(divisors[:-1]) == number
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
|
||||
|
||||
def simplifyFraction(numerator, denominator):
|
||||
"""
|
||||
input: two integer 'numerator' and 'denominator'
|
||||
assumes: 'denominator' != 0
|
||||
returns: a tuple with simplify numerator and denominator.
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(numerator, int)
|
||||
and isinstance(denominator, int)
|
||||
and (denominator != 0)
|
||||
), "The arguments must been from type int and 'denominator' != 0"
|
||||
|
||||
# build the greatest common divisor of numerator and denominator.
|
||||
gcdOfFraction = gcd(abs(numerator), abs(denominator))
|
||||
|
||||
# precondition
|
||||
assert (
|
||||
isinstance(gcdOfFraction, int)
|
||||
and (numerator % gcdOfFraction == 0)
|
||||
and (denominator % gcdOfFraction == 0)
|
||||
), "Error in function gcd(...,...)"
|
||||
|
||||
return (numerator // gcdOfFraction, denominator // gcdOfFraction)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
|
||||
def factorial(n):
|
||||
"""
|
||||
input: positive integer 'n'
|
||||
returns the factorial of 'n' (n!)
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(n, int) and (n >= 0), "'n' must been a int and >= 0"
|
||||
|
||||
ans = 1 # this will be return.
|
||||
|
||||
for factor in range(1, n + 1):
|
||||
ans *= factor
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
|
||||
def fib(n):
|
||||
"""
|
||||
input: positive integer 'n'
|
||||
returns the n-th fibonacci term , indexing by 0
|
||||
"""
|
||||
|
||||
# precondition
|
||||
assert isinstance(n, int) and (n >= 0), "'n' must been an int and >= 0"
|
||||
|
||||
tmp = 0
|
||||
fib1 = 1
|
||||
ans = 1 # this will be return
|
||||
|
||||
for i in range(n - 1):
|
||||
|
||||
tmp = ans
|
||||
ans += fib1
|
||||
fib1 = tmp
|
||||
|
||||
return ans
|
89
maths/triplet_sum.py
Normal file
89
maths/triplet_sum.py
Normal file
@ -0,0 +1,89 @@
|
||||
"""
|
||||
Given an array of integers and another integer target,
|
||||
we are required to find a triplet from the array such that it's sum is equal to
|
||||
the target.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from itertools import permutations
|
||||
from random import randint
|
||||
from timeit import repeat
|
||||
|
||||
|
||||
def make_dataset() -> tuple[list[int], int]:
|
||||
arr = [randint(-1000, 1000) for i in range(10)]
|
||||
r = randint(-5000, 5000)
|
||||
return (arr, r)
|
||||
|
||||
|
||||
dataset = make_dataset()
|
||||
|
||||
|
||||
def triplet_sum1(arr: list[int], target: int) -> tuple[int, int, int]:
|
||||
"""
|
||||
Returns a triplet in the array with sum equal to target,
|
||||
else (0, 0, 0).
|
||||
>>> triplet_sum1([13, 29, 7, 23, 5], 35)
|
||||
(5, 7, 23)
|
||||
>>> triplet_sum1([37, 9, 19, 50, 44], 65)
|
||||
(9, 19, 37)
|
||||
>>> arr = [6, 47, 27, 1, 15]
|
||||
>>> target = 11
|
||||
>>> triplet_sum1(arr, target)
|
||||
(0, 0, 0)
|
||||
"""
|
||||
for triplet in permutations(arr, 3):
|
||||
if sum(triplet) == target:
|
||||
return tuple(sorted(triplet))
|
||||
return (0, 0, 0)
|
||||
|
||||
|
||||
def triplet_sum2(arr: list[int], target: int) -> tuple[int, int, int]:
|
||||
"""
|
||||
Returns a triplet in the array with sum equal to target,
|
||||
else (0, 0, 0).
|
||||
>>> triplet_sum2([13, 29, 7, 23, 5], 35)
|
||||
(5, 7, 23)
|
||||
>>> triplet_sum2([37, 9, 19, 50, 44], 65)
|
||||
(9, 19, 37)
|
||||
>>> arr = [6, 47, 27, 1, 15]
|
||||
>>> target = 11
|
||||
>>> triplet_sum2(arr, target)
|
||||
(0, 0, 0)
|
||||
"""
|
||||
arr.sort()
|
||||
n = len(arr)
|
||||
for i in range(n - 1):
|
||||
left, right = i + 1, n - 1
|
||||
while left < right:
|
||||
if arr[i] + arr[left] + arr[right] == target:
|
||||
return (arr[i], arr[left], arr[right])
|
||||
elif arr[i] + arr[left] + arr[right] < target:
|
||||
left += 1
|
||||
elif arr[i] + arr[left] + arr[right] > target:
|
||||
right -= 1
|
||||
return (0, 0, 0)
|
||||
|
||||
|
||||
def solution_times() -> tuple[float, float]:
|
||||
setup_code = """
|
||||
from __main__ import dataset, triplet_sum1, triplet_sum2
|
||||
"""
|
||||
test_code1 = """
|
||||
triplet_sum1(*dataset)
|
||||
"""
|
||||
test_code2 = """
|
||||
triplet_sum2(*dataset)
|
||||
"""
|
||||
times1 = repeat(setup=setup_code, stmt=test_code1, repeat=5, number=10000)
|
||||
times2 = repeat(setup=setup_code, stmt=test_code2, repeat=5, number=10000)
|
||||
return (min(times1), min(times2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from doctest import testmod
|
||||
|
||||
testmod()
|
||||
times = solution_times()
|
||||
print(f"The time for naive implementation is {times[0]}.")
|
||||
print(f"The time for optimized implementation is {times[1]}.")
|
61
maths/two_pointer.py
Normal file
61
maths/two_pointer.py
Normal file
@ -0,0 +1,61 @@
|
||||
"""
|
||||
Given a sorted array of integers, return indices of the two numbers such
|
||||
that they add up to a specific target using the two pointers technique.
|
||||
|
||||
You may assume that each input would have exactly one solution, and you
|
||||
may not use the same element twice.
|
||||
|
||||
This is an alternative solution of the two-sum problem, which uses a
|
||||
map to solve the problem. Hence can not solve the issue if there is a
|
||||
constraint not use the same index twice. [1]
|
||||
|
||||
Example:
|
||||
Given nums = [2, 7, 11, 15], target = 9,
|
||||
|
||||
Because nums[0] + nums[1] = 2 + 7 = 9,
|
||||
return [0, 1].
|
||||
|
||||
[1]: https://github.com/TheAlgorithms/Python/blob/master/other/two_sum.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def two_pointer(nums: list[int], target: int) -> list[int]:
|
||||
"""
|
||||
>>> two_pointer([2, 7, 11, 15], 9)
|
||||
[0, 1]
|
||||
>>> two_pointer([2, 7, 11, 15], 17)
|
||||
[0, 3]
|
||||
>>> two_pointer([2, 7, 11, 15], 18)
|
||||
[1, 2]
|
||||
>>> two_pointer([2, 7, 11, 15], 26)
|
||||
[2, 3]
|
||||
>>> two_pointer([1, 3, 3], 6)
|
||||
[1, 2]
|
||||
>>> two_pointer([2, 7, 11, 15], 8)
|
||||
[]
|
||||
>>> two_pointer([3 * i for i in range(10)], 19)
|
||||
[]
|
||||
>>> two_pointer([1, 2, 3], 6)
|
||||
[]
|
||||
"""
|
||||
i = 0
|
||||
j = len(nums) - 1
|
||||
|
||||
while i < j:
|
||||
|
||||
if nums[i] + nums[j] == target:
|
||||
return [i, j]
|
||||
elif nums[i] + nums[j] < target:
|
||||
i = i + 1
|
||||
else:
|
||||
j = j - 1
|
||||
|
||||
return []
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
print(f"{two_pointer([2, 7, 11, 15], 9) = }")
|
47
maths/two_sum.py
Normal file
47
maths/two_sum.py
Normal file
@ -0,0 +1,47 @@
|
||||
"""
|
||||
Given an array of integers, return indices of the two numbers such that they add up to
|
||||
a specific target.
|
||||
|
||||
You may assume that each input would have exactly one solution, and you may not use the
|
||||
same element twice.
|
||||
|
||||
Example:
|
||||
Given nums = [2, 7, 11, 15], target = 9,
|
||||
|
||||
Because nums[0] + nums[1] = 2 + 7 = 9,
|
||||
return [0, 1].
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def two_sum(nums: list[int], target: int) -> list[int]:
|
||||
"""
|
||||
>>> two_sum([2, 7, 11, 15], 9)
|
||||
[0, 1]
|
||||
>>> two_sum([15, 2, 11, 7], 13)
|
||||
[1, 2]
|
||||
>>> two_sum([2, 7, 11, 15], 17)
|
||||
[0, 3]
|
||||
>>> two_sum([7, 15, 11, 2], 18)
|
||||
[0, 2]
|
||||
>>> two_sum([2, 7, 11, 15], 26)
|
||||
[2, 3]
|
||||
>>> two_sum([2, 7, 11, 15], 8)
|
||||
[]
|
||||
>>> two_sum([3 * i for i in range(10)], 19)
|
||||
[]
|
||||
"""
|
||||
chk_map = {}
|
||||
for index, val in enumerate(nums):
|
||||
compl = target - val
|
||||
if compl in chk_map:
|
||||
return [chk_map[compl], index]
|
||||
chk_map[val] = index
|
||||
return []
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
print(f"{two_sum([2, 7, 11, 15], 9) = }")
|
Reference in New Issue
Block a user