Advent of Code 2022: Day6

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

aimeeble@blog

the blog of aimeeble


By Aimee, 2022-12-06


Table of Contents: