Skip to content

Commit 478b0ac

Browse files
committed
change algorithm for negative numbers
1 parent cea02d9 commit 478b0ac

File tree

1 file changed

+62
-40
lines changed

1 file changed

+62
-40
lines changed

maths/extended_euclidean_algorithm.py

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,42 @@
33
44
Finds 2 numbers a and b such that it satisfies
55
the equation am + bn = gcd(m, n) (a.k.a Bezout's Identity)
6+
7+
https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
68
"""
79

810
# @Author: S. Sharma <silentcat>
911
# @Date: 2019-02-25T12:08:53-06:00
1012
11-
# @Last modified by: PatOnTheBack
12-
# @Last modified time: 2019-07-05
13+
# @Last modified by: pikulet
14+
# @Last modified time: 2020-10-02
1315

1416
import sys
1517

1618

17-
def extended_euclidean_algorithm(m: int, n: int) -> (int, int):
19+
def sign(n: int) -> int:
20+
"""
21+
Returns sign of number for correction of negative numbers in algorithm
22+
23+
>>> sign(4)
24+
1
25+
26+
>>> sign(0)
27+
0
28+
29+
>>> sign(-8)
30+
-1
31+
32+
"""
33+
if n > 0:
34+
return 1
35+
elif n < 0:
36+
return -1
37+
else:
38+
return 0
39+
40+
41+
def extended_euclidean_algorithm(a: int, b: int) -> (int, int):
1842
"""
1943
Extended Euclidean Algorithm.
2044
@@ -26,52 +50,50 @@ def extended_euclidean_algorithm(m: int, n: int) -> (int, int):
2650
2751
>>> extended_euclidean_algorithm(8, 14)
2852
(2, -1)
53+
54+
>>> extended_euclidean_algorithm(240, 46)
55+
(-9, 47)
56+
57+
>>> extended_euclidean_algorithm(1, -4)
58+
(1, 0)
59+
60+
>>> extended_euclidean_algorithm(-2, -4)
61+
(-1, 0)
62+
63+
>>> extended_euclidean_algorithm(0, -4)
64+
(0, -1)
65+
66+
>>> extended_euclidean_algorithm(2, 0)
67+
(1, 0)
68+
2969
"""
30-
a = 0
31-
a_prime = 1
32-
b = 1
33-
b_prime = 0
34-
q = 0
35-
r = 0
36-
if m > n:
37-
c = m
38-
d = n
39-
else:
40-
c = n
41-
d = m
42-
43-
while True:
44-
q = int(c / d)
45-
r = c % d
46-
if r == 0:
47-
break
48-
c = d
49-
d = r
50-
51-
t = a_prime
52-
a_prime = a
53-
a = t - q * a
54-
55-
t = b_prime
56-
b_prime = b
57-
b = t - q * b
58-
59-
pair = None
60-
if m > n:
61-
pair = (a, b)
70+
old_r, r = a, b
71+
old_s, s = 1, 0
72+
old_t, t = 0, 1
73+
74+
while r != 0:
75+
quotient = old_r // r
76+
old_r, r = r, old_r - quotient * r
77+
old_s, s = s, old_s - quotient * s
78+
old_t, t = t, old_t - quotient * t
79+
80+
# sign correction for negative numbers
81+
if abs(a) == 1:
82+
return sign(a), 0
83+
elif abs(b) == 1:
84+
return 0, sign(b)
6285
else:
63-
pair = (b, a)
64-
return pair
86+
return (sign(a) * old_s, sign(b) * old_t)
6587

6688

6789
def main():
6890
"""Call Extended Euclidean Algorithm."""
6991
if len(sys.argv) < 3:
7092
print("2 integer arguments required")
7193
exit(1)
72-
m = int(sys.argv[1])
73-
n = int(sys.argv[2])
74-
print(extended_euclidean_algorithm(m, n))
94+
a = int(sys.argv[1])
95+
b = int(sys.argv[2])
96+
print(extended_euclidean_algorithm(a, b))
7597

7698

7799
if __name__ == "__main__":

0 commit comments

Comments
 (0)