advent-of-code/2021/nim/day9.nim

51 lines
1.6 KiB
Nim

import ./common, std/[strutils, sequtils, strformat, sugar, sets, math, algorithm]
proc toGrid(s: seq[string]): seq[seq[int]] =
for l in s: result.add(l.mapIt(int(it)-int('0')))
proc p1(c: seq[seq[int]]): int =
let h = c.len()
let w = c[0].len()
for y,l in c.pairs():
for x,n in l.pairs():
if x > 0 and c[y][x-1] <= n: continue
if y > 0 and c[y-1][x] <= n: continue
if x < w-1 and c[y][x+1] <= n: continue
if y < h-1 and c[y+1][x] <= n: continue
result += n + 1
proc p2(c: seq[seq[int]]): int =
let h = c.len()
let w = c[0].len()
var crawledPoints = toHashSet[(int, int)]([])
var basins: seq[int] = @[]
for y,l in c.pairs():
for x,n in l.pairs():
if crawledPoints.contains((x, y)): continue
crawledPoints.incl((x, y))
if n >= 9: continue
var eligiblePoints = toHashSet[(int, int)]([(x, y)])
var basin = 0
while eligiblePoints.len() > 0:
var newEligiblePoints = toHashSet[(int, int)]([])
for (cx,cy) in eligiblePoints:
inc basin
for (nx,ny) in [(cx-1,cy),(cx+1,cy),(cx,cy-1),(cx,cy+1)]:
if crawledPoints.contains((nx,ny)): continue
if nx >= 0 and nx < w and ny >= 0 and ny < h and c[ny][nx] < 9:
newEligiblePoints.incl((nx,ny))
crawledPoints.incl((nx,ny))
eligiblePoints = newEligiblePoints
basins.add(basin)
basins.sort(system.cmp[int], SortOrder.Descending)
basins[0] * basins[1] * basins[2]
doDay(9, (n) => n.loadInput().toGrid(),
p1,
p2,
"""2199943210
3987894921
9856789892
8767896789
9899965678""".split('\n').toGrid(), 15, 1134)