You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.0 KiB
111 lines
2.0 KiB
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 expand(cursor, matches int, duplicates []int) []int {
|
|
if cursor+matches > len(duplicates) {
|
|
tmp := make([]int, cursor+matches)
|
|
for i := range duplicates {
|
|
tmp[i] = duplicates[i]
|
|
}
|
|
duplicates = tmp
|
|
}
|
|
|
|
for i := cursor; i < cursor+matches; i++ {
|
|
duplicates[i] = duplicates[i] + 1
|
|
|
|
// only count duplicates if we are past the first card
|
|
if cursor > 0 {
|
|
duplicates[i] = duplicates[i] + duplicates[cursor-1]
|
|
}
|
|
}
|
|
|
|
return duplicates
|
|
}
|
|
|
|
func (d day04) solve2(r io.Reader) string {
|
|
var (
|
|
cursor int
|
|
duplicates = make([]int, 0)
|
|
scanner = bufio.NewScanner(r)
|
|
)
|
|
|
|
for matches := -1; scanner.Scan() && matches != 0; cursor++ {
|
|
_, line, _ := strings.Cut(scanner.Text(), ": ")
|
|
matches := countwinings(line)
|
|
duplicates = expand(cursor, matches, duplicates)
|
|
}
|
|
|
|
sum := cursor
|
|
for _, c := range duplicates {
|
|
sum += c
|
|
}
|
|
return fmt.Sprintf("%d", sum)
|
|
}
|
|
|