122 lines
2.4 KiB
Go
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]))
|
|
}
|
|
}
|