Back up
Stream Video
Code
package aoc
import (
"errors"
"fmt"
"io"
"strings"
"mono3/advent/lib/lineio"
"mono3/common/log"
)
// 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, 4)
}
func PuzzlePart2(r io.Reader) error {
return solveit(r, 2, 14)
}
func solveit(r io.Reader, part int, n int) error {
log.Info("Running")
if err := lineio.ForEach(r, func(ln int, line string) error {
pos, err := findStart(line, n)
if err != nil {
return err
}
var sb strings.Builder
fmt.Fprintf(&sb, "Solution: %s", string(line[:pos-n]))
fmt.Fprintf(&sb, "%%F{brightred}%s%%f", string(line[pos-n:pos]))
fmt.Fprintf(&sb, "%s: %d", string(line[pos:]), pos)
log.Colour(sb.String())
return nil
}); err != nil {
return err
}
return nil
}
func allDiff(window []rune) bool {
seen := make(map[rune]bool)
for _, r := range window {
if seen[r] {
return false
}
seen[r] = true
}
return true
}
func findStart(data string, n int) (int, error) {
var window []rune
for i, r := range data {
window = append(window, r)
if len(window) > n {
window = window[1:]
}
if len(window) == n && allDiff(window) {
return i + 1, nil
}
}
return 0, errors.New("no start-of-thingy")
}