Files
advent-of-code-go/2023/day02/main.go
T
2024-01-22 23:37:55 -05:00

113 lines
2.3 KiB
Go

package main
import (
_ "embed"
"flag"
"fmt"
"strings"
"github.com/alexchao26/advent-of-code-go/cast"
"github.com/alexchao26/advent-of-code-go/mathy"
"github.com/alexchao26/advent-of-code-go/util"
)
//go:embed input.txt
var input string
func init() {
// do this in init (not main) so test file has same input
input = strings.TrimRight(input, "\n")
if len(input) == 0 {
panic("empty input.txt file")
}
}
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Println("Running part", part)
if part == 1 {
ans := part1(input)
util.CopyToClipboard(fmt.Sprintf("%v", ans))
fmt.Println("Output:", ans)
} else {
ans := part2(input)
util.CopyToClipboard(fmt.Sprintf("%v", ans))
fmt.Println("Output:", ans)
}
}
func part1(input string) int {
games := parseInput(input)
var possibleIDSum int
for _, g := range games {
isPossible := true
for _, step := range g.steps {
// only 12 red cubes, 13 green cubes, and 14 blue cubes
if step["red"] > 12 || step["green"] > 13 || step["blue"] > 14 {
isPossible = false
break
}
}
if isPossible {
possibleIDSum += g.id
}
}
return possibleIDSum
}
func part2(input string) int {
games := parseInput(input)
var sum int
for _, g := range games {
lowestPossibleCount := map[string]int{}
for _, step := range g.steps {
lowestPossibleCount["red"] = mathy.MaxInt(lowestPossibleCount["red"], step["red"])
lowestPossibleCount["green"] = mathy.MaxInt(lowestPossibleCount["green"], step["green"])
lowestPossibleCount["blue"] = mathy.MaxInt(lowestPossibleCount["blue"], step["blue"])
}
sum += lowestPossibleCount["red"] * lowestPossibleCount["blue"] * lowestPossibleCount["green"]
}
return sum
}
type game struct {
id int
steps []map[string]int
}
func parseInput(input string) (ans []game) {
for i, line := range strings.Split(input, "\n") {
parts := strings.Split(line, ": ")
g := game{
id: i + 1,
}
for _, p := range strings.Split(parts[1], "; ") {
step := map[string]int{}
for _, group := range strings.Split(p, ", ") {
numberColor := strings.Split(group, " ")
if len(numberColor) != 2 {
panic(fmt.Sprintf("group not in two pieces %q", group))
}
step[numberColor[1]] = cast.ToInt(numberColor[0])
}
g.steps = append(g.steps, step)
}
ans = append(ans, g)
}
return ans
}