Stream Video
I forgot to record today. Doh!
Code
package aoc
import (
"errors"
"fmt"
"io"
"strings"
"mono3/advent/lib/lineio"
"mono3/common/tty"
)
const score = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func findBadge(items map[rune]int) rune {
for k, v := range items {
if v == 3 {
return k
}
}
return '?'
}
// Each part gets the same input with reader pointing at the start of input.
var PuzzleParts = []func(r io.Reader) error{
PuzzlePart1,
PuzzlePart2,
}
func PuzzlePart1(r io.Reader) error {
return solveit(r, 1)
}
func PuzzlePart2(r io.Reader) error {
return solveit(r, 2)
}
func solveit(r io.Reader, part int) error {
totalScore := 0
elfGroupItems := map[rune]int{}
if err := lineio.ForEach(r, func(ln int, line string) error {
if len(line)%2 != 0 {
return fmt.Errorf("odd line length (%d) %q", len(line), line)
}
one := line[:len(line)/2]
two := line[len(line)/2:]
if len(one) != len(two) {
return fmt.Errorf("two compartments are not same size! %d vs %d", len(one), len(two))
}
if ln%3 == 0 && ln != 0 {
badge := findBadge(elfGroupItems)
pos := strings.IndexRune(score, badge)
if part == 2 {
totalScore += pos
}
elfGroupItems = map[rune]int{}
}
seen := map[rune]bool{}
for _, r := range line {
if !seen[r] {
seen[r] = true
elfGroupItems[r] += 1
}
}
seen = map[rune]bool{}
for _, r := range one {
seen[r] = true
}
for _, r := range two {
if seen[r] {
pos := strings.IndexRune(score, r)
if part == 1 {
totalScore += pos
}
return nil
}
}
tty.Printf("NO DUPLICATE line %d in %q\n", ln, line)
return errors.New("no duplicates found!")
}); err != nil {
return err
}
badge := findBadge(elfGroupItems)
score := strings.IndexRune(score, badge)
if part == 2 {
totalScore += score
}
tty.Printf("Total score for part %d: %d\n", part, totalScore)
return nil
}