mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-13 17:22:27 +08:00
feat: add Cos, Sin, LCM, GCD function
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -36,6 +37,52 @@ func (a *Assert) Equal(expected, actual interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EqualValues asserts that two objects are equal or convertable to the same types and equal.
|
||||||
|
// https://github.com/stretchr/testify/assert/assertions.go
|
||||||
|
func (a *Assert) EqualValues(expected, actual interface{}) {
|
||||||
|
if !objectsAreEqualValues(expected, actual) {
|
||||||
|
makeTestFailed(a.T, a.CaseName, expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func objectsAreEqualValues(expected, actual interface{}) bool {
|
||||||
|
if objectsAreEqual(expected, actual) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
actualType := reflect.TypeOf(actual)
|
||||||
|
if actualType == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
expectedValue := reflect.ValueOf(expected)
|
||||||
|
if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
|
||||||
|
// Attempt comparison after type conversion
|
||||||
|
return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func objectsAreEqual(expected, actual interface{}) bool {
|
||||||
|
if expected == nil || actual == nil {
|
||||||
|
return expected == actual
|
||||||
|
}
|
||||||
|
|
||||||
|
exp, ok := expected.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return reflect.DeepEqual(expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
act, ok := actual.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if exp == nil || act == nil {
|
||||||
|
return exp == nil && act == nil
|
||||||
|
}
|
||||||
|
return bytes.Equal(exp, act)
|
||||||
|
}
|
||||||
|
|
||||||
// NotEqual check if expected is not equal with actual
|
// NotEqual check if expected is not equal with actual
|
||||||
func (a *Assert) NotEqual(expected, actual interface{}) {
|
func (a *Assert) NotEqual(expected, actual interface{}) {
|
||||||
if compare(expected, actual) == compareEqual {
|
if compare(expected, actual) == compareEqual {
|
||||||
|
|||||||
@@ -126,3 +126,66 @@ func IsPrime(n int) bool {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GCD return greatest common divisor (GCD) of integers.
|
||||||
|
func GCD(integers ...int) int {
|
||||||
|
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(a, b int) int {
|
||||||
|
if b == 0 {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
return gcd(b, a%b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LCM return Least Common Multiple (LCM) of integers.
|
||||||
|
func LCM(integers ...int) int {
|
||||||
|
result := integers[0]
|
||||||
|
|
||||||
|
for k := range integers {
|
||||||
|
result = lcm(integers[k], result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// find Least Common Multiple (LCM) via GCD.
|
||||||
|
func lcm(a, b int) int {
|
||||||
|
if a == 0 || b == 0 {
|
||||||
|
panic("lcm function: provide non zero integers only.")
|
||||||
|
}
|
||||||
|
return a * b / gcd(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cos returns the cosine of the radian argument.
|
||||||
|
func Cos(radian float64, precision ...int) float64 {
|
||||||
|
t := 1.0 / (2.0 * math.Pi)
|
||||||
|
radian *= t
|
||||||
|
radian -= 0.25 + math.Floor(radian+0.25)
|
||||||
|
radian *= 16.0 * (math.Abs(radian) - 0.5)
|
||||||
|
radian += 0.225 * radian * (math.Abs(radian) - 1.0)
|
||||||
|
|
||||||
|
if len(precision) == 1 {
|
||||||
|
return TruncRound(radian, precision[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return TruncRound(radian, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cos returns the sine of the radian argument.
|
||||||
|
func Sin(radian float64, precision ...int) float64 {
|
||||||
|
return Cos((math.Pi / 2) - radian)
|
||||||
|
}
|
||||||
|
|||||||
@@ -114,3 +114,61 @@ func TestIsPrime(t *testing.T) {
|
|||||||
assert.Equal(true, IsPrime(3))
|
assert.Equal(true, IsPrime(3))
|
||||||
assert.Equal(false, IsPrime(4))
|
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(1, LCM(1))
|
||||||
|
assert.Equal(-1, LCM(-1))
|
||||||
|
assert.Equal(-1, LCM(1, -1))
|
||||||
|
assert.Equal(1, LCM(-1, 1))
|
||||||
|
assert.Equal(1, LCM(1, 1))
|
||||||
|
assert.Equal(-1, LCM(-1, -1))
|
||||||
|
assert.Equal(2, LCM(1, 2))
|
||||||
|
assert.Equal(18, LCM(3, 6, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCos(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestCos")
|
||||||
|
|
||||||
|
assert.EqualValues(1, Cos(0))
|
||||||
|
assert.EqualValues(-0.447, Cos(90))
|
||||||
|
assert.EqualValues(-0.598, Cos(180))
|
||||||
|
assert.EqualValues(-1, Cos(math.Pi))
|
||||||
|
assert.EqualValues(0, Cos(math.Pi/2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSin(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSin")
|
||||||
|
|
||||||
|
assert.EqualValues(0, Sin(0))
|
||||||
|
assert.EqualValues(0.894, Sin(90))
|
||||||
|
assert.EqualValues(-0.801, Sin(180))
|
||||||
|
assert.EqualValues(0, Sin(math.Pi))
|
||||||
|
assert.EqualValues(1, Sin(math.Pi/2))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user