From 654ba15aaffd4e8610fdc0aeb1cd4c1a61b81b3c Mon Sep 17 00:00:00 2001 From: dudaodong Date: Sat, 6 May 2023 11:02:00 +0800 Subject: [PATCH] feat: add GCD and LCM function --- mathutil/mathutil.go | 42 +++++++++++++++++++++++++++++++++++++++ mathutil/mathutil_test.go | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/mathutil/mathutil.go b/mathutil/mathutil.go index c97967c..d76303b 100644 --- a/mathutil/mathutil.go +++ b/mathutil/mathutil.go @@ -256,3 +256,45 @@ func IsPrime(n int) bool { return true } + +// GCD return greatest common divisor (GCD) of integers. +// Play: todo +func GCD[T constraints.Integer](integers ...T) T { + result := integers[0] + + for k := range integers { + result = gcd(integers[k], result) + + if result == 1 { + return 1 + } + } + + return result +} + +// find greatest common divisor (GCD) +func gcd[T constraints.Integer](a, b T) T { + if b == 0 { + return a + } + + return gcd(b, a%b) +} + +// LCM return Least Common Multiple (LCM) of integers. +// Play: todo +func LCM[T constraints.Integer](integers ...T) T { + result := integers[0] + + for i := 1; i < len(integers)-1; i++ { + result = lcm(result, integers[i]) + } + + return result +} + +// find Least Common Multiple (LCM) via GCD. +func lcm[T constraints.Integer](a, b T) T { + return a * b / gcd(a, b) +} diff --git a/mathutil/mathutil_test.go b/mathutil/mathutil_test.go index 62bc390..319015f 100644 --- a/mathutil/mathutil_test.go +++ b/mathutil/mathutil_test.go @@ -210,3 +210,41 @@ func TestIsPrime(t *testing.T) { assert.Equal(true, IsPrime(3)) assert.Equal(false, IsPrime(4)) } + +func TestGCD(t *testing.T) { + assert := internal.NewAssert(t, "TestGCD") + + assert.Equal(1, GCD(1, 1)) + assert.Equal(1, GCD(1, -1)) + assert.Equal(-1, GCD(-1, 1)) + assert.Equal(-1, GCD(-1, -1)) + + assert.Equal(1, GCD(1, 0)) + assert.Equal(1, GCD(0, 1)) + assert.Equal(-1, GCD(-1, 0)) + assert.Equal(-1, GCD(0, -1)) + + assert.Equal(1, GCD(1, -2)) + assert.Equal(1, GCD(-2, 1)) + assert.Equal(-1, GCD(-1, 2)) + assert.Equal(-1, GCD(2, -1)) + + assert.Equal(-1, GCD(-1, -2)) + assert.Equal(-1, GCD(-2, -1)) + + assert.Equal(-9, GCD(-27, -36)) + assert.Equal(3, GCD(3, 6, 9)) +} + +func TestLCM(t *testing.T) { + assert := internal.NewAssert(t, "TestLCM") + + assert.Equal(0, LCM(0)) + assert.Equal(1, LCM(1)) + assert.Equal(-1, LCM(-1)) + assert.Equal(0, LCM(0, -1)) + assert.Equal(0, LCM(0, 1)) + assert.Equal(1, LCM(1, 1)) + assert.Equal(1, LCM(1, 2)) + assert.Equal(6, LCM(3, 6, 9)) +}