aoc2023/day02/day02.go
2024-11-04 23:14:01 +00:00

95 lines
1.8 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type Game struct {
id int
sets []Set
}
type Set struct {
red int
green int
blue int
}
func parseGame(input string) Game {
idStr, setsStr, _ := strings.Cut(input, ": ")
var game Game
var err error
game.id, err = strconv.Atoi(strings.TrimPrefix(idStr, "Game "))
for i, setStr := range strings.Split(setsStr, "; ") {
game.sets = append(game.sets, Set{})
for _, colorStr := range strings.Split(setStr, ", ") {
if strings.HasSuffix(colorStr, " red") {
game.sets[i].red, err = strconv.Atoi(strings.TrimSuffix(colorStr, " red"))
}
if strings.HasSuffix(colorStr, " green") {
game.sets[i].green, err = strconv.Atoi(strings.TrimSuffix(colorStr, " green"))
}
if strings.HasSuffix(colorStr, " blue") {
game.sets[i].blue, err = strconv.Atoi(strings.TrimSuffix(colorStr, " blue"))
}
}
}
if err != nil {
panic("day02: invalid game format")
}
return game
}
func isGameValid(game Game) bool {
for _, set := range game.sets {
if set.red > 12 || set.green > 13 || set.blue > 14 {
return false
}
}
return true
}
func power(game Game) int {
var red, green, blue int
for _, set := range game.sets {
red = max(red, set.red)
green = max(green, set.green)
blue = max(blue, set.blue)
}
return red * green * blue
}
func ScanFile(file *os.File) (int, int, error) {
scanner := bufio.NewScanner(file)
var idSum, powerSum int
for scanner.Scan() {
game := parseGame(scanner.Text())
if isGameValid(game) {
idSum += game.id
}
powerSum += power(game)
}
if err := scanner.Err(); err != nil {
return 0, 0, err
}
return idSum, powerSum, nil
}
func main() {
idSum, powerSum, err := ScanFile(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid input: %s\n", err)
return
}
fmt.Println(idSum)
fmt.Println(powerSum)
}