diff --git a/day02/main.go b/day02/main.go index 7f2f2b2..f9759c2 100644 --- a/day02/main.go +++ b/day02/main.go @@ -2,24 +2,39 @@ package main import ( "bufio" - "bytes" _ "embed" "fmt" + "os" "strconv" "strings" + + aoc "go.sour.is/advent-of-code-2023" ) -//go:embed input.txt -var input []byte +func main() { + result, err := aoc.Runner(run) + if err != nil { + aoc.Log("ERR", err) + os.Exit(1) + } + + aoc.Log(result) +} + +type result struct { + sum int + powerSum int +} + +func (r result) String() string { + return fmt.Sprintln("result pt1:", r.sum, "\nresult pt2:", r.powerSum) +} type gameResult struct { red, green, blue int } -func main() { - buf := bytes.NewReader(input) - scan := bufio.NewScanner(buf) - +func run(scan *bufio.Scanner) (*result, error) { // only 12 red cubes, 13 green cubes, and 14 blue cubes maxCounts := gameResult{ red: 12, @@ -62,8 +77,8 @@ func main() { } } - fmt.Println(games) - fmt.Println(len(games)) + aoc.Log(games) + aoc.Log(len(games)) sum := 0 powerSum := 0 @@ -81,24 +96,24 @@ func main() { mins.blue = max(mins.blue, round.blue) if maxCounts.red < round.red { - fmt.Println("game", i, round, "too many red", round.red) + aoc.Log("game", i, round, "too many red", round.red) ok = false } else if maxCounts.blue < round.blue { - fmt.Println("game", i, round, "too many blue", round.blue) + aoc.Log("game", i, round, "too many blue", round.blue) ok = false } else if maxCounts.green < round.green { - fmt.Println("game", i, round, "too many green", round.green) + aoc.Log("game", i, round, "too many green", round.green) ok = false } - fmt.Println("game", i, round, ok) + aoc.Log("game", i, round, ok) } if ok { sum += i - fmt.Println("game", i, "passes", sum) + aoc.Log("game", i, "passes", sum) } - power := mins.red*mins.blue*mins.green - fmt.Println("game", i, "mins", mins, power) + power := mins.red * mins.blue * mins.green + aoc.Log("game", i, "mins", mins, power) powerSum += power } - fmt.Println("sum", sum, "power", powerSum) + return &result{sum, powerSum}, nil } diff --git a/day02/main_test.go b/day02/main_test.go new file mode 100644 index 0000000..23215eb --- /dev/null +++ b/day02/main_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "bufio" + "bytes" + "testing" + + _ "embed" + + "github.com/matryer/is" +) + +//go:embed example.txt +var example []byte + +//go:embed input.txt +var input []byte + +func TestExample(t *testing.T) { + is := is.New(t) + scan := bufio.NewScanner(bytes.NewReader(example)) + + result, err := run(scan) + is.NoErr(err) + + t.Log(result) + is.Equal(result.sum, 8) + is.Equal(result.powerSum, 2286) +} + +func TestSolution(t *testing.T) { + is := is.New(t) + scan := bufio.NewScanner(bytes.NewReader(input)) + + result, err := run(scan) + is.NoErr(err) + + t.Log(result) + is.Equal(result.sum, 2317) + is.Equal(result.powerSum, 74804) +} diff --git a/tools.go b/tools.go index a78e990..05f87aa 100644 --- a/tools.go +++ b/tools.go @@ -4,22 +4,33 @@ import ( "bufio" "fmt" "os" + "strings" ) func Runner[R any, F func(*bufio.Scanner) (R, error)](run F) (R, error) { if len(os.Args) != 2 { - fmt.Fprintln(os.Stderr, "Usage:", os.Args[0] , "FILE") + Log("Usage:", os.Args[0], "FILE") + os.Exit(22) } input, err := os.Open(os.Args[1]) if err != nil { - fmt.Fprintln(os.Stderr, err) + Log(err) + os.Exit(1) } scan := bufio.NewScanner(input) return run(scan) } +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...) +} + 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] @@ -27,9 +38,16 @@ func Reverse[T any](arr []T) []T { return arr } +type integer interface { + int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 +} +// type float interface { +// complex64 | complex128 | float32 | float64 +// } +// type number interface{ integer | float } // greatest common divisor (GCD) via Euclidean algorithm -func GCD(a, b uint64) uint64 { +func GCD[T integer](a, b T) T { for b != 0 { t := b b = a % b @@ -39,7 +57,7 @@ func GCD(a, b uint64) uint64 { } // find Least Common Multiple (LCM) via GCD -func LCM(integers ...uint64) uint64 { +func LCM[T integer](integers ...T) T { if len(integers) == 0 { return 0 }