83 lines
1.9 KiB
Nim
83 lines
1.9 KiB
Nim
import
|
|
../../adventofcode,
|
|
hashes,
|
|
sequtils,
|
|
strutils,
|
|
strformat,
|
|
tables
|
|
|
|
type
|
|
Grid = TableRef[Point, int]
|
|
|
|
HydrothermalVent = object
|
|
x1, y1, x2, y2: int
|
|
|
|
Point = object
|
|
x, y: int
|
|
|
|
## https://stackoverflow.com/questions/919612/mapping-two-integers-to-one-in-a-unique-and-deterministic-way
|
|
#[
|
|
A = a >= 0 ? 2 * a : -2 * a - 1;
|
|
B = b >= 0 ? 2 * b : -2 * b - 1;
|
|
A >= B ? A * A + A + B : A + B * B;
|
|
]#
|
|
proc hash(p: Point): Hash =
|
|
let A =
|
|
if p.x >= 0: 2 * p.x
|
|
else: -2 * p.x - 1
|
|
let B =
|
|
if p.y >= 0: 2 * p.y
|
|
else: -2 * p.y - 1
|
|
return
|
|
if A >= B: A * A + A + B
|
|
else: A + B * B
|
|
|
|
proc getPoints(v: HydrothermalVent): seq[Point] =
|
|
let xOffset = v.x2 - v.x1
|
|
let yOffset = v.y2 - v.y1
|
|
let xd = xOffset.abs()
|
|
let yd = yOffset.abs()
|
|
|
|
if xd != 0 and v.y1 == v.y2:
|
|
for i in 0 .. xd:
|
|
result.add Point(x: min(v.x1, v.x2) + i, y: v.y1)
|
|
|
|
elif yd != 0 and v.x1 == v.x2:
|
|
for i in 0 .. yd:
|
|
result.add Point(x: v.x1, y: min(v.y1, v.y2) + i)
|
|
|
|
else:
|
|
when defined(second):
|
|
assert xd == yd
|
|
|
|
for i in 0 .. xd:
|
|
result.add Point(
|
|
x:
|
|
if xOffset > 0: min(v.x1, v.x2) + i
|
|
else: max(v.x1, v.x2) - i,
|
|
y:
|
|
if yOffset > 0: min(v.y1, v.y2) + i
|
|
else: max(v.y1, v.y2) - i
|
|
)
|
|
|
|
proc parseInput(input: string): seq[HydrothermalVent] =
|
|
for line in input.splitLines()[0 .. ^2]:
|
|
let coords = line.split(" -> ").mapIt(it.split(",").mapIt(it.parseInt()))
|
|
result.add HydrothermalVent(
|
|
x1: coords[0][0], y1: coords[0][1], x2: coords[1][0], y2: coords[1][1]
|
|
)
|
|
|
|
let input = adventofcode.getInput(2021, 5)
|
|
let vents = input.parseInput()
|
|
let grid = Grid()
|
|
|
|
for vent in vents:
|
|
let points = vent.getPoints()
|
|
for point in points:
|
|
if not grid.hasKey point:
|
|
grid[point] = 1
|
|
else:
|
|
grid[point] += 1
|
|
|
|
let overlappingPoints = toSeq(grid.values).countIt(it > 1)
|
|
echo fmt"Answer: {overlappingPoints}" |