123456789101112131415161718192021222324252627282930313233343536373839404142 |
- 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, end = segment
- delta_x = end.x - start.x
- delta_y = end.y - start.y
- sign_x = int(math.copysign(1, end.x - start.x)) if abs(delta_x) > 0 else 0
- sign_y = int(math.copysign(1, end.y - start.y)) if abs(delta_y) > 0 else 0
- for d in range(0, max(abs(delta_x), abs(delta_y)) + 1):
- board[start.y + sign_y * d][start.x + sign_x * d] += 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))
|