From a6831c898a12e568c2e611d457dd71bd89488ce2 Mon Sep 17 00:00:00 2001 From: Joyce Date: Thu, 29 Oct 2020 00:17:26 -0700 Subject: [PATCH] math/greatest_common_divisor: add support for negative numbers (#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 --- maths/greatest_common_divisor.py | 39 ++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/maths/greatest_common_divisor.py b/maths/greatest_common_divisor.py index 0926ade5d..a2174a8eb 100644 --- a/maths/greatest_common_divisor.py +++ b/maths/greatest_common_divisor.py @@ -2,10 +2,12 @@ Greatest Common Divisor. Wikipedia reference: https://en.wikipedia.org/wiki/Greatest_common_divisor + +gcd(a, b) = gcd(a, -b) = gcd(-a, b) = gcd(-a, -b) by definition of divisibility """ -def greatest_common_divisor(a, b): +def greatest_common_divisor(a: int, b: int) -> int: """ Calculate Greatest Common Divisor (GCD). >>> greatest_common_divisor(24, 40) @@ -20,31 +22,44 @@ def greatest_common_divisor(a, b): 1 >>> greatest_common_divisor(16, 4) 4 + >>> greatest_common_divisor(-3, 9) + 3 + >>> greatest_common_divisor(9, -3) + 3 + >>> greatest_common_divisor(3, -9) + 3 + >>> greatest_common_divisor(-3, -9) + 3 """ - return b if a == 0 else greatest_common_divisor(b % a, a) + return abs(b) if a == 0 else greatest_common_divisor(b % a, a) -""" -Below method is more memory efficient because it does not use the stack (chunk of -memory). While above method is good, uses more memory for huge numbers because of the -recursive calls required to calculate the greatest common divisor. -""" - - -def gcd_by_iterative(x, y): +def gcd_by_iterative(x: int, y: int) -> int: """ + Below method is more memory efficient because it does not create additional + stack frames for recursive functions calls (as done in the above method). >>> gcd_by_iterative(24, 40) 8 >>> greatest_common_divisor(24, 40) == gcd_by_iterative(24, 40) True + >>> gcd_by_iterative(-3, -9) + 3 + >>> gcd_by_iterative(3, -9) + 3 + >>> gcd_by_iterative(1, -800) + 1 + >>> gcd_by_iterative(11, 37) + 1 """ while y: # --> when y=0 then loop will terminate and return x as final GCD. x, y = y, x % y - return x + return abs(x) def main(): - """Call Greatest Common Divisor function.""" + """ + Call Greatest Common Divisor function. + """ try: nums = input("Enter two integers separated by comma (,): ").split(",") num_1 = int(nums[0])