From 95a894e53f9b7ae62aa439a413e552ed4684877a Mon Sep 17 00:00:00 2001 From: dudaodong Date: Tue, 19 Nov 2024 10:12:07 +0800 Subject: [PATCH] feat: add Permutation and Combination --- mathutil/mathutil.go | 44 +++++++++++++++++++++++++---- mathutil/mathutil_exmaple_test.go | 24 ++++++++++++++++ mathutil/mathutil_test.go | 46 +++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 6 deletions(-) diff --git a/mathutil/mathutil.go b/mathutil/mathutil.go index 0f4c2d7..148d3f3 100644 --- a/mathutil/mathutil.go +++ b/mathutil/mathutil.go @@ -44,14 +44,19 @@ func Fibonacci(first, second, n int) int { } } -// Factorial calculate x!. +// Factorial calculate n!. // Play: https://go.dev/play/p/tt6LdOK67Nx -func Factorial(x uint) uint { - var f uint = 1 - for ; x > 1; x-- { - f *= x +func Factorial(n uint) uint { + if n == 0 || n == 1 { + return 1 } - return f + + result := uint(1) + for i := uint(2); i <= n; i++ { + result *= i + } + + return result } // Percent calculate the percentage of value to total. @@ -417,3 +422,30 @@ func Variance[T constraints.Float | constraints.Integer](numbers []T) float64 { func StdDev[T constraints.Float | constraints.Integer](numbers []T) float64 { return math.Sqrt(Variance(numbers)) } + +// Permutation calculate P(n, k). +// Play: todo +func Permutation(n, k uint) uint { + if n < k { + return 0 + } + + nFactorial := Factorial(n) + nMinusKFactorial := Factorial(n - k) + + return nFactorial / nMinusKFactorial +} + +// Combination calculate C(n, k). +// Play: todo +func Combination(n, k uint) uint { + if n < k { + return 0 + } + + nFactorial := Factorial(n) + kFactorial := Factorial(k) + nMinusKFactorial := Factorial(n - k) + + return nFactorial / (kFactorial * nMinusKFactorial) +} diff --git a/mathutil/mathutil_exmaple_test.go b/mathutil/mathutil_exmaple_test.go index 1408aab..ed840ac 100644 --- a/mathutil/mathutil_exmaple_test.go +++ b/mathutil/mathutil_exmaple_test.go @@ -502,3 +502,27 @@ func ExampleStdDev() { // 1.41 // 1.55 } + +func ExamplePermutation() { + result1 := Permutation(5, 3) + result2 := Permutation(5, 5) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 60 + // 120 +} + +func ExampleCombination() { + result1 := Combination(5, 3) + result2 := Combination(5, 5) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1 +} diff --git a/mathutil/mathutil_test.go b/mathutil/mathutil_test.go index b79fb24..0252490 100644 --- a/mathutil/mathutil_test.go +++ b/mathutil/mathutil_test.go @@ -491,3 +491,49 @@ func TestStdDev(t *testing.T) { assert.Equal(tt.expected, TruncRound(StdDev(tt.numbers), 3)) } } + +func TestPermutation(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestPermutation") + + tests := []struct { + n uint + k uint + expected uint + }{ + {1, 1, 1}, + {1, 0, 1}, + {0, 1, 0}, + {0, 0, 1}, + {3, 2, 6}, + {4, 2, 12}, + } + + for _, tt := range tests { + assert.Equal(tt.expected, Permutation(tt.n, tt.k)) + } +} + +func TestCombination(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestCombination") + + tests := []struct { + n uint + k uint + expected uint + }{ + {1, 1, 1}, + {1, 0, 1}, + {0, 1, 0}, + {0, 0, 1}, + {3, 2, 3}, + {4, 2, 6}, + } + + for _, tt := range tests { + assert.Equal(tt.expected, Combination(tt.n, tt.k)) + } +}