-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
117 lines (92 loc) · 3.43 KB
/
main.go
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main
import (
"github.com/danvolchek/AdventOfCode/lib"
"strings"
)
type Command interface {
Cycles() int
Run(*CPU)
}
type NoOpCommand struct{}
func (n NoOpCommand) Cycles() int {
return 1
}
func (n NoOpCommand) Run(cpu *CPU) {}
type AddXCommand struct {
arg int
}
func (a AddXCommand) Cycles() int {
return 2
}
func (a AddXCommand) Run(cpu *CPU) {
cpu.x += a.arg
}
type PendingCommand struct {
countdown int
action func(*CPU)
}
type CPU struct {
x int
cycle int
commands []*PendingCommand
}
func (c *CPU) addCommand(command Command) {
c.commands = append(c.commands, &PendingCommand{
countdown: command.Cycles(),
action: command.Run,
})
}
func (c *CPU) step() {
if len(c.commands) > 0 {
command := c.commands[0]
command.countdown -= 1
if command.countdown == 0 {
command.action(c)
c.commands = c.commands[1:]
}
}
c.cycle += 1
}
func parse(line string) Command {
if line == "noop" {
return NoOpCommand{}
} else if strings.Contains(line, "addx") {
arg := lib.Atoi(line[len("addx "):])
return AddXCommand{arg: arg}
}
panic(line)
}
func solve(commands []Command) string {
cpu := CPU{
x: 1,
cycle: 1,
}
for _, command := range commands {
cpu.addCommand(command)
}
var picture strings.Builder
for len(cpu.commands) != 0 {
//fmt.Printf("During cycle %v, x is %v\n", i, cpu.x)
xPos := (cpu.cycle - 1) % 40
if lib.Abs(xPos-cpu.x) <= 1 {
picture.WriteString("#")
} else {
picture.WriteString(".")
}
if cpu.cycle%40 == 0 {
picture.WriteString("\n")
}
cpu.step()
//fmt.Printf("After cycle %v, x is %v\n", i, cpu.x)
}
return "\n" + strings.TrimSpace(picture.String())
}
func main() {
solver := lib.Solver[[]Command, string]{
ParseF: lib.ParseLine(parse),
SolveF: solve,
}
solver.Test("noop\naddx 3\naddx -5")
solver.Expect("addx 15\naddx -11\naddx 6\naddx -3\naddx 5\naddx -1\naddx -8\naddx 13\naddx 4\nnoop\naddx -1\naddx 5\naddx -1\naddx 5\naddx -1\naddx 5\naddx -1\naddx 5\naddx -1\naddx -35\naddx 1\naddx 24\naddx -19\naddx 1\naddx 16\naddx -11\nnoop\nnoop\naddx 21\naddx -15\nnoop\nnoop\naddx -3\naddx 9\naddx 1\naddx -3\naddx 8\naddx 1\naddx 5\nnoop\nnoop\nnoop\nnoop\nnoop\naddx -36\nnoop\naddx 1\naddx 7\nnoop\nnoop\nnoop\naddx 2\naddx 6\nnoop\nnoop\nnoop\nnoop\nnoop\naddx 1\nnoop\nnoop\naddx 7\naddx 1\nnoop\naddx -13\naddx 13\naddx 7\nnoop\naddx 1\naddx -33\nnoop\nnoop\nnoop\naddx 2\nnoop\nnoop\nnoop\naddx 8\nnoop\naddx -1\naddx 2\naddx 1\nnoop\naddx 17\naddx -9\naddx 1\naddx 1\naddx -3\naddx 11\nnoop\nnoop\naddx 1\nnoop\naddx 1\nnoop\nnoop\naddx -13\naddx -19\naddx 1\naddx 3\naddx 26\naddx -30\naddx 12\naddx -1\naddx 3\naddx 1\nnoop\nnoop\nnoop\naddx -9\naddx 18\naddx 1\naddx 2\nnoop\nnoop\naddx 9\nnoop\nnoop\nnoop\naddx -1\naddx 2\naddx -37\naddx 1\naddx 3\nnoop\naddx 15\naddx -21\naddx 22\naddx -6\naddx 1\nnoop\naddx 2\naddx 1\nnoop\naddx -10\nnoop\nnoop\naddx 20\naddx 1\naddx 2\naddx 2\naddx -6\naddx -11\nnoop\nnoop\nnoop", "\n##..##..##..##..##..##..##..##..##..##..\n###...###...###...###...###...###...###.\n####....####....####....####....####....\n#####.....#####.....#####.....#####.....\n######......######......######......####\n#######.......#######.......#######.....")
solver.Verify("\n###..####..##..###..#..#.###..####.###..\n#..#....#.#..#.#..#.#.#..#..#.#....#..#.\n#..#...#..#....#..#.##...#..#.###..###..\n###...#...#.##.###..#.#..###..#....#..#.\n#....#....#..#.#....#.#..#....#....#..#.\n#....####..###.#....#..#.#....####.###..")
}