package main import ( "bufio" "fmt" "io" "math" "sort" "strconv" "strings" ) func countwinings(line string) int { var matches int before, after, _ := strings.Cut(line, "|") w := strings.Split(before, " ") o := strings.Split(after, " ") winnings := make([]int, 0, len(w)) obtained := make([]int, 0, len(o)) for i := range w { val, err := strconv.Atoi(strings.TrimSpace(w[i])) if err == nil { winnings = append(winnings, val) } } for i := range o { val, err := strconv.Atoi(strings.TrimSpace(o[i])) if err == nil { obtained = append(obtained, val) } } sort.Ints(winnings) sort.Ints(obtained) for i, j := 0, 0; i < len(winnings) && j < len(obtained); { if winnings[i] == obtained[j] { matches++ i++ j++ } else if winnings[i] > obtained[j] { j++ } else { i++ } } return matches } type day04 struct{} func (d day04) solve1(r io.Reader) string { var ( sum int scanner = bufio.NewScanner(r) ) for scanner.Scan() { _, line, _ := strings.Cut(scanner.Text(), ": ") matches := countwinings(line) if matches > 0 { sum += int(math.Pow(2, float64(matches)-1)) } } return fmt.Sprintf("%d", sum) } func (d day04) solve2(r io.Reader) string { var ( current int sum = 1 cards = make([]int, 185) scanner = bufio.NewScanner(r) ) for matches := -1; scanner.Scan() && matches != 0; current++ { _, line, _ := strings.Cut(scanner.Text(), ": ") sum++ matches = countwinings(line) for i := 1; i <= matches; i++ { cards[current+i] = cards[current+i] + 1 + cards[current] } } for _, c := range cards { sum += c } return fmt.Sprintf("%d", sum) }