70 lines
1.6 KiB
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)
|