mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-27 15:01:08 +00:00
Removed redundant greatest_common_divisor code (#9358)
* Deleted greatest_common_divisor def from many files and instead imported the method from Maths folder * Deleted greatest_common_divisor def from many files and instead imported the method from Maths folder, also fixed comments * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Deleted greatest_common_divisor def from many files and instead imported the method from Maths folder, also fixed comments * Imports organized * recursive gcd function implementation rolledback * more gcd duplicates removed * more gcd duplicates removed * Update maths/carmichael_number.py * updated files * moved a file to another location --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>
This commit is contained in:
parent
876087be99
commit
583a614fef
|
@ -1,11 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from maths.greatest_common_divisor import greatest_common_divisor
|
||||||
|
|
||||||
|
|
||||||
def diophantine(a: int, b: int, c: int) -> tuple[float, float]:
|
def diophantine(a: int, b: int, c: int) -> tuple[float, float]:
|
||||||
"""
|
"""
|
||||||
Diophantine Equation : Given integers a,b,c ( at least one of a and b != 0), the
|
Diophantine Equation : Given integers a,b,c ( at least one of a and b != 0), the
|
||||||
diophantine equation a*x + b*y = c has a solution (where x and y are integers)
|
diophantine equation a*x + b*y = c has a solution (where x and y are integers)
|
||||||
iff gcd(a,b) divides c.
|
iff greatest_common_divisor(a,b) divides c.
|
||||||
|
|
||||||
GCD ( Greatest Common Divisor ) or HCF ( Highest Common Factor )
|
GCD ( Greatest Common Divisor ) or HCF ( Highest Common Factor )
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ def diophantine(a: int, b: int, c: int) -> tuple[float, float]:
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
c % greatest_common_divisor(a, b) == 0
|
c % greatest_common_divisor(a, b) == 0
|
||||||
) # greatest_common_divisor(a,b) function implemented below
|
) # greatest_common_divisor(a,b) is in maths directory
|
||||||
(d, x, y) = extended_gcd(a, b) # extended_gcd(a,b) function implemented below
|
(d, x, y) = extended_gcd(a, b) # extended_gcd(a,b) function implemented below
|
||||||
r = c / d
|
r = c / d
|
||||||
return (r * x, r * y)
|
return (r * x, r * y)
|
||||||
|
@ -69,32 +71,6 @@ def diophantine_all_soln(a: int, b: int, c: int, n: int = 2) -> None:
|
||||||
print(x, y)
|
print(x, y)
|
||||||
|
|
||||||
|
|
||||||
def greatest_common_divisor(a: int, b: int) -> int:
|
|
||||||
"""
|
|
||||||
Euclid's Lemma : d divides a and b, if and only if d divides a-b and b
|
|
||||||
|
|
||||||
Euclid's Algorithm
|
|
||||||
|
|
||||||
>>> greatest_common_divisor(7,5)
|
|
||||||
1
|
|
||||||
|
|
||||||
Note : In number theory, two integers a and b are said to be relatively prime,
|
|
||||||
mutually prime, or co-prime if the only positive integer (factor) that
|
|
||||||
divides both of them is 1 i.e., gcd(a,b) = 1.
|
|
||||||
|
|
||||||
>>> greatest_common_divisor(121, 11)
|
|
||||||
11
|
|
||||||
|
|
||||||
"""
|
|
||||||
if a < b:
|
|
||||||
a, b = b, a
|
|
||||||
|
|
||||||
while a % b != 0:
|
|
||||||
a, b = b, a % b
|
|
||||||
|
|
||||||
return b
|
|
||||||
|
|
||||||
|
|
||||||
def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
|
def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
|
||||||
"""
|
"""
|
||||||
Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers
|
Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from maths.greatest_common_divisor import gcd_by_iterative
|
||||||
|
|
||||||
from . import cryptomath_module as cryptomath
|
from . import cryptomath_module as cryptomath
|
||||||
|
|
||||||
SYMBOLS = (
|
SYMBOLS = (
|
||||||
|
@ -26,7 +28,7 @@ def check_keys(key_a: int, key_b: int, mode: str) -> None:
|
||||||
"Key A must be greater than 0 and key B must "
|
"Key A must be greater than 0 and key B must "
|
||||||
f"be between 0 and {len(SYMBOLS) - 1}."
|
f"be between 0 and {len(SYMBOLS) - 1}."
|
||||||
)
|
)
|
||||||
if cryptomath.gcd(key_a, len(SYMBOLS)) != 1:
|
if gcd_by_iterative(key_a, len(SYMBOLS)) != 1:
|
||||||
sys.exit(
|
sys.exit(
|
||||||
f"Key A {key_a} and the symbol set size {len(SYMBOLS)} "
|
f"Key A {key_a} and the symbol set size {len(SYMBOLS)} "
|
||||||
"are not relatively prime. Choose a different key."
|
"are not relatively prime. Choose a different key."
|
||||||
|
@ -76,7 +78,7 @@ def get_random_key() -> int:
|
||||||
while True:
|
while True:
|
||||||
key_b = random.randint(2, len(SYMBOLS))
|
key_b = random.randint(2, len(SYMBOLS))
|
||||||
key_b = random.randint(2, len(SYMBOLS))
|
key_b = random.randint(2, len(SYMBOLS))
|
||||||
if cryptomath.gcd(key_b, len(SYMBOLS)) == 1 and key_b % len(SYMBOLS) != 0:
|
if gcd_by_iterative(key_b, len(SYMBOLS)) == 1 and key_b % len(SYMBOLS) != 0:
|
||||||
return key_b * len(SYMBOLS) + key_b
|
return key_b * len(SYMBOLS) + key_b
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
def gcd(a: int, b: int) -> int:
|
from maths.greatest_common_divisor import gcd_by_iterative
|
||||||
while a != 0:
|
|
||||||
a, b = b % a, a
|
|
||||||
return b
|
|
||||||
|
|
||||||
|
|
||||||
def find_mod_inverse(a: int, m: int) -> int:
|
def find_mod_inverse(a: int, m: int) -> int:
|
||||||
if gcd(a, m) != 1:
|
if gcd_by_iterative(a, m) != 1:
|
||||||
msg = f"mod inverse of {a!r} and {m!r} does not exist"
|
msg = f"mod inverse of {a!r} and {m!r} does not exist"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
u1, u2, u3 = 1, 0, a
|
u1, u2, u3 = 1, 0, a
|
||||||
|
|
|
@ -39,19 +39,7 @@ import string
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
|
from maths.greatest_common_divisor import greatest_common_divisor
|
||||||
def greatest_common_divisor(a: int, b: int) -> int:
|
|
||||||
"""
|
|
||||||
>>> greatest_common_divisor(4, 8)
|
|
||||||
4
|
|
||||||
>>> greatest_common_divisor(8, 4)
|
|
||||||
4
|
|
||||||
>>> greatest_common_divisor(4, 7)
|
|
||||||
1
|
|
||||||
>>> greatest_common_divisor(0, 10)
|
|
||||||
10
|
|
||||||
"""
|
|
||||||
return b if a == 0 else greatest_common_divisor(b % a, a)
|
|
||||||
|
|
||||||
|
|
||||||
class HillCipher:
|
class HillCipher:
|
||||||
|
|
|
@ -2,6 +2,8 @@ import os
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from maths.greatest_common_divisor import gcd_by_iterative
|
||||||
|
|
||||||
from . import cryptomath_module, rabin_miller
|
from . import cryptomath_module, rabin_miller
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ def generate_key(key_size: int) -> tuple[tuple[int, int], tuple[int, int]]:
|
||||||
# Generate e that is relatively prime to (p - 1) * (q - 1)
|
# Generate e that is relatively prime to (p - 1) * (q - 1)
|
||||||
while True:
|
while True:
|
||||||
e = random.randrange(2 ** (key_size - 1), 2 ** (key_size))
|
e = random.randrange(2 ** (key_size - 1), 2 ** (key_size))
|
||||||
if cryptomath_module.gcd(e, (p - 1) * (q - 1)) == 1:
|
if gcd_by_iterative(e, (p - 1) * (q - 1)) == 1:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate d that is mod inverse of e
|
# Calculate d that is mod inverse of e
|
||||||
|
|
|
@ -10,14 +10,7 @@ satisfies the following modular arithmetic condition:
|
||||||
Examples of Carmichael Numbers: 561, 1105, ...
|
Examples of Carmichael Numbers: 561, 1105, ...
|
||||||
https://en.wikipedia.org/wiki/Carmichael_number
|
https://en.wikipedia.org/wiki/Carmichael_number
|
||||||
"""
|
"""
|
||||||
|
from maths.greatest_common_divisor import greatest_common_divisor
|
||||||
|
|
||||||
def gcd(a: int, b: int) -> int:
|
|
||||||
if a < b:
|
|
||||||
return gcd(b, a)
|
|
||||||
if a % b == 0:
|
|
||||||
return b
|
|
||||||
return gcd(b, a % b)
|
|
||||||
|
|
||||||
|
|
||||||
def power(x: int, y: int, mod: int) -> int:
|
def power(x: int, y: int, mod: int) -> int:
|
||||||
|
@ -33,7 +26,7 @@ def power(x: int, y: int, mod: int) -> int:
|
||||||
def is_carmichael_number(n: int) -> bool:
|
def is_carmichael_number(n: int) -> bool:
|
||||||
b = 2
|
b = 2
|
||||||
while b < n:
|
while b < n:
|
||||||
if gcd(b, n) == 1 and power(b, n - 1, n) != 1:
|
if greatest_common_divisor(b, n) == 1 and power(b, n - 1, n) != 1:
|
||||||
return False
|
return False
|
||||||
b += 1
|
b += 1
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import unittest
|
import unittest
|
||||||
from timeit import timeit
|
from timeit import timeit
|
||||||
|
|
||||||
|
from maths.greatest_common_divisor import greatest_common_divisor
|
||||||
|
|
||||||
|
|
||||||
def least_common_multiple_slow(first_num: int, second_num: int) -> int:
|
def least_common_multiple_slow(first_num: int, second_num: int) -> int:
|
||||||
"""
|
"""
|
||||||
|
@ -20,26 +22,6 @@ def least_common_multiple_slow(first_num: int, second_num: int) -> int:
|
||||||
return common_mult
|
return common_mult
|
||||||
|
|
||||||
|
|
||||||
def greatest_common_divisor(a: int, b: int) -> int:
|
|
||||||
"""
|
|
||||||
Calculate Greatest Common Divisor (GCD).
|
|
||||||
see greatest_common_divisor.py
|
|
||||||
>>> greatest_common_divisor(24, 40)
|
|
||||||
8
|
|
||||||
>>> greatest_common_divisor(1, 1)
|
|
||||||
1
|
|
||||||
>>> greatest_common_divisor(1, 800)
|
|
||||||
1
|
|
||||||
>>> greatest_common_divisor(11, 37)
|
|
||||||
1
|
|
||||||
>>> greatest_common_divisor(3, 5)
|
|
||||||
1
|
|
||||||
>>> greatest_common_divisor(16, 4)
|
|
||||||
4
|
|
||||||
"""
|
|
||||||
return b if a == 0 else greatest_common_divisor(b % a, a)
|
|
||||||
|
|
||||||
|
|
||||||
def least_common_multiple_fast(first_num: int, second_num: int) -> int:
|
def least_common_multiple_fast(first_num: int, second_num: int) -> int:
|
||||||
"""
|
"""
|
||||||
Find the least common multiple of two numbers.
|
Find the least common multiple of two numbers.
|
||||||
|
|
|
@ -21,7 +21,6 @@ get_primes_between(pNumber1, pNumber2)
|
||||||
|
|
||||||
is_even(number)
|
is_even(number)
|
||||||
is_odd(number)
|
is_odd(number)
|
||||||
gcd(number1, number2) // greatest common divisor
|
|
||||||
kg_v(number1, number2) // least common multiple
|
kg_v(number1, number2) // least common multiple
|
||||||
get_divisors(number) // all divisors of 'number' inclusive 1, number
|
get_divisors(number) // all divisors of 'number' inclusive 1, number
|
||||||
is_perfect_number(number)
|
is_perfect_number(number)
|
||||||
|
@ -40,6 +39,8 @@ goldbach(number) // Goldbach's assumption
|
||||||
|
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
|
from maths.greatest_common_divisor import gcd_by_iterative
|
||||||
|
|
||||||
|
|
||||||
def is_prime(number: int) -> bool:
|
def is_prime(number: int) -> bool:
|
||||||
"""
|
"""
|
||||||
|
@ -317,39 +318,6 @@ def goldbach(number):
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
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 kg_v(number1, number2):
|
def kg_v(number1, number2):
|
||||||
"""
|
"""
|
||||||
Least common multiple
|
Least common multiple
|
||||||
|
@ -567,14 +535,14 @@ def simplify_fraction(numerator, denominator):
|
||||||
), "The arguments must been from type int and 'denominator' != 0"
|
), "The arguments must been from type int and 'denominator' != 0"
|
||||||
|
|
||||||
# build the greatest common divisor of numerator and denominator.
|
# build the greatest common divisor of numerator and denominator.
|
||||||
gcd_of_fraction = gcd(abs(numerator), abs(denominator))
|
gcd_of_fraction = gcd_by_iterative(abs(numerator), abs(denominator))
|
||||||
|
|
||||||
# precondition
|
# precondition
|
||||||
assert (
|
assert (
|
||||||
isinstance(gcd_of_fraction, int)
|
isinstance(gcd_of_fraction, int)
|
||||||
and (numerator % gcd_of_fraction == 0)
|
and (numerator % gcd_of_fraction == 0)
|
||||||
and (denominator % gcd_of_fraction == 0)
|
and (denominator % gcd_of_fraction == 0)
|
||||||
), "Error in function gcd(...,...)"
|
), "Error in function gcd_by_iterative(...,...)"
|
||||||
|
|
||||||
return (numerator // gcd_of_fraction, denominator // gcd_of_fraction)
|
return (numerator // gcd_of_fraction, denominator // gcd_of_fraction)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from maths.greatest_common_divisor import greatest_common_divisor
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Project Euler Problem 5: https://projecteuler.net/problem=5
|
Project Euler Problem 5: https://projecteuler.net/problem=5
|
||||||
|
|
||||||
|
@ -16,23 +18,6 @@ References:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def greatest_common_divisor(x: int, y: int) -> int:
|
|
||||||
"""
|
|
||||||
Euclidean Greatest Common Divisor algorithm
|
|
||||||
|
|
||||||
>>> greatest_common_divisor(0, 0)
|
|
||||||
0
|
|
||||||
>>> greatest_common_divisor(23, 42)
|
|
||||||
1
|
|
||||||
>>> greatest_common_divisor(15, 33)
|
|
||||||
3
|
|
||||||
>>> greatest_common_divisor(12345, 67890)
|
|
||||||
15
|
|
||||||
"""
|
|
||||||
|
|
||||||
return x if y == 0 else greatest_common_divisor(y, x % y)
|
|
||||||
|
|
||||||
|
|
||||||
def lcm(x: int, y: int) -> int:
|
def lcm(x: int, y: int) -> int:
|
||||||
"""
|
"""
|
||||||
Least Common Multiple.
|
Least Common Multiple.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user