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])) } }