Skip to content

Commit 583a614

Browse files
Siddikpatelpre-commit-ci[bot]tianyizheng02
authoredOct 9, 2023
Removed redundant greatest_common_divisor code (TheAlgorithms#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 <[email protected]>
1 parent 876087b commit 583a614

9 files changed

+24
-131
lines changed
 

‎blockchain/diophantine_equation.py

+4-28
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from __future__ import annotations
22

3+
from maths.greatest_common_divisor import greatest_common_divisor
4+
35

46
def diophantine(a: int, b: int, c: int) -> tuple[float, float]:
57
"""
68
Diophantine Equation : Given integers a,b,c ( at least one of a and b != 0), the
79
diophantine equation a*x + b*y = c has a solution (where x and y are integers)
8-
iff gcd(a,b) divides c.
10+
iff greatest_common_divisor(a,b) divides c.
911
1012
GCD ( Greatest Common Divisor ) or HCF ( Highest Common Factor )
1113
@@ -22,7 +24,7 @@ def diophantine(a: int, b: int, c: int) -> tuple[float, float]:
2224

2325
assert (
2426
c % greatest_common_divisor(a, b) == 0
25-
) # greatest_common_divisor(a,b) function implemented below
27+
) # greatest_common_divisor(a,b) is in maths directory
2628
(d, x, y) = extended_gcd(a, b) # extended_gcd(a,b) function implemented below
2729
r = c / d
2830
return (r * x, r * y)
@@ -69,32 +71,6 @@ def diophantine_all_soln(a: int, b: int, c: int, n: int = 2) -> None:
6971
print(x, y)
7072

7173

72-
def greatest_common_divisor(a: int, b: int) -> int:
73-
"""
74-
Euclid's Lemma : d divides a and b, if and only if d divides a-b and b
75-
76-
Euclid's Algorithm
77-
78-
>>> greatest_common_divisor(7,5)
79-
1
80-
81-
Note : In number theory, two integers a and b are said to be relatively prime,
82-
mutually prime, or co-prime if the only positive integer (factor) that
83-
divides both of them is 1 i.e., gcd(a,b) = 1.
84-
85-
>>> greatest_common_divisor(121, 11)
86-
11
87-
88-
"""
89-
if a < b:
90-
a, b = b, a
91-
92-
while a % b != 0:
93-
a, b = b, a % b
94-
95-
return b
96-
97-
9874
def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
9975
"""
10076
Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers

‎ciphers/affine_cipher.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import random
22
import sys
33

4+
from maths.greatest_common_divisor import gcd_by_iterative
5+
46
from . import cryptomath_module as cryptomath
57

68
SYMBOLS = (
@@ -26,7 +28,7 @@ def check_keys(key_a: int, key_b: int, mode: str) -> None:
2628
"Key A must be greater than 0 and key B must "
2729
f"be between 0 and {len(SYMBOLS) - 1}."
2830
)
29-
if cryptomath.gcd(key_a, len(SYMBOLS)) != 1:
31+
if gcd_by_iterative(key_a, len(SYMBOLS)) != 1:
3032
sys.exit(
3133
f"Key A {key_a} and the symbol set size {len(SYMBOLS)} "
3234
"are not relatively prime. Choose a different key."
@@ -76,7 +78,7 @@ def get_random_key() -> int:
7678
while True:
7779
key_b = random.randint(2, len(SYMBOLS))
7880
key_b = random.randint(2, len(SYMBOLS))
79-
if cryptomath.gcd(key_b, len(SYMBOLS)) == 1 and key_b % len(SYMBOLS) != 0:
81+
if gcd_by_iterative(key_b, len(SYMBOLS)) == 1 and key_b % len(SYMBOLS) != 0:
8082
return key_b * len(SYMBOLS) + key_b
8183

8284

‎ciphers/cryptomath_module.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
def gcd(a: int, b: int) -> int:
2-
while a != 0:
3-
a, b = b % a, a
4-
return b
1+
from maths.greatest_common_divisor import gcd_by_iterative
52

63

74
def find_mod_inverse(a: int, m: int) -> int:
8-
if gcd(a, m) != 1:
5+
if gcd_by_iterative(a, m) != 1:
96
msg = f"mod inverse of {a!r} and {m!r} does not exist"
107
raise ValueError(msg)
118
u1, u2, u3 = 1, 0, a

‎ciphers/hill_cipher.py

+1-13
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,7 @@
3939

4040
import numpy
4141

42-
43-
def greatest_common_divisor(a: int, b: int) -> int:
44-
"""
45-
>>> greatest_common_divisor(4, 8)
46-
4
47-
>>> greatest_common_divisor(8, 4)
48-
4
49-
>>> greatest_common_divisor(4, 7)
50-
1
51-
>>> greatest_common_divisor(0, 10)
52-
10
53-
"""
54-
return b if a == 0 else greatest_common_divisor(b % a, a)
42+
from maths.greatest_common_divisor import greatest_common_divisor
5543

5644

5745
class HillCipher:

‎ciphers/rsa_key_generator.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import random
33
import sys
44

5+
from maths.greatest_common_divisor import gcd_by_iterative
6+
57
from . import cryptomath_module, rabin_miller
68

79

@@ -27,7 +29,7 @@ def generate_key(key_size: int) -> tuple[tuple[int, int], tuple[int, int]]:
2729
# Generate e that is relatively prime to (p - 1) * (q - 1)
2830
while True:
2931
e = random.randrange(2 ** (key_size - 1), 2 ** (key_size))
30-
if cryptomath_module.gcd(e, (p - 1) * (q - 1)) == 1:
32+
if gcd_by_iterative(e, (p - 1) * (q - 1)) == 1:
3133
break
3234

3335
# Calculate d that is mod inverse of e

‎maths/carmichael_number.py

+2-9
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,7 @@
1010
Examples of Carmichael Numbers: 561, 1105, ...
1111
https://en.wikipedia.org/wiki/Carmichael_number
1212
"""
13-
14-
15-
def gcd(a: int, b: int) -> int:
16-
if a < b:
17-
return gcd(b, a)
18-
if a % b == 0:
19-
return b
20-
return gcd(b, a % b)
13+
from maths.greatest_common_divisor import greatest_common_divisor
2114

2215

2316
def power(x: int, y: int, mod: int) -> int:
@@ -33,7 +26,7 @@ def power(x: int, y: int, mod: int) -> int:
3326
def is_carmichael_number(n: int) -> bool:
3427
b = 2
3528
while b < n:
36-
if gcd(b, n) == 1 and power(b, n - 1, n) != 1:
29+
if greatest_common_divisor(b, n) == 1 and power(b, n - 1, n) != 1:
3730
return False
3831
b += 1
3932
return True

‎maths/least_common_multiple.py

+2-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import unittest
22
from timeit import timeit
33

4+
from maths.greatest_common_divisor import greatest_common_divisor
5+
46

57
def least_common_multiple_slow(first_num: int, second_num: int) -> int:
68
"""
@@ -20,26 +22,6 @@ def least_common_multiple_slow(first_num: int, second_num: int) -> int:
2022
return common_mult
2123

2224

23-
def greatest_common_divisor(a: int, b: int) -> int:
24-
"""
25-
Calculate Greatest Common Divisor (GCD).
26-
see greatest_common_divisor.py
27-
>>> greatest_common_divisor(24, 40)
28-
8
29-
>>> greatest_common_divisor(1, 1)
30-
1
31-
>>> greatest_common_divisor(1, 800)
32-
1
33-
>>> greatest_common_divisor(11, 37)
34-
1
35-
>>> greatest_common_divisor(3, 5)
36-
1
37-
>>> greatest_common_divisor(16, 4)
38-
4
39-
"""
40-
return b if a == 0 else greatest_common_divisor(b % a, a)
41-
42-
4325
def least_common_multiple_fast(first_num: int, second_num: int) -> int:
4426
"""
4527
Find the least common multiple of two numbers.

‎maths/primelib.py

+4-36
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
2222
is_even(number)
2323
is_odd(number)
24-
gcd(number1, number2) // greatest common divisor
2524
kg_v(number1, number2) // least common multiple
2625
get_divisors(number) // all divisors of 'number' inclusive 1, number
2726
is_perfect_number(number)
@@ -40,6 +39,8 @@
4039

4140
from math import sqrt
4241

42+
from maths.greatest_common_divisor import gcd_by_iterative
43+
4344

4445
def is_prime(number: int) -> bool:
4546
"""
@@ -317,39 +318,6 @@ def goldbach(number):
317318
# ----------------------------------------------
318319

319320

320-
def gcd(number1, number2):
321-
"""
322-
Greatest common divisor
323-
input: two positive integer 'number1' and 'number2'
324-
returns the greatest common divisor of 'number1' and 'number2'
325-
"""
326-
327-
# precondition
328-
assert (
329-
isinstance(number1, int)
330-
and isinstance(number2, int)
331-
and (number1 >= 0)
332-
and (number2 >= 0)
333-
), "'number1' and 'number2' must been positive integer."
334-
335-
rest = 0
336-
337-
while number2 != 0:
338-
rest = number1 % number2
339-
number1 = number2
340-
number2 = rest
341-
342-
# precondition
343-
assert isinstance(number1, int) and (
344-
number1 >= 0
345-
), "'number' must been from type int and positive"
346-
347-
return number1
348-
349-
350-
# ----------------------------------------------------
351-
352-
353321
def kg_v(number1, number2):
354322
"""
355323
Least common multiple
@@ -567,14 +535,14 @@ def simplify_fraction(numerator, denominator):
567535
), "The arguments must been from type int and 'denominator' != 0"
568536

569537
# build the greatest common divisor of numerator and denominator.
570-
gcd_of_fraction = gcd(abs(numerator), abs(denominator))
538+
gcd_of_fraction = gcd_by_iterative(abs(numerator), abs(denominator))
571539

572540
# precondition
573541
assert (
574542
isinstance(gcd_of_fraction, int)
575543
and (numerator % gcd_of_fraction == 0)
576544
and (denominator % gcd_of_fraction == 0)
577-
), "Error in function gcd(...,...)"
545+
), "Error in function gcd_by_iterative(...,...)"
578546

579547
return (numerator // gcd_of_fraction, denominator // gcd_of_fraction)
580548

‎project_euler/problem_005/sol2.py

+2-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from maths.greatest_common_divisor import greatest_common_divisor
2+
13
"""
24
Project Euler Problem 5: https://projecteuler.net/problem=5
35
@@ -16,23 +18,6 @@
1618
"""
1719

1820

19-
def greatest_common_divisor(x: int, y: int) -> int:
20-
"""
21-
Euclidean Greatest Common Divisor algorithm
22-
23-
>>> greatest_common_divisor(0, 0)
24-
0
25-
>>> greatest_common_divisor(23, 42)
26-
1
27-
>>> greatest_common_divisor(15, 33)
28-
3
29-
>>> greatest_common_divisor(12345, 67890)
30-
15
31-
"""
32-
33-
return x if y == 0 else greatest_common_divisor(y, x % y)
34-
35-
3621
def lcm(x: int, y: int) -> int:
3722
"""
3823
Least Common Multiple.

0 commit comments

Comments
 (0)
Please sign in to comment.