Skip to content

Commit 8aa82df

Browse files
pikuletstokhos
authored andcommitted
math/greatest_common_divisor: add support for negative numbers (TheAlgorithms#2628)
* add type hints to math/gcd * add doctest * math/gcd - run black formatter * math/gcd: remove manual doctest * add correction to gcd of negative numbers * add more doctest in iterative gcd
1 parent ab40e19 commit 8aa82df

File tree

1 file changed

+27
-12
lines changed

1 file changed

+27
-12
lines changed

Diff for: maths/greatest_common_divisor.py

+27-12
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
Greatest Common Divisor.
33
44
Wikipedia reference: https://en.wikipedia.org/wiki/Greatest_common_divisor
5+
6+
gcd(a, b) = gcd(a, -b) = gcd(-a, b) = gcd(-a, -b) by definition of divisibility
57
"""
68

79

8-
def greatest_common_divisor(a, b):
10+
def greatest_common_divisor(a: int, b: int) -> int:
911
"""
1012
Calculate Greatest Common Divisor (GCD).
1113
>>> greatest_common_divisor(24, 40)
@@ -20,31 +22,44 @@ def greatest_common_divisor(a, b):
2022
1
2123
>>> greatest_common_divisor(16, 4)
2224
4
25+
>>> greatest_common_divisor(-3, 9)
26+
3
27+
>>> greatest_common_divisor(9, -3)
28+
3
29+
>>> greatest_common_divisor(3, -9)
30+
3
31+
>>> greatest_common_divisor(-3, -9)
32+
3
2333
"""
24-
return b if a == 0 else greatest_common_divisor(b % a, a)
25-
26-
27-
"""
28-
Below method is more memory efficient because it does not use the stack (chunk of
29-
memory). While above method is good, uses more memory for huge numbers because of the
30-
recursive calls required to calculate the greatest common divisor.
31-
"""
34+
return abs(b) if a == 0 else greatest_common_divisor(b % a, a)
3235

3336

34-
def gcd_by_iterative(x, y):
37+
def gcd_by_iterative(x: int, y: int) -> int:
3538
"""
39+
Below method is more memory efficient because it does not create additional
40+
stack frames for recursive functions calls (as done in the above method).
3641
>>> gcd_by_iterative(24, 40)
3742
8
3843
>>> greatest_common_divisor(24, 40) == gcd_by_iterative(24, 40)
3944
True
45+
>>> gcd_by_iterative(-3, -9)
46+
3
47+
>>> gcd_by_iterative(3, -9)
48+
3
49+
>>> gcd_by_iterative(1, -800)
50+
1
51+
>>> gcd_by_iterative(11, 37)
52+
1
4053
"""
4154
while y: # --> when y=0 then loop will terminate and return x as final GCD.
4255
x, y = y, x % y
43-
return x
56+
return abs(x)
4457

4558

4659
def main():
47-
"""Call Greatest Common Divisor function."""
60+
"""
61+
Call Greatest Common Divisor function.
62+
"""
4863
try:
4964
nums = input("Enter two integers separated by comma (,): ").split(",")
5065
num_1 = int(nums[0])

0 commit comments

Comments
 (0)