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
|
import strutils
import sequtils
import sugar
type
Instruction = tuple
opcode: string
arg: int
Program = seq[Instruction]
func instructionFromString(str: string): Instruction =
let tokens = str.split()
let opcode = tokens[0]
var arg: int
if tokens.len() > 1:
arg = tokens[1].parseInt()
else:
arg = 0
(opcode, arg)
func parseProgram(content: seq[string]): Program =
result = map(
content,
(line) => instructionFromString(line)
)
proc checkSignal(cycle: int, x: int): int =
# cycle+1 because cycle is supposed to be starting at 0
if cycle+1 in [20, 60, 100, 140, 180, 220]:
result = x * (cycle+1)
var CRT: array[0 .. 5, array[0 .. 39, char]]
proc draw(cycle: int, x: int): void =
let
col = cycle mod 40
row = cycle div 40
if col in [x-1, x, x+1]:
CRT[row][col] = '#'
proc execute(program: Program): int =
var
x = 1
cycle = 0
for i, instr in program:
result += checkSignal(cycle, x)
draw(cycle, x)
case instr.opcode:
of "addx":
result += checkSignal(cycle+1, x)
draw(cycle+1, x)
x += instr.arg
cycle += 2
of "noop":
cycle += 1
else:
assert(false)
let content = readFile("./input.txt").strip().splitLines()
let program = parseProgram(content)
for row in 0 ..< 6:
for col in 0 ..< 40:
CRT[row][col] = ' '
echo execute(program)
for row in CRT:
echo row.join()
|