Skip to content

Commit 448143a

Browse files
committed
Fix: improve GCD function with documentation and better test cases
1 parent cd3c3c3 commit 448143a

File tree

1 file changed

+162
-39
lines changed

1 file changed

+162
-39
lines changed

maths/greatest_common_divisor.py

Lines changed: 162 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,171 @@
11
"""
22
Greatest Common Divisor.
3-
43
Wikipedia reference: https://en.wikipedia.org/wiki/Greatest_common_divisor
5-
64
gcd(a, b) = gcd(a, -b) = gcd(-a, b) = gcd(-a, -b) by definition of divisibility
75
"""
86

97

108
def greatest_common_divisor(a: int, b: int) -> int:
119
"""
12-
Calculate Greatest Common Divisor (GCD).
13-
>>> greatest_common_divisor(24, 40)
14-
8
15-
>>> greatest_common_divisor(1, 1)
16-
1
17-
>>> greatest_common_divisor(1, 800)
18-
1
19-
>>> greatest_common_divisor(11, 37)
20-
1
21-
>>> greatest_common_divisor(3, 5)
22-
1
23-
>>> greatest_common_divisor(16, 4)
24-
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
10+
Calculate Greatest Common Divisor (GCD) using Euclidean algorithm recursively.
11+
12+
The GCD of two integers is the largest positive integer that divides both numbers.
13+
14+
Args:
15+
a: First integer
16+
b: Second integer
17+
18+
Returns:
19+
The greatest common divisor of a and b
20+
21+
Examples:
22+
Basic cases:
23+
>>> greatest_common_divisor(24, 40)
24+
8
25+
>>> greatest_common_divisor(48, 18)
26+
6
27+
>>> greatest_common_divisor(100, 25)
28+
25
29+
>>> greatest_common_divisor(17, 19)
30+
1
31+
32+
Edge cases with small numbers:
33+
>>> greatest_common_divisor(1, 1)
34+
1
35+
>>> greatest_common_divisor(1, 800)
36+
1
37+
>>> greatest_common_divisor(11, 37)
38+
1
39+
>>> greatest_common_divisor(3, 5)
40+
1
41+
>>> greatest_common_divisor(16, 4)
42+
4
43+
44+
Cases with zero:
45+
>>> greatest_common_divisor(0, 5)
46+
5
47+
>>> greatest_common_divisor(5, 0)
48+
5
49+
>>> greatest_common_divisor(0, 0)
50+
0
51+
52+
Negative numbers:
53+
>>> greatest_common_divisor(-3, 9)
54+
3
55+
>>> greatest_common_divisor(9, -3)
56+
3
57+
>>> greatest_common_divisor(3, -9)
58+
3
59+
>>> greatest_common_divisor(-3, -9)
60+
3
61+
>>> greatest_common_divisor(-24, -40)
62+
8
63+
>>> greatest_common_divisor(-48, 18)
64+
6
65+
66+
Large numbers:
67+
>>> greatest_common_divisor(1071, 462)
68+
21
69+
>>> greatest_common_divisor(12345, 54321)
70+
3
71+
72+
Same numbers:
73+
>>> greatest_common_divisor(42, 42)
74+
42
75+
>>> greatest_common_divisor(-15, -15)
76+
15
77+
78+
One divides the other:
79+
>>> greatest_common_divisor(15, 45)
80+
15
81+
>>> greatest_common_divisor(7, 49)
82+
7
3383
"""
3484
return abs(b) if a == 0 else greatest_common_divisor(b % a, a)
3585

3686

3787
def gcd_by_iterative(x: int, y: int) -> int:
3888
"""
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).
41-
>>> gcd_by_iterative(24, 40)
42-
8
43-
>>> greatest_common_divisor(24, 40) == gcd_by_iterative(24, 40)
44-
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
89+
Calculate Greatest Common Divisor (GCD) using iterative Euclidean algorithm.
90+
91+
This method is more memory efficient because it does not create additional
92+
stack frames for recursive function calls.
93+
94+
Args:
95+
x: First integer
96+
y: Second integer
97+
98+
Returns:
99+
The greatest common divisor of x and y
100+
101+
Examples:
102+
Basic cases:
103+
>>> gcd_by_iterative(24, 40)
104+
8
105+
>>> gcd_by_iterative(48, 18)
106+
6
107+
>>> gcd_by_iterative(100, 25)
108+
25
109+
>>> gcd_by_iterative(17, 19)
110+
1
111+
112+
Verify equivalence with recursive version:
113+
>>> greatest_common_divisor(24, 40) == gcd_by_iterative(24, 40)
114+
True
115+
>>> greatest_common_divisor(48, 18) == gcd_by_iterative(48, 18)
116+
True
117+
>>> greatest_common_divisor(100, 25) == gcd_by_iterative(100, 25)
118+
True
119+
120+
Edge cases with small numbers:
121+
>>> gcd_by_iterative(1, 1)
122+
1
123+
>>> gcd_by_iterative(1, 800)
124+
1
125+
>>> gcd_by_iterative(11, 37)
126+
1
127+
>>> gcd_by_iterative(16, 4)
128+
4
129+
130+
Cases with zero:
131+
>>> gcd_by_iterative(0, 5)
132+
5
133+
>>> gcd_by_iterative(5, 0)
134+
5
135+
>>> gcd_by_iterative(0, 0)
136+
0
137+
138+
Negative numbers:
139+
>>> gcd_by_iterative(-3, -9)
140+
3
141+
>>> gcd_by_iterative(3, -9)
142+
3
143+
>>> gcd_by_iterative(-3, 9)
144+
3
145+
>>> gcd_by_iterative(1, -800)
146+
1
147+
>>> gcd_by_iterative(-24, -40)
148+
8
149+
>>> gcd_by_iterative(-48, 18)
150+
6
151+
152+
Large numbers:
153+
>>> gcd_by_iterative(1071, 462)
154+
21
155+
>>> gcd_by_iterative(12345, 54321)
156+
3
157+
158+
Same numbers:
159+
>>> gcd_by_iterative(42, 42)
160+
42
161+
>>> gcd_by_iterative(-15, -15)
162+
15
163+
164+
One divides the other:
165+
>>> gcd_by_iterative(15, 45)
166+
15
167+
>>> gcd_by_iterative(7, 49)
168+
7
53169
"""
54170
while y: # --> when y=0 then loop will terminate and return x as final GCD.
55171
x, y = y, x % y
@@ -58,7 +174,14 @@ def gcd_by_iterative(x: int, y: int) -> int:
58174

59175
def main():
60176
"""
61-
Call Greatest Common Divisor function.
177+
Call Greatest Common Divisor function with user input.
178+
179+
Prompts user for two integers separated by comma and calculates their GCD
180+
using both recursive and iterative methods.
181+
182+
Examples:
183+
This function handles user input, so direct doctests aren't practical.
184+
However, it should handle valid input like "24,40" and invalid input gracefully.
62185
"""
63186
try:
64187
nums = input("Enter two integers separated by comma (,): ").split(",")
@@ -74,4 +197,4 @@ def main():
74197

75198

76199
if __name__ == "__main__":
77-
main()
200+
main()

0 commit comments

Comments
 (0)