advent-of-code/2017/day19.nim

84 lines
2.0 KiB
Nim

import sequtils
import future
import nre except toSeq
type
Direction = enum
up = 0, left = 1, down = 2, right = 3
Grid = seq[seq[char]]
const directions = [up, left, down, right]
proc indexOf(hay: seq[char], needle: char): int =
# It almost seems weird that this doesn’t already exist...
# It probably does, and I just missed it. Whatever, no error handling because :lul:
var i = 0
while hay[i] != needle:
i += 1
return i
proc gridGet(g: Grid, p: array[2, int]): char =
return g[p[0]][p[1]]
proc changePosition(current: array[2, int], dir: Direction): array[2, int] =
if dir == up:
return [current[0]-1, current[1]]
if dir == left:
return [current[0], current[1]-1]
if dir == down:
return [current[0]+1, current[1]]
if dir == right:
return [current[0], current[1]+1]
proc oppositeDirection(d: Direction): Direction =
# the better solution would be something like
# mod(getEnumOrdinal(direction, $direction) + 2, 4)
# but that doesn’t quite work because I’m bad at this whole thing
case d
of up: return down
of left: return right
of down: return up
of right: return left
else: discard
proc changeDirection(g: Grid, pos: array[2, int], direction: Direction): Direction =
for d in directions:
if d != oppositeDirection(direction) and gridGet(g, changePosition(pos, d)) != ' ':
return d
let grid = lc[toSeq(line.items()) | (line <- lines("input.txt")), seq[char]]
var position = [0, indexOf(grid[0], '|')]
var direction = down
var done = false
var visited = ""
var newchar: char
var steps = 1
while not done:
#echo position[0], ", ", position[1]
#echo direction
var newpos = changePosition(position, direction)
newchar = gridGet(grid, newpos)
#echo(newchar)
if newchar in ['|', '-']:
inc steps
elif newchar == '+':
inc steps
direction = changeDirection(grid, newpos, direction)
elif nre.contains($newchar, re"[A-Z]"):
inc steps
visited &= newchar
elif newchar == ' ':
done = true
position = newpos
echo(visited)
echo(steps)