aboutsummaryrefslogtreecommitdiffstats
path: root/day10/solution.nim
blob: 42776963640fe8f98869d74dbbad21ebeb7bce47 (plain) (blame)
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()