-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday17.um
85 lines (71 loc) · 1.97 KB
/
day17.um
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
import "std.um"
type Regs = struct {
a, b, c: uint
}
fn getcombo(regs: Regs, op: uint): uint {
tbl := [7]uint{0, 1, 2, 3, regs.a, regs.b, regs.c}
return tbl[op]
}
fn run(program: []uint, regs: Regs, ip: int): int {
out := 0
for ip < len(program) {
instr, op := program[ip], program[ip+1]
ip += 2
switch instr {
case 0: regs.a = regs.a>>getcombo(regs, op)
case 1: regs.b = regs.b~op
case 2: regs.b = getcombo(regs, op)&7
case 3: if regs.a != 0 { ip = op }
case 4: regs.b = regs.b~regs.c
case 5: out = out<<3|(getcombo(regs, op)&7)
case 6: regs.b = regs.a>>getcombo(regs, op)
case 7: regs.c = regs.a>>getcombo(regs, op)
}
}
return out
}
fn find(program: []uint, progstr: int, regs: Regs, a, octet: int): int {
mask := (1<<(octet*3))-1
for i := 0; i < 8; i++ {
regs.a = a<<3|i
match := run(program, regs, 0)
if match == progstr {
return regs.a
}
if match == progstr&mask {
next := find(program, progstr, regs, regs.a, octet+1)
if next > 0 {
return next
}
}
}
return 0
}
fn main() {
a, b, c := 0, 0, 0
scanf("Register A: %lld\nRegister B: %lld\nRegister C: %lld\nProgram: ", &a, &b, &c)
regs := Regs{a, b, c}
regs.a = a
program := []uint{}
programstr := 0
trailingzeros := 0
for n := 0; scanf("%lld", &n) == 1 {
program = append(program, n)
programstr = programstr<<3|n&7
if n == 0 && programstr == 0 {
trailingzeros++
}
scanf(",")
}
out := run(program, regs, 0)
p1 := ""
for out > 0 {
p1 = char(out&7+int('0'))+p1
out >>= 3
if out>0 {
p1 = ","+p1
}
}
printf("Part 1: %s\n", p1)
printf("Part 2: %v\n", find(program, programstr, regs, 0, 1)<<(3*trailingzeros))
}