2023-12-27 14:07:32 -07:00
|
|
|
package aoc
|
|
|
|
|
|
|
|
import "cmp"
|
|
|
|
|
|
|
|
type uinteger interface {
|
2024-01-01 09:26:31 -07:00
|
|
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
|
2023-12-27 14:07:32 -07:00
|
|
|
}
|
|
|
|
type sinteger interface {
|
2024-01-01 09:26:31 -07:00
|
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64
|
2023-12-27 14:07:32 -07:00
|
|
|
}
|
|
|
|
type integer interface {
|
|
|
|
sinteger | uinteger
|
|
|
|
}
|
|
|
|
|
2024-01-01 09:26:31 -07:00
|
|
|
type float interface {
|
|
|
|
complex64 | complex128 | float32 | float64
|
|
|
|
}
|
|
|
|
type number interface{ integer | float }
|
2023-12-27 14:07:32 -07:00
|
|
|
|
|
|
|
// greatest common divisor (GCD) via Euclidean algorithm
|
|
|
|
func GCD[T integer](a, b T) T {
|
|
|
|
for b != 0 {
|
|
|
|
t := b
|
|
|
|
b = a % b
|
|
|
|
a = t
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
// find Least Common Multiple (LCM) via GCD
|
|
|
|
func LCM[T integer](integers ...T) T {
|
|
|
|
if len(integers) == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if len(integers) == 1 {
|
|
|
|
return integers[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
a, b := integers[0], integers[1]
|
|
|
|
result := a * b / GCD(a, b)
|
|
|
|
|
|
|
|
for _, c := range integers[2:] {
|
|
|
|
result = LCM(result, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2024-01-01 09:26:31 -07:00
|
|
|
func Sum[T number](arr ...T) T {
|
2023-12-27 14:07:32 -07:00
|
|
|
var acc T
|
|
|
|
for _, a := range arr {
|
|
|
|
acc += a
|
|
|
|
}
|
|
|
|
return acc
|
|
|
|
}
|
2024-01-01 09:26:31 -07:00
|
|
|
func SumFunc[T any, U number](fn func(T) U, input ...T) U {
|
2023-12-27 14:07:32 -07:00
|
|
|
return Sum(SliceMap(fn, input...)...)
|
|
|
|
}
|
2024-01-01 09:26:31 -07:00
|
|
|
func SumIFunc[T any, U number](fn func(int, T) U, input ...T) U {
|
2023-12-27 14:07:32 -07:00
|
|
|
return Sum(SliceIMap(fn, input...)...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Power2(n int) int {
|
|
|
|
if n == 0 {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
p := 2
|
|
|
|
for ; n > 1; n-- {
|
|
|
|
p *= 2
|
|
|
|
}
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2024-01-01 09:26:31 -07:00
|
|
|
func ABS[I integer](i I) I {
|
2023-12-27 14:07:32 -07:00
|
|
|
if i < 0 {
|
|
|
|
return -i
|
|
|
|
}
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func Max[T cmp.Ordered](a T, v ...T) T {
|
|
|
|
for _, b := range v {
|
|
|
|
if b > a {
|
|
|
|
a = b
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
func Min[T cmp.Ordered](a T, v ...T) T {
|
|
|
|
for _, b := range v {
|
|
|
|
if b < a {
|
|
|
|
a = b
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|