advent-of-code/2021/python/day05.py

80 lines
2.3 KiB
Python

import shared
from pprint import pprint as pp
from matrix import matrix_of_size
class Vents:
def __init__(self, name):
self.width = 0
self.height = 0
self.parse(name)
self.matrix = matrix_of_size(self.width + 1, self.height + 1)
def parse(self, name):
def _split_line(line):
one, two = line.split(" -> ")
coords = list(map(int, one.split(","))), list(map(int, two.split(",")))
(x1, y1), (x2, y2) = coords
# set grid size
if max(x1, x2) > self.width:
self.width = max(x1, x2)
if max(y1, y2) > self.height:
self.height = max(y1, y2)
return coords
with open(name, "r") as f:
self.coords = [_split_line(x.rstrip()) for x in f.readlines() if x.rstrip()]
def draw_lines(self):
for coords in self.coords:
self.draw_line(*coords)
def draw_line(self, pos1, pos2):
x1, y1 = pos1
x2, y2 = pos2
if x1 == x2: # Straight
self.draw_horizontal_x(x1, (y1, y2))
elif y1 == y2: # Straight
self.draw_horizontal_y((x1, x2), y1)
else: # diagonal
self.draw_diagonal((x1, x2), (y1, y2))
def draw_horizontal_x(self, x, y_coords):
coords = sorted(y_coords)
for y in range(coords[0], coords[1] + 1):
self.matrix[y][x] += 1
def draw_horizontal_y(self, x_coords, y):
coords = sorted(x_coords)
for x in range(coords[0], coords[1] + 1):
self.matrix[y][x] += 1
def draw_diagonal(self, x_coords, y_coords):
coords = self.generate_diagonal(*x_coords, *y_coords)
for x, y in coords:
self.matrix[y][x] += 1
def generate_diagonal(self, x1, x2, y1, y2):
x_dir, y_dir = 1, 1
if x2 < x1:
x_dir = -1
if y2 < y1:
y_dir = -1
new_y = range(y1 + y_dir, y2, y_dir)
new_x = range(x1 + x_dir, x2, x_dir)
return [(x1, y1), *list(zip(new_x, new_y)), (x2, y2)]
def count(self):
return len([item for sublist in self.matrix for item in sublist if item > 1])
def main():
v = Vents(shared.get_fname(5))
v.draw_lines()
pp(v.count())
if __name__ == "__main__":
main()