Nim
Could be done more elegantly, but I haven’t bothered yet.
proc solve(input: string): AOCSolution[int, int] =
var lines = input.splitLines()
block p1:
# horiz
for line in lines:
for i in 0..line.high-3:
if line[i..i+3] in ["XMAS", "SAMX"]:
inc result.part1
for y in 0..lines.high-3:
#vert
for x in 0..lines[0].high:
let word = collect(for y in y..y+3: lines[y][x])
if word in [@"XMAS", @"SAMX"]:
inc result.part1
#diag \
for x in 0..lines[0].high-3:
let word = collect(for d in 0..3: lines[y+d][x+d])
if word in [@"XMAS", @"SAMX"]:
inc result.part1
#diag /
for x in 3..lines[0].high:
let word = collect(for d in 0..3: lines[y+d][x-d])
if word in [@"XMAS", @"SAMX"]:
inc result.part1
block p2:
for y in 0..lines.high-2:
for x in 0..lines[0].high-2:
let diagNW = collect(for d in 0..2: lines[y+d][x+d])
let diagNE = collect(for d in 0..2: lines[y+d][x+2-d])
if diagNW in [@"MAS", @"SAM"] and diagNE in [@"MAS", @"SAM"]:
inc result.part2