adventOfCode/challenges/2021/05-hydrothermalVenture/nim/challenge.nim
AKU d87ba9053c
nimpretty
Signed-off-by: AKU <tom@tdpain.net>
2021-12-06 21:20:45 +00:00

84 lines
1.8 KiB
Nim

import std/tables
import std/sequtils
import std/strutils
type
Point = object
x: int
y: int
Line = (Point, Point)
proc pointFromString(instr: string): Point =
let
parts = instr.split(",")
x = parts[0].parseInt
y = parts[1].parseInt
return Point(x: x, y: y)
proc parse(instr: string): seq[Line] =
for line in instr.strip.splitLines:
let parts = line.split(" -> ")
result.add((
pointFromString(parts[0]), pointFromString(parts[1])
))
proc removeDiagonalLines(lines: seq[Line]): seq[Line] =
return lines.filter(
proc(line: Line): bool = line[0].x == line[1].x or line[0].y == line[
1].y,
)
iterator iteratePoints(line: Line): Point =
let
(p1, p2) = line
deltaX = p2.x - p1.x
deltaY = p2.y - p1.y
var
xStep: int
yStep: int
if deltaX > 0:
xStep = 1
elif deltaX < 0:
xStep = -1
if deltaY > 0:
yStep = 1
elif deltaY < 0:
yStep = -1
var lastPoint = p1
yield p1
while lastPoint != p2:
let np = Point(
x: lastPoint.x + xStep,
y: lastPoint.y + yStep,
)
yield np
lastPoint = np
proc countOverlappingPoints(lines: seq[Line]): int =
var areas = initTable[Point, int]()
for line in lines:
for point in iteratePoints(line):
let nextValue = areas.getOrDefault(point, 0) + 1
areas[point] = nextValue
for count in areas.values:
if count > 1:
result += 1
proc partOne*(instr: string): int =
return instr.
parse.
removeDiagonalLines.
countOverlappingPoints
proc partTwo*(instr: string): int =
return instr.
parse.
countOverlappingPoints