123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- import math, sequtils, strutils
-
- type
- Point = array[2, int]
-
- func read_coords(text: string): seq[Point] =
- for line in text.strip.splitlines:
- let parts = line.split(", ").map(parseInt)
- result &= [parts[0], parts[1]]
-
- func bounds(coords: seq[Point]): array[4, int] =
- let
- xs = coords.map(proc(coord: Point): int = coord[0])
- ys = coords.map(proc(coord: Point): int = coord[1])
- result = [min(xs), max(xs), min(ys), max(ys)]
-
- func distance(point1: Point, point2: Point): int = abs(point1[0] - point2[0]) + abs(point1[1] - point2[1])
-
- func nearest(coords: seq[Point], point: Point): int =
- var
- min = -1
- best = -1
- dupe = false
- i = 0
-
- for coord in coords:
- let distance = coord.distance(point)
- if min == -1 or distance < min:
- min = distance
- best = i
- dupe = false
- elif min == distance:
- dupe = true
- i += 1
-
- if dupe:
- result = -1
- else:
- result = best
-
- func inrange(coords: seq[Point], point: Point): bool = coords.map(proc (coord: Point): int = coord.distance(point)).sum < 10000
-
- let
- coords = read_coords(readFile("data/06.txt"))
- extents = coords.bounds
-
- var
- counts = newSeqWith(coords.len, 0)
- excluded = newSeqWith(coords.len, false)
-
- for x in extents[0] .. extents[1]:
- for y in extents[2] .. extents[3]:
- let coord = coords.nearest([x, y])
- if coord != -1:
- counts[coord] += 1
- if x == extents[0] or x == extents[1] or y == extents[2] or y == extents[3]:
- excluded[coord] = true
-
- echo zip(counts, excluded)
- .filter(proc(x: tuple[a: int, b: bool]): bool = not x.b)
- .map(proc(x: tuple[a: int, b: bool]): int = x.a)
- .max
-
-
- var size = 0
- let
- extension = int(10000 / coords.len)
- y_start = extents[2] - extension
- y_finish = extents[3] + extension
- y_range = y_finish - y_start
-
- for x in extents[0] - extension .. extents[1] + extension:
- var
- min_y = 0
- max_y = 0
- for y in extents[2] - extension .. extents[3] + extension:
- if coords.inrange([x,y]):
- min_y = y
- break
- for dy in 0 .. y_range:
- var y = y_finish - dy
- if coords.inrange([x,y]):
- max_y = y + 1
- break
- size += abs(max_y - min_y)
-
- echo size
|