advent-of-code/tools.go

99 lines
1.7 KiB
Go
Raw Normal View History

2023-12-08 16:24:48 -07:00
package aoc
import (
"bufio"
"fmt"
"os"
2023-12-09 10:52:49 -07:00
"path/filepath"
2023-12-09 14:57:02 -07:00
"strconv"
2023-12-08 20:33:36 -07:00
"strings"
2023-12-08 16:24:48 -07:00
)
func Runner[R any, F func(*bufio.Scanner) (R, error)](run F) (R, error) {
if len(os.Args) != 2 {
2023-12-09 10:52:49 -07:00
Log("Usage:", filepath.Base(os.Args[0]), "FILE")
2023-12-08 20:33:36 -07:00
os.Exit(22)
2023-12-08 16:24:48 -07:00
}
input, err := os.Open(os.Args[1])
if err != nil {
2023-12-08 20:33:36 -07:00
Log(err)
os.Exit(1)
2023-12-08 16:24:48 -07:00
}
scan := bufio.NewScanner(input)
return run(scan)
}
2023-12-09 10:52:49 -07:00
func MustResult[T any](result T, err error) {
if err != nil {
fmt.Println("ERR", err)
os.Exit(1)
}
Log("result", result)
}
2023-12-08 20:33:36 -07:00
func Log(v ...any) { fmt.Fprintln(os.Stderr, v...) }
func Logf(format string, v ...any) {
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
fmt.Fprintf(os.Stderr, format, v...)
}
2023-12-08 19:09:00 -07:00
func Reverse[T any](arr []T) []T {
for i := 0; i < len(arr)/2; i++ {
arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
}
return arr
}
2023-12-08 20:33:36 -07:00
type integer interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64
}
2023-12-09 14:57:02 -07:00
2023-12-08 20:33:36 -07:00
// type float interface {
// complex64 | complex128 | float32 | float64
// }
// type number interface{ integer | float }
2023-12-08 19:09:00 -07:00
2023-12-08 16:24:48 -07:00
// greatest common divisor (GCD) via Euclidean algorithm
2023-12-08 20:33:36 -07:00
func GCD[T integer](a, b T) T {
2023-12-08 16:24:48 -07:00
for b != 0 {
t := b
b = a % b
a = t
}
return a
}
// find Least Common Multiple (LCM) via GCD
2023-12-08 20:33:36 -07:00
func LCM[T integer](integers ...T) T {
2023-12-08 16:24:48 -07:00
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
}
2023-12-09 14:57:02 -07:00
func ReadStringToInts(fields []string) []int {
arr := make([]int, len(fields))
for i, s := range fields {
if v, err := strconv.Atoi(s); err == nil {
arr[i] = v
}
}
return arr
}