diff --git a/2021/nine.nim b/2021/nine.nim index 527ff41..26e4f29 100644 --- a/2021/nine.nim +++ b/2021/nine.nim @@ -1,4 +1,4 @@ -import ./common, std/[strutils, sequtils, strformat, sugar, sets, math] +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'))) @@ -14,11 +14,37 @@ proc p1(c: seq[seq[int]]): int = 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, - p1, + p2, """2199943210 3987894921 9856789892 8767896789 -9899965678""".split('\n').toGrid(), 15, 15) +9899965678""".split('\n').toGrid(), 15, 1134)