aoc2023/day02/day02.go
2024-11-04 19:18:21 +00:00

82 lines
1.5 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 ScanFile(file *os.File) (int, error) {
scanner := bufio.NewScanner(file)
sum := 0
for scanner.Scan() {
if game := parseGame(scanner.Text()); isGameValid(game) {
sum += game.id
}
}
if err := scanner.Err(); err != nil {
return 0, err
}
return sum, nil
}
func main() {
sum, err := ScanFile(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid input: %s\n", err)
return
}
fmt.Println(sum)
}