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