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

70 lines
1.6 KiB
Nim

import ./common, std/[sequtils, algorithm, sugar, sets, strformat, strutils, tables]
type
Axis = enum X, Y
Points = HashSet[(int, int)]
Fold = (Axis, int)
Folds = seq[Fold]
proc parse(input: Lines): (Points, Folds) =
var parsingFolds = false
for l in input.mapIt it.strip:
if l == "": parsingFolds = true; continue
if not parsingFolds:
let coords = l.split(',').map parseInt
result[0].incl (coords[0], coords[1])
else:
result[1].add ((if l.contains 'x': X else: Y), l.split('=')[1].parseInt)
proc printPoints(points: Points): void =
var w, h = 0
for (x, y) in points:
w = max(w, x)
h = max(h, y)
var lines: Lines = @[]
for y in 0..h: lines.add(' '.repeat(w+1))
for (x, y) in points: lines[y][x] = '#'
for l in lines: echo l
proc doFold(points: Points, f: Fold): Points =
let (axis, n) = f
for (x, y) in points:
if (axis == X and x > n): result.incl((n - (x - n), y))
elif (axis == Y and y > n):
result.incl((x, n - (y - n)))
else: result.incl((x, y))
proc p1(input: Lines): int =
let (points, folds) = input.parse()
points.doFold(folds[0]).len()
proc p2(input: Lines): int =
let (points, folds) = input.parse()
folds.reduce((points: Points, fold) => points.doFold(fold), points).printPoints()
echo "You'll have to read this one on your own, captain."
const input = @[
"6,10",
"0,14",
"9,10",
"0,3",
"10,4",
"4,11",
"6,0",
"6,12",
"4,1",
"0,13",
"10,12",
"3,4",
"3,0",
"8,4",
"1,10",
"2,14",
"8,10",
"9,0",
"",
"fold along y=7",
"fold along x=5",
]
doDay 13, n => n.loadInput, p1, p2, (input, 17, 0)