Advent of Code 2022: Day5

Back up

Stream Video

Code

package aoc

import (
	"fmt"
	"io"
	"strings"

	"mono3/advent/lib/lineio"
	"mono3/common/log"
)

type stack struct {
	items []string
}

func colToStack(i int) int {
	return i/4 + 1
}

// 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 {
	log.Info("Running")

	n := 10
	stacks := make([]*stack, n)
	for i := 0; i < n; i++ {
		stacks[i] = &stack{}
	}

	inInitialConditions := true

	if err := lineio.ForEachWithoutTrim(r, func(ln int, line string) error {
		//log.Infof("[%3d] %s", ln, line)

		if line == "" {
			inInitialConditions = false
			return nil
		}

		if inInitialConditions {
			// Read initial stack conditions.
			stackIdx := 0
			inItem := false
			for i, r := range line {
				switch r {
				case '[':
					stackIdx = colToStack(i)
					log.Infof("Adding item to stack %d", stackIdx)
					inItem = true

				case ']':
					log.Infof("Done item")
					inItem = false

				default:
					if inItem {
						item := line[i : i+1]
						log.Infof("  item = %q", item)
						stacks[stackIdx].items = append(stacks[stackIdx].items, item)
					}
				}
			}
		} else {
			// Instructions on moves.
			count := 0
			src := 0
			dst := 0
			fmt.Sscanf(line, "move %d from %d to %d", &count, &src, &dst)
			if count == 0 {
				return nil
			}

			log.Infof("Moving %d from stack %d to %d", count, src, dst)

			srcStack := stacks[src]
			dstStack := stacks[dst]

			log.Infof("\tsrc stack[%2d]: (%d) %v", src, len(srcStack.items), srcStack.items)
			log.Infof("\tdst stack[%2d]: (%d) %v", dst, len(dstStack.items), dstStack.items)

			if part == 1 {
				for i := 0; i < count; i++ {
					item := srcStack.items[0]
					srcStack.items = srcStack.items[1:]
					dstStack.items = append([]string{item}, dstStack.items...)
				}
			}

			if part == 2 {
				items := srcStack.items[0:count]
				srcStack.items = srcStack.items[count:]
				dstStack.items = append(append([]string{}, items...), dstStack.items...)

				log.Infof("\tPOST src stack[%2d]: (%d) %v", src, len(srcStack.items), srcStack.items)
				log.Infof("\tPOST dst stack[%2d]: (%d) %v", dst, len(dstStack.items), dstStack.items)
			}
		}

		return nil
	}); err != nil {
		return err
	}

	var sb strings.Builder
	for i := 0; i < n; i++ {
		stack := stacks[i]
		log.Infof("Final state stack[%2d]: (%d) %v", i, len(stack.items), stack.items)
		if len(stack.items) > 0 {
			sb.WriteString(stack.items[0])
		}
	}
	log.Infof("Top items: %s", sb.String())

	return nil
}

aimeeble@blog

the blog of aimeeble


By Aimee, 2022-12-05


Table of Contents: