diff --git a/math/liouville.go b/math/liouville.go new file mode 100644 index 000000000..908a4deac --- /dev/null +++ b/math/liouville.go @@ -0,0 +1,35 @@ +// liouville.go +// description: Returns λ(n) +// details: +// For any positive integer n, define λ(n) as the sum of the primitive nth roots of unity. +// It has values in {−1, 1} depending on the factorization of n into prime factors: +// λ(n) = +1 if n is a positive integer with an even number of prime factors. +// λ(n) = −1 if n is a positive integer with an odd number of prime factors. +// wikipedia: https://en.wikipedia.org/wiki/Liouville_function +// author: Akshay Dubey (https://github.com/itsAkshayDubey) +// see liouville_test.go + +package math + +import ( + "errors" + + "github.com/TheAlgorithms/Go/math/prime" +) + +var ErrNonZeroArgsOnly error = errors.New("arguments cannot be zero") + +// Lambda is the liouville function +// This function returns λ(n) for given number +func LiouvilleLambda(n int) (int, error) { + switch { + case n < 0: + return 0, ErrPosArgsOnly + case n == 0: + return 0, ErrNonZeroArgsOnly + case len(prime.Factorize(int64(n)))%2 == 0: + return 1, nil + default: + return -1, nil + } +} diff --git a/math/liouville_test.go b/math/liouville_test.go new file mode 100644 index 000000000..41d327c3e --- /dev/null +++ b/math/liouville_test.go @@ -0,0 +1,39 @@ +// liouville_test.go +// description: Returns λ(n) +// author: Akshay Dubey (https://github.com/itsAkshayDubey) +// see liouville.go + +package math_test + +import ( + "testing" + + "github.com/TheAlgorithms/Go/math" +) + +func TestLiouvilleLambda(t *testing.T) { + var tests = []struct { + name string + n int + expectedValue int + expectedError error + }{ + {"n = 10", 10, 1, nil}, + {"n = 11", 11, -1, nil}, + {"n = -1", -1, 0, math.ErrPosArgsOnly}, + {"n = 0", 0, 0, math.ErrNonZeroArgsOnly}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result, err := math.LiouvilleLambda(test.n) + if result != test.expectedValue || test.expectedError != err { + t.Errorf("expected error: %s, got: %s; expected value: %v, got: %v", test.expectedError, err, test.expectedValue, result) + } + }) + } +} +func BenchmarkLiouvilleLambda(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = math.LiouvilleLambda(65536) + } +}