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