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
}