Skip to content

Commit cdbfe13

Browse files
committed
day21
1 parent 1d81636 commit cdbfe13

File tree

3 files changed

+227
-0
lines changed

3 files changed

+227
-0
lines changed

day21/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.PHONY: all clean run
2+
all:
3+
go build
4+
clean:
5+
go clean
6+
run:
7+
go run main.go < input.txt

day21/input.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ip 3
2+
seti 123 0 1
3+
bani 1 456 1
4+
eqri 1 72 1
5+
addr 1 3 3
6+
seti 0 0 3
7+
seti 0 7 1
8+
bori 1 65536 4
9+
seti 3798839 3 1
10+
bani 4 255 5
11+
addr 1 5 1
12+
bani 1 16777215 1
13+
muli 1 65899 1
14+
bani 1 16777215 1
15+
gtir 256 4 5
16+
addr 5 3 3
17+
addi 3 1 3
18+
seti 27 6 3
19+
seti 0 2 5
20+
addi 5 1 2
21+
muli 2 256 2
22+
gtrr 2 4 2
23+
addr 2 3 3
24+
addi 3 1 3
25+
seti 25 3 3
26+
addi 5 1 5
27+
seti 17 1 3
28+
setr 5 6 4
29+
seti 7 8 3
30+
eqrr 1 0 5
31+
addr 5 3 3
32+
seti 5 6 3

day21/main.go

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
)
8+
9+
type (
10+
Regs [6]int
11+
Instr [4]int
12+
Op = func(r *Regs, a, b, c int)
13+
)
14+
15+
func main() {
16+
var ops [16]Op = [...]Op{
17+
Addr, Addi, Mulr, Muli, Banr, Bani, Borr, Bori,
18+
Seti, Setr, Gtir, Gtri, Gtrr, Eqir, Eqri, Eqrr,
19+
}
20+
21+
sc := bufio.NewScanner(os.Stdin)
22+
var ipreg int
23+
var program []Instr
24+
for sc.Scan() {
25+
if sc.Text()[0] == '#' {
26+
fmt.Sscanf(sc.Text(), "#ip %d", &ipreg)
27+
} else {
28+
var op string
29+
var instr Instr
30+
fmt.Sscanf(sc.Text(), "%s %d %d %d", &op, &instr[1], &instr[2], &instr[3])
31+
switch op {
32+
case "addr":
33+
instr[0] = 0
34+
case "addi":
35+
instr[0] = 1
36+
case "mulr":
37+
instr[0] = 2
38+
case "muli":
39+
instr[0] = 3
40+
case "banr":
41+
instr[0] = 4
42+
case "bani":
43+
instr[0] = 5
44+
case "borr":
45+
instr[0] = 6
46+
case "bori":
47+
instr[0] = 7
48+
case "seti":
49+
instr[0] = 8
50+
case "setr":
51+
instr[0] = 9
52+
case "gtir":
53+
instr[0] = 10
54+
case "gtri":
55+
instr[0] = 11
56+
case "gtrr":
57+
instr[0] = 12
58+
case "eqir":
59+
instr[0] = 13
60+
case "eqri":
61+
instr[0] = 14
62+
case "eqrr":
63+
instr[0] = 15
64+
default:
65+
panic(sc.Text())
66+
}
67+
program = append(program, instr)
68+
}
69+
}
70+
N := len(program)
71+
72+
// Calculate answer to b) naively by iterating until we reach a value
73+
// previously seen. That does not guarantee the correct answer as it might
74+
// occur before entering a periodic phase, but turns out ok in this case.
75+
seen := make(map[int]byte)
76+
firstTime := true
77+
var prev int
78+
var regs Regs
79+
for ip := 0; 0 <= ip && ip < N; ip++ {
80+
// Noted in input: program halts when register 0 equals the value in
81+
// register 1 when instruction pointer is 28.
82+
if ip == 28 {
83+
if firstTime {
84+
fmt.Printf("a) %d\n", regs[1])
85+
firstTime = false
86+
}
87+
seen[regs[1]] = seen[regs[1]] + 1
88+
if seen[regs[1]] == 2 {
89+
break
90+
}
91+
prev = regs[1]
92+
}
93+
instr := program[ip]
94+
regs[ipreg] = ip
95+
ops[instr[0]](&regs, instr[1], instr[2], instr[3])
96+
ip = regs[ipreg]
97+
}
98+
fmt.Printf("b) %d\n", prev)
99+
fmt.Println("(Note: the code is hardcoded to the input)")
100+
}
101+
102+
func Addr(r *Regs, a, b, c int) {
103+
r[c] = r[a] + r[b]
104+
}
105+
106+
func Addi(r *Regs, a, b, c int) {
107+
r[c] = r[a] + b
108+
}
109+
110+
func Mulr(r *Regs, a, b, c int) {
111+
r[c] = r[a] * r[b]
112+
}
113+
114+
func Muli(r *Regs, a, b, c int) {
115+
r[c] = r[a] * b
116+
}
117+
118+
func Banr(r *Regs, a, b, c int) {
119+
r[c] = r[a] & r[b]
120+
}
121+
122+
func Bani(r *Regs, a, b, c int) {
123+
r[c] = r[a] & b
124+
}
125+
126+
func Borr(r *Regs, a, b, c int) {
127+
r[c] = r[a] | r[b]
128+
}
129+
130+
func Bori(r *Regs, a, b, c int) {
131+
r[c] = r[a] | b
132+
}
133+
134+
func Setr(r *Regs, a, b, c int) {
135+
r[c] = r[a]
136+
}
137+
138+
func Seti(r *Regs, a, b, c int) {
139+
r[c] = a
140+
}
141+
142+
func Gtir(r *Regs, a, b, c int) {
143+
if a > r[b] {
144+
r[c] = 1
145+
} else {
146+
r[c] = 0
147+
}
148+
}
149+
150+
func Gtri(r *Regs, a, b, c int) {
151+
if r[a] > b {
152+
r[c] = 1
153+
} else {
154+
r[c] = 0
155+
}
156+
}
157+
158+
func Gtrr(r *Regs, a, b, c int) {
159+
if r[a] > r[b] {
160+
r[c] = 1
161+
} else {
162+
r[c] = 0
163+
}
164+
}
165+
166+
func Eqir(r *Regs, a, b, c int) {
167+
if a == r[b] {
168+
r[c] = 1
169+
} else {
170+
r[c] = 0
171+
}
172+
}
173+
174+
func Eqri(r *Regs, a, b, c int) {
175+
if r[a] == b {
176+
r[c] = 1
177+
} else {
178+
r[c] = 0
179+
}
180+
}
181+
182+
func Eqrr(r *Regs, a, b, c int) {
183+
if r[a] == r[b] {
184+
r[c] = 1
185+
} else {
186+
r[c] = 0
187+
}
188+
}

0 commit comments

Comments
 (0)