diff --git a/2023/day14.nim b/2023/day14.nim new file mode 100644 index 0000000..7200cbe --- /dev/null +++ b/2023/day14.nim @@ -0,0 +1,108 @@ +import std/algorithm +import std/deques +import std/enumerate +import std/math +import std/options +import std/sequtils +import std/sets +import std/strscans +import std/strutils +import std/sugar +import std/tables +import std/terminal + +proc dbg[T](v: T): T = (echo(v); v) + +func empty[T](v: seq[T]): bool = v.len == 0 + +proc split[T](v: seq[T], pred: proc(elt: T): bool): seq[seq[T]] = + var current: seq[T] + for elt in v: + if pred(elt): + result.add current + current = @[] + else: + current.add elt + result.add current + +func join[T](parts: seq[seq[T]], sep: T): seq[T] = + if parts.len > 0: + result &= parts[0] + + for part in parts[1..^1]: + result.add sep + result &= part + +type Point = tuple + r: int + c: int + +type Platform = object + height: int + width: int + + grid: Table[Point, char] + + rows: seq[seq[char]] + cols: seq[seq[char]] + +func parsePlatform(text: string): Platform = + let lines = text.strip.splitLines() + result.height = lines.len + result.width = lines[0].len + + for r in 0 ..< result.height: + result.rows.add @[] + + for c in 0 ..< result.width: + result.cols.add @[] + + for (r, line) in enumerate(lines): + for (c, sym) in enumerate(line): + result.grid[(r, c)] = sym + result.rows[r] &= @[sym] + result.cols[c] &= @[sym] + +proc fromCols(cols: seq[seq[char]]): Platform = + result.cols = cols + result.width = cols.len + result.height = cols[0].len + + for r in 0 ..< result.height: + result.rows.add @[] + + for (c, col) in enumerate(cols): + for (r, sym) in enumerate(col): + result.grid[(r, c)] = sym + result.rows[r] &= @[sym] + +func render(p: Platform): string = + p.rows.mapIt(it.mapIt($it).join("")).join("\n") + +proc tiltNorth(col: seq[char]): seq[char] = + let parts = col.split(func (sym: char): bool = sym == '#') + var rolled: seq[seq[char]] + for part in parts: + rolled.add part.sorted(Descending) + result = rolled.join('#') + +proc tiltNorth(p: Platform): Platform = + var cols: seq[seq[char]] + for col in p.cols: + cols.add col.tiltNorth + fromCols(cols) + +proc loadNorth(platform: Platform): int = + for (p, sym) in platform.grid.pairs: + if sym != 'O': continue + result.inc (platform.height - p.r) + +proc part1(input: string): int = + let text = readFile(input) + let platform = parsePlatform(text) + platform.tiltNorth.loadNorth + +echo part1("input/test.txt") +echo part1("input/day14.txt") +# echo part2("input/test.txt") +# echo part2("input/day14.txt")