Files
advent-of-code-go/2022/day05/main.go
T
2022-12-20 01:06:57 -05:00

127 lines
2.6 KiB
Go

package main
import (
_ "embed"
"flag"
"fmt"
"strings"
"github.com/alexchao26/advent-of-code-go/util"
)
//go:embed input.txt
var input string
func init() {
// do this in init (not main) so test file has same input
input = strings.TrimRight(input, "\n")
if len(input) == 0 {
panic("empty input.txt file")
}
}
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Println("Running part", part)
if part == 1 {
ans := part1(input)
util.CopyToClipboard(fmt.Sprintf("%v", ans))
fmt.Println("Output:", ans)
} else {
ans := part2(input)
util.CopyToClipboard(fmt.Sprintf("%v", ans))
fmt.Println("Output:", ans)
}
}
func part1(input string) string {
stacks, steps := parseInput(input)
for _, step := range steps {
// move crates ONE AT A TIME
for q := 0; q < step.qty; q++ {
top := stacks[step.from][len(stacks[step.from])-1]
stacks[step.to] = append(stacks[step.to], top)
stacks[step.from] = stacks[step.from][:len(stacks[step.from])-1]
}
}
ans := ""
for _, stack := range stacks {
ans += stack[len(stack)-1]
}
return ans
}
func part2(input string) string {
stacks, steps := parseInput(input)
for _, step := range steps {
// move crates ONCE
fromIndex := len(stacks[step.from]) - step.qty
stacks[step.to] = append(stacks[step.to], stacks[step.from][fromIndex:]...)
stacks[step.from] = stacks[step.from][:fromIndex]
}
ans := ""
for _, stack := range stacks {
ans += stack[len(stack)-1]
}
return ans
}
// move 4 from 3 to 1
type step struct {
qty, from, to int
}
func (s step) String() string {
return fmt.Sprintf("move %d from %d to %d", s.qty, s.from, s.to)
}
func parseInput(input string) ([][]string, []step) {
parts := strings.Split(input, "\n\n")
state := parts[0]
oversized := [][]string{}
for _, row := range strings.Split(state, "\n") {
oversized = append(oversized, strings.Split(row, ""))
}
oRows, oCols := len(oversized), len(oversized[0])
actual := [][]string{}
for c := 0; c < oCols-1; c++ {
if oversized[oRows-1][c] != " " {
// hit a column with values... move up from here
stack := []string{}
for r := oRows - 2; r >= 0; r-- {
char := oversized[r][c]
if char != " " {
stack = append(stack, char)
}
}
actual = append(actual, stack)
}
}
stepsRaw := parts[1]
steps := []step{}
for _, row := range strings.Split(stepsRaw, "\n") {
inst := step{}
_, err := fmt.Sscanf(row, "move %d from %d to %d", &inst.qty, &inst.from, &inst.to)
if err != nil {
panic(err)
}
// subtract one so they're zero indexed...
inst.from--
inst.to--
steps = append(steps, inst)
}
return actual, steps
}