My solutions to 2018's advent of code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import math, sequtils, strutils
  2. type
  3. Point = array[2, int]
  4. func read_coords(text: string): seq[Point] =
  5. for line in text.strip.splitlines:
  6. let parts = line.split(", ").map(parseInt)
  7. result &= [parts[0], parts[1]]
  8. func bounds(coords: seq[Point]): array[4, int] =
  9. let
  10. xs = coords.map(proc(coord: Point): int = coord[0])
  11. ys = coords.map(proc(coord: Point): int = coord[1])
  12. result = [min(xs), max(xs), min(ys), max(ys)]
  13. func distance(point1: Point, point2: Point): int = abs(point1[0] - point2[0]) + abs(point1[1] - point2[1])
  14. func nearest(coords: seq[Point], point: Point): int =
  15. var
  16. min = -1
  17. best = -1
  18. dupe = false
  19. i = 0
  20. for coord in coords:
  21. let distance = coord.distance(point)
  22. if min == -1 or distance < min:
  23. min = distance
  24. best = i
  25. dupe = false
  26. elif min == distance:
  27. dupe = true
  28. i += 1
  29. if dupe:
  30. result = -1
  31. else:
  32. result = best
  33. func inrange(coords: seq[Point], point: Point): bool = coords.map(proc (coord: Point): int = coord.distance(point)).sum < 10000
  34. let
  35. coords = read_coords(readFile("data/06.txt"))
  36. extents = coords.bounds
  37. var
  38. counts = newSeqWith(coords.len, 0)
  39. excluded = newSeqWith(coords.len, false)
  40. for x in extents[0] .. extents[1]:
  41. for y in extents[2] .. extents[3]:
  42. let coord = coords.nearest([x, y])
  43. if coord != -1:
  44. counts[coord] += 1
  45. if x == extents[0] or x == extents[1] or y == extents[2] or y == extents[3]:
  46. excluded[coord] = true
  47. echo zip(counts, excluded)
  48. .filter(proc(x: tuple[a: int, b: bool]): bool = not x.b)
  49. .map(proc(x: tuple[a: int, b: bool]): int = x.a)
  50. .max
  51. var size = 0
  52. let
  53. extension = int(10000 / coords.len)
  54. y_start = extents[2] - extension
  55. y_finish = extents[3] + extension
  56. y_range = y_finish - y_start
  57. for x in extents[0] - extension .. extents[1] + extension:
  58. var
  59. min_y = 0
  60. max_y = 0
  61. for y in extents[2] - extension .. extents[3] + extension:
  62. if coords.inrange([x,y]):
  63. min_y = y
  64. break
  65. for dy in 0 .. y_range:
  66. var y = y_finish - dy
  67. if coords.inrange([x,y]):
  68. max_y = y + 1
  69. break
  70. size += abs(max_y - min_y)
  71. echo size