40 lines
1.5 KiB
Plaintext
40 lines
1.5 KiB
Plaintext
(function :Array<Line> parseLines [file]
|
|
(for textLine (Util.readLines file)
|
|
(let [[p1 p2] (textLine.split " -> ")
|
|
[x1 y1] (map (p1.split ",") Std.parseInt)
|
|
[x2 y2] (map (p2.split ",") Std.parseInt)]
|
|
(objectWith x1 y1 x2 y2))))
|
|
|
|
// An inclusive range whose start may be greater than its end
|
|
(function :Array<Int> inclusiveRange [start end]
|
|
(let [s (min start end)
|
|
e (max start end)]
|
|
(let [r (collect (range s (+ e 1)))]
|
|
(if (> start end)
|
|
(reverse r)
|
|
r))))
|
|
|
|
(function :Array<Point> pointsCoveredBy [:Line line :Bool part2]
|
|
(cond
|
|
((= line.x1 line.x2)
|
|
(for y (inclusiveRange line.y1 line.y2) [line.x1 y]))
|
|
((= line.y1 line.y2)
|
|
(for x (inclusiveRange line.x1 line.x2) [x line.y1]))
|
|
// Diagonal lines:
|
|
(part2
|
|
(cast (zipThrow (inclusiveRange line.x1 line.x2) (inclusiveRange line.y1 line.y2))))
|
|
(true
|
|
[])))
|
|
|
|
(function :Map<String,Int64> ventsByPos [file :Bool part2]
|
|
(let [lines (parseLines file)
|
|
:Map<String,Int64> theMap (new Map)]
|
|
(doFor line lines
|
|
(doFor point (pointsCoveredBy line part2)
|
|
(dictInc theMap (Std.string point) 1)))
|
|
theMap))
|
|
|
|
(function :Int numHotPositions [file &opt :Bool part2]
|
|
(let [theMap (ventsByPos file ?part2)
|
|
two (Int64Helper.fromFloat 2)]
|
|
(count theMap ->vents #{ vents >= two; }#))) |