123456789101112131415161718192021222324252627282930313233343536373839404142434445 |
- import argparse
- from typing import List, Set, NamedTuple
- import pprint
- import functools
- import math
- class Point(NamedTuple):
- x: int
- y: int
- parser = argparse.ArgumentParser()
- parser.add_argument("ifile", type=argparse.FileType('r'))
- args = parser.parse_args()
- lines = [line.strip() for line in args.ifile.readlines()]
- # for some reason I can't just do `for (x, y) in thing.split(',')`
- # dunno why. works in the repl.
- line_segments = [[
- Point(int(thing.split(',')[0]), int(thing.split(',')[1])) for thing in line.split(' ')[::2]
- ] for line in lines]
- max_x = max(map(lambda p: p.x, [point for segment in line_segments for point in segment]))
- max_y = max(map(lambda p: p.y, [point for segment in line_segments for point in segment]))
- board = [[0 for _ in range(0, max_x + 1)] for _ in range(0, max_y + 1)]
- def draw_line(board: List[List[int]], segment: List[Point]):
- start = segment[0]
- end = segment[1]
- if start.x == end.x:
- delta_y = end.y - start.y
- for y in range(0, abs(delta_y) + 1):
- board[start.y + int(math.copysign(1, delta_y)) * y][start.x] += 1
- elif start.y == end.y:
- delta_x = end.x - start.x
- for x in range(0, abs(delta_x) + 1):
- board[start.y][start.x + int(math.copysign(1, delta_x)) * x] += 1
- return board
- finished_board = functools.reduce(draw_line, line_segments, board)
- print(functools.reduce(lambda acc, val: acc + 1 if val >= 2 else acc, [val for row in finished_board for val in row], 0))
|