-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
106 lines (83 loc) · 1.45 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
package main
import (
"bufio"
"bytes"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
fmt.Printf("Part 1: %d\n", part1(input))
fmt.Printf("Part 2:\n%s\n", part2(input))
}
func part1(input []string) int {
var sum int
c := newCPU(input)
c.run(func() {
if (c.cycle-20)%40 == 0 {
sum += c.cycle * c.x
}
})
return sum
}
func part2(input []string) string {
const w, h = 40, 6
screen := make([][]byte, h)
for y := 0; y < h; y++ {
screen[y] = make([]byte, w)
}
c := newCPU(input)
c.run(func() {
x, y := (c.cycle-1)%w, (c.cycle-1)/w
if c.x-1 <= x && x <= c.x+1 {
screen[y][x] = '#'
} else {
screen[y][x] = '.'
}
})
return string(bytes.Join(screen, []byte{'\n'}))
}
type cpu struct {
program []string
cycle int
cur int
curSpent int
x int
}
func newCPU(program []string) *cpu {
return &cpu{
program: program,
x: 1,
}
}
// run runs the program, calling f at the beginning of each cycle.
func (c *cpu) run(f func()) {
cost := map[string]int{
"addx": 2,
"noop": 1,
}
for c.cur < len(c.program) {
c.cycle++
c.curSpent++
f()
inst := strings.Fields(c.program[c.cur])
if c.curSpent < cost[inst[0]] {
continue
}
switch inst[0] {
case "addx":
val, _ := strconv.Atoi(inst[1])
c.x += val
case "noop":
// noop
}
c.cur++
c.curSpent = 0
}
}