Nim
import ../aoc, strutils
type
Cell* = tuple[x,y:int]
#the 8 grid direction
const directions : array[8, Cell] = [
(1, 0), (-1, 0),
(0, 1), ( 0,-1),
(1, 1), (-1,-1),
(1,-1), (-1, 1)
]
const xmas = "XMAS"
#part 1
proc searchXMAS*(grid:seq[string], x,y:int):int =
#search in all 8 directions (provided we can find a full match in that direction)
let w = grid[0].len
let h = grid.len
for dir in directions:
# check if XMAS can even fit
let xEnd = x + dir.x * 3
let yEnd = y + dir.y * 3
if xEnd < 0 or xEnd >= w or
yEnd < 0 or yEnd >= h:
continue;
#step along direction
var matches = 0
for s in 0..3:
if grid[y + dir.y * s][x + dir.x * s] == xmas[s]:
inc matches
if matches == xmas.len:
inc result
#part 2
proc isMAS(grid:seq[string], c, o:Cell):bool=
let ca : Cell = (c.x+o.x, c.y+o.y)
let cb : Cell = (c.x-o.x, c.y-o.y)
let a = grid[ca.y][ca.x]
let b = grid[cb.y][cb.x]
(a == 'M' and b == 'S') or (a == 'S' and b == 'M')
proc searchCrossMAS*(grid:seq[string], x,y:int):bool =
grid[y][x] == 'A' and
grid.isMAS((x,y), (1,1)) and
grid.isMAS((x,y), (1,-1))
proc solve*(input:string): array[2,int] =
let grid = input.splitLines
let w = grid[0].len
let h = grid.len
#part 1
for y in 0..<h:
for x in 0..<w:
result[0] += grid.searchXMAS(x, y)
#part 2, skipping borders
for y in 1..<h-1:
for x in 1..<w-1:
result[1] += (int)grid.searchCrossMAS(x, y)
Part 1 was done really quickly. Part 2 as well, but the result was not accepted…
Turns out +MAS isn’t actually a thing :P









Nim
I thought of doing a sort at first, but dismissed it for some reason, so I came up with this slow and bulky recursive backtracking thing which traverses the rules as a graph until it reaches a depth equal to the given sequence. Not my finest work, but it does solve the puzzle :)