-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
84 lines (68 loc) · 2.07 KB
/
main.go
File metadata and controls
84 lines (68 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package main
import (
"github.com/danvolchek/AdventOfCode/lib"
"strings"
)
// Instruction represents a crane instruction to move amount crates from stack from to stack to.
type Instruction struct {
amount, from, to int
}
// Puzzle represents the puzzle input, which is a set of stacks of crates and a set of movement instructions.
type Puzzle struct {
stacks []lib.Stack[string]
instructions []Instruction
}
func parseCrates(crates string, p *Puzzle) {
cratesByLine := strings.Split(crates, "\n")
for lineIndex := range cratesByLine {
// parse in reverse order so stack is built properly
line := cratesByLine[len(cratesByLine)-1-lineIndex]
for i := 1; i < len(line); i += 4 {
if line[i] >= 'A' && line[i] <= 'Z' {
stackNumber := (i - 1) / 4
// grow stacks if needed
for len(p.stacks) < stackNumber+1 {
p.stacks = append(p.stacks, lib.Stack[string]{})
}
// add crate to stack
p.stacks[stackNumber].Push(string(line[i]))
}
}
}
}
func parseInstruction(instruction string) Instruction {
nums := lib.Ints(instruction)
return Instruction{
amount: nums[0],
from: nums[1] - 1,
to: nums[2] - 1,
}
}
func parseInstructions(instructions string, p *Puzzle) {
p.instructions = lib.ParseLine(parseInstruction)(instructions)
}
func solve(puzzle Puzzle) string {
for _, instr := range puzzle.instructions {
// simulate lifting crates with order preserved by putting them into a temporary stack and popping that onto to
var temp lib.Stack[string]
for i := 0; i < instr.amount; i++ {
temp.Push(puzzle.stacks[instr.from].Pop())
}
for i := 0; i < instr.amount; i++ {
puzzle.stacks[instr.to].Push(temp.Pop())
}
}
result := ""
for _, stack := range puzzle.stacks {
result += stack.Pop()
}
return result
}
func main() {
solver := lib.Solver[Puzzle, string]{
ParseF: lib.ParseChunksUnique(parseCrates, parseInstructions),
SolveF: solve,
}
solver.Expect(" [D] \n[N] [C] \n[Z] [M] [P]\n 1 2 3 \n\nmove 1 from 2 to 1\nmove 3 from 1 to 3\nmove 2 from 2 to 1\nmove 1 from 1 to 2", "MCD")
solver.Verify("LCTQFBVZV")
}