-
Notifications
You must be signed in to change notification settings - Fork 3
/
day18.nim
83 lines (71 loc) · 1.87 KB
/
day18.nim
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
import strutils, deques
const rawInstructions = readFile("./inputs/18.txt").splitLines
type
Instruction = tuple
command: char
switch: bool
register, value: int
Registers = array[26, int]
var
first_reg, x_reg, y_reg: Registers
first_i, x_i, y_i: int
x_queue = initDeque[int]()
y_queue = initDeque[int]()
sentCounter: int
instructions: array[41, Instruction]
r, v: int
for i, line in rawInstructions:
let c = line[1] # second letter of a command is unique
r = ord(line[4]) - ord('a')
var s: bool
if line.len > 5:
if line[6].isAlphaAscii:
s = true
v = ord(line[6]) - ord('a')
else:
v = parseInt(line[6 .. line.high])
instructions[i] = (c, s, r, v)
proc solve(reg: var Registers, i: var int, id = 'x', firstPart = false): int =
var
c: char
s: bool
r, val, v: int
while i < instructions.len:
(c, s, r, val) = instructions[i]
v = if s: reg[val] else: val
case c
of 'e': reg[r] = v
of 'd': reg[r] += v
of 'u': reg[r] *= v
of 'o': reg[r] = reg[r] mod v
of 'g':
if i == 33 or reg[r] > 0:
i += v; continue
of 'n':
if firstPart:
result = reg[r]
elif id == 'x':
y_queue.addLast(reg[r])
else:
inc sentCounter
x_queue.addLast(reg[r])
of 'c':
if firstPart:
if reg[r] != 0:
return result
elif id == 'x' and x_queue.len > 0:
reg[r] = x_queue.popFirst
elif id == 'y' and y_queue.len > 0:
reg[r] = y_queue.popFirst
else:
return i
else: discard
inc i
echo solve(first_reg, first_i, firstPart = true)
y_reg[ord('p') - ord('a')] = 1
x_i = solve(x_reg, x_i, 'x')
y_i = solve(y_reg, y_i, 'y')
while x_queue.len > 0 or y_queue.len > 0:
x_i = solve(x_reg, x_i, 'x')
y_i = solve(y_reg, y_i, 'y')
echo sentCounter