adventofcode/2022/day05/main.go
2022-12-05 09:47:05 -06:00

122 lines
2.4 KiB
Go

package main
import (
"fmt"
"sort"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToStringSlice()
part1(inp)
fmt.Println("")
part2(inp)
}
func part1(inp []string) {
fmt.Println("# Part 1")
stacks, bottom := buildStacks(inp)
// Run instructions
// Instructions start at bottom+2
for i := bottom + 2; i < len(inp); i++ {
inst := strings.Fields(inp[i])
count := h.Atoi(inst[1])
from := h.Atoi(inst[3])
to := h.Atoi(inst[5])
for c := 0; c < count; c++ {
moveCrates(stacks, from, to, 1)
}
}
for i := range stacks {
fmt.Print(string(stacks[i][0]))
}
fmt.Println("")
}
func part2(inp []string) {
fmt.Println("# Part 2")
stacks, bottom := buildStacks(inp)
// Run instructions
// Instructions start at bottom+2
for i := bottom + 2; i < len(inp); i++ {
inst := strings.Fields(inp[i])
count := h.Atoi(inst[1])
from := h.Atoi(inst[3])
to := h.Atoi(inst[5])
moveCrates(stacks, from, to, count)
}
for i := range stacks {
fmt.Print(string(stacks[i][0]))
}
fmt.Println("")
}
func getCrateHash(stacks [][]byte) string {
var ret []byte
for i := range stacks {
for j := range stacks[i] {
ret = append(ret, stacks[i][j])
}
}
sort.Slice(ret, func(p, q int) bool {
return ret[p] > ret[q]
})
return string(ret)
}
func validateCrates(valid string, stacks [][]byte) bool {
return valid == getCrateHash(stacks)
}
func buildStacks(inp []string) ([][]byte, int) {
var stacks [][]byte
// Find the bottom
var bottom int
for i, row := range inp {
if len(row) > 1 && row[1] == '1' {
bottom = i
break
}
}
// Allocate stacks
stCnt := strings.Fields(inp[bottom])
for i := 0; i < len(stCnt); i++ {
stacks = append(stacks, []byte{})
}
// Build stacks
for i := bottom - 1; i >= 0; i-- {
for stI := 0; stI < len(stCnt); stI++ {
pos := stI*4 + 1
if len(inp[i]) >= pos && (inp[i][pos] >= 'A' && inp[i][pos] <= 'Z') {
stacks[stI] = append([]byte{inp[i][pos]}, stacks[stI]...)
}
}
}
return stacks, bottom
}
func moveCrates(stacks [][]byte, from, to, count int) {
var x []byte
if count > 1 {
x, stacks[from-1] = stacks[from-1][0:count], stacks[from-1][count:]
} else {
x, stacks[from-1] = []byte{stacks[from-1][0]}, stacks[from-1][count:]
}
for i := len(x) - 1; i >= 0; i-- {
stacks[to-1] = append([]byte{x[i]}, stacks[to-1]...)
}
}
func printStacks(stacks [][]byte) {
for i := range stacks {
fmt.Println(i+1, string(stacks[i]))
}
}