solutions for the Advent of Code 2023
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

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