summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-12-11 17:25:23 +0000
committerTomasz Kramkowski <tk@the-tk.com>2021-12-11 17:25:23 +0000
commitf755290feb0227dbc76c60becd3f8d746d64af52 (patch)
tree69ad5b278b2a79e9041b229f7af1669c9147a244
parentffffebd680e545204d8ac6695a66fb21692273a5 (diff)
downloadaoc2021-f755290feb0227dbc76c60becd3f8d746d64af52.tar.gz
aoc2021-f755290feb0227dbc76c60becd3f8d746d64af52.tar.xz
aoc2021-f755290feb0227dbc76c60becd3f8d746d64af52.zip
day 11: nim
-rw-r--r--d11.nim76
1 files changed, 76 insertions, 0 deletions
diff --git a/d11.nim b/d11.nim
new file mode 100644
index 0000000..73ddfe3
--- /dev/null
+++ b/d11.nim
@@ -0,0 +1,76 @@
+import std/os, std/sugar, std/strutils, std/sequtils
+
+type
+ OctoState = Natural
+ Map = tuple[map: seq[OctoState], width: int, height: int]
+
+proc read_map(filename: string): Map =
+ let f = open(filename)
+ defer: f.close()
+ result.map = collect:
+ for line in f.lines():
+ result.width = line.len
+ result.height += 1
+ for c in line:
+ (c.ord - '0'.ord).OctoState
+
+proc print_map(map: Map) =
+ for y in countup(0, map.height - 1):
+ for x in countup(0, map.width - 1):
+ stdout.write(('0'.ord + map.map[x + map.width * y]).char)
+ stdout.write('\n')
+
+proc solve(map: Map): tuple[part1, part2: int] =
+ var
+ current = map.map
+ flashed = new_seq[bool](current.len)
+ flash = new_seq[bool](current.len)
+ flashes = 0
+ for step in 1..1000:
+ #print_map((current, map.width, map.height))
+ #echo ""
+ flashed.apply(proc(_: bool): bool = false)
+ current.apply(proc(s: OctoState): OctoState = s + 1)
+ while true:
+ var any = false
+ flash.apply(proc(_: bool): bool = false)
+ for i, s in current:
+ if flashed[i] or s <= 9: continue
+ flashed[i] = true
+ flash[i] = true
+ any = true
+ if not any: break
+ for i, s in flash:
+ if not s: continue
+ let
+ x = i mod map.width
+ y = i div map.width
+ for dy in countup(-1, 1):
+ for dx in countup(-1, 1):
+ if dx == 0 and dy == 0: continue
+ let
+ x = x + dx
+ y = y + dy
+ if x < 0 or x >= map.width: continue
+ if y < 0 or y >= map.height: continue
+ inc current[x + map.width * y]
+ var sum = 0
+ for i, s in flashed:
+ if not s: continue
+ current[i] = 0
+ inc sum
+ flashes += sum
+ if step == 100:
+ result.part1 = flashes
+ if sum == map.width * map.height:
+ result.part2 = step
+ break
+
+when is_main_module:
+ var filename: string = "11.in"
+ if param_count() == 1:
+ filename = param_str(1)
+ let map = read_map(filename)
+ let (part1, part2) = solve(map)
+ echo part1
+ echo part2