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) }