Skip to content

Commit a50e4a6

Browse files
RY908cclausssiriak
authored
Add extended gcd (TheAlgorithms#307)
Co-authored-by: Christian Clauss <[email protected]> Co-authored-by: Andrii Siriak <[email protected]>
1 parent 2ce0de8 commit a50e4a6

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

math/gcd/extendedgcd.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package gcd
2+
3+
// ExtendedRecursive finds and returns gcd(a, b), x, y satisfying a*x + b*y = gcd(a, b).
4+
func ExtendedRecursive(a, b int64) (int64, int64, int64) {
5+
if b > 0 {
6+
d, y, x := ExtendedRecursive(b, a%b)
7+
y -= (a / b) * x
8+
return d, x, y
9+
}
10+
11+
return a, 1, 0
12+
}

math/gcd/extendedgcd_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package gcd
2+
3+
import "testing"
4+
5+
type testExtendedFunction func(int64, int64) (int64, int64, int64)
6+
7+
var testCasesExtended = []struct {
8+
name string
9+
a int64
10+
b int64
11+
gcd int64
12+
x int64
13+
y int64
14+
}{
15+
{"gcd of 10 and 0", 10, 0, 10, 1, 0},
16+
{"gcd of 98 and 56", 98, 56, 14, -1, 2},
17+
{"gcd of 0 and 10", 0, 10, 10, 0, 1},
18+
}
19+
20+
func TemplateTestExtendedGCD(t *testing.T, f testExtendedFunction) {
21+
for _, tc := range testCasesExtended {
22+
t.Run(tc.name, func(t *testing.T) {
23+
actualGcd, actualX, actualY := f(tc.a, tc.b)
24+
if actualGcd != tc.gcd {
25+
t.Errorf("Expected GCD of %d and %d to be: %v, but got: %d", tc.a, tc.b, tc.gcd, actualGcd)
26+
}
27+
if actualX != tc.x {
28+
t.Errorf("Expected x satisfying %d * x + %d * y = gcd to be: %v, but got: %d", tc.a, tc.b, tc.x, actualX)
29+
}
30+
if actualY != tc.y {
31+
t.Errorf("Expected y satisfying %d * x + %d * y = gcd to be: %v, but got: %d", tc.a, tc.b, tc.y, actualY)
32+
}
33+
})
34+
}
35+
}
36+
37+
func TestExtendedGCDRecursive(t *testing.T) {
38+
TemplateTestExtendedGCD(t, ExtendedRecursive)
39+
}
40+
41+
func TestExtendedGCDIterative(t *testing.T) {
42+
TemplateTestExtendedGCD(t, ExtendedIterative)
43+
}
44+
45+
func TemplateBenchmarkExtendedGCD(b *testing.B, f testExtendedFunction) {
46+
for i := 0; i < b.N; i++ {
47+
f(98, 56)
48+
}
49+
}
50+
51+
func BenchmarkExtendedGCDRecursive(b *testing.B) {
52+
TemplateBenchmarkExtendedGCD(b, ExtendedRecursive)
53+
}
54+
55+
func BenchmarkExtendedGCDIterative(b *testing.B) {
56+
TemplateBenchmarkExtendedGCD(b, ExtendedIterative)
57+
}

math/gcd/extendedgcditerative.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package gcd
2+
3+
// ExtendedIterative finds and returns gcd(a, b), x, y satisfying a*x + b*y = gcd(a, b).
4+
func ExtendedIterative(a, b int64) (int64, int64, int64) {
5+
var u, y, v, x int64 = 1, 1, 0, 0
6+
for a > 0 {
7+
var q int64 = b / a
8+
x, u = u, x-q*u
9+
y, v = v, y-q*v
10+
b, a = a, b-q*a
11+
}
12+
return b, x, y
13+
}

0 commit comments

Comments
 (0)