part1.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import argparse
  2. from typing import List, Set, NamedTuple
  3. import pprint
  4. import functools
  5. import math
  6. class Point(NamedTuple):
  7. x: int
  8. y: int
  9. parser = argparse.ArgumentParser()
  10. parser.add_argument("ifile", type=argparse.FileType('r'))
  11. args = parser.parse_args()
  12. lines = [line.strip() for line in args.ifile.readlines()]
  13. # for some reason I can't just do `for (x, y) in thing.split(',')`
  14. # dunno why. works in the repl.
  15. line_segments = [[
  16. Point(int(thing.split(',')[0]), int(thing.split(',')[1])) for thing in line.split(' ')[::2]
  17. ] for line in lines]
  18. max_x = max(map(lambda p: p.x, [point for segment in line_segments for point in segment]))
  19. max_y = max(map(lambda p: p.y, [point for segment in line_segments for point in segment]))
  20. board = [[0 for _ in range(0, max_x + 1)] for _ in range(0, max_y + 1)]
  21. def draw_line(board: List[List[int]], segment: List[Point]):
  22. start = segment[0]
  23. end = segment[1]
  24. if start.x == end.x:
  25. delta_y = end.y - start.y
  26. for y in range(0, abs(delta_y) + 1):
  27. board[start.y + int(math.copysign(1, delta_y)) * y][start.x] += 1
  28. elif start.y == end.y:
  29. delta_x = end.x - start.x
  30. for x in range(0, abs(delta_x) + 1):
  31. board[start.y][start.x + int(math.copysign(1, delta_x)) * x] += 1
  32. return board
  33. finished_board = functools.reduce(draw_line, line_segments, board)
  34. print(functools.reduce(lambda acc, val: acc + 1 if val >= 2 else acc, [val for row in finished_board for val in row], 0))