136 lines
3.2 KiB
Python
136 lines
3.2 KiB
Python
|
#!/usr/bin/env python
|
||
|
# 2021 - Advent Of Code - 5 part 2
|
||
|
|
||
|
def parse_file(file):
|
||
|
horizontal_lines = []
|
||
|
vertical_lines = []
|
||
|
diagonal_lines = []
|
||
|
with open(file) as f:
|
||
|
for l in f.readlines():
|
||
|
p1, p2 = l.strip().split(' -> ')
|
||
|
strx1, stry1 = p1.split(',')
|
||
|
strx2, stry2 = p2.split(',')
|
||
|
|
||
|
# filter horizontal and vertical lines only
|
||
|
p1 = (int(strx1), int(stry1))
|
||
|
p2 = (int(strx2), int(stry2))
|
||
|
if strx1 == strx2:
|
||
|
vertical_lines.append([p1, p2])
|
||
|
elif stry1 == stry2:
|
||
|
horizontal_lines.append([p1, p2])
|
||
|
else:
|
||
|
diagonal_lines.append([p1, p2])
|
||
|
|
||
|
return horizontal_lines, vertical_lines, diagonal_lines
|
||
|
|
||
|
|
||
|
def draw_horizontal(g, hline):
|
||
|
|
||
|
# print(f'drawing hline: {hline}')
|
||
|
if hline[0][0] < hline[1][0]: # left -> right
|
||
|
start_point = hline[0]
|
||
|
end_point = hline[1]
|
||
|
else:
|
||
|
start_point = hline[1]
|
||
|
end_point = hline[0]
|
||
|
|
||
|
ly = start_point[1]
|
||
|
# print(f'drawing from {start_point[0]} to {end_point[0]}')
|
||
|
for lx in range(start_point[0], end_point[0]+1):
|
||
|
g[ly][lx] += 1
|
||
|
|
||
|
|
||
|
def draw_vertical(g, vline):
|
||
|
# print(f'drawing vline: {vline}')
|
||
|
if vline[0][1] < vline[1][1]: # up -> down
|
||
|
start_point = vline[0]
|
||
|
end_point = vline[1]
|
||
|
else:
|
||
|
start_point = vline[1]
|
||
|
end_point = vline[0]
|
||
|
|
||
|
lx = start_point[0]
|
||
|
# print(f'drawing from {start_point[0]} to {end_point[0]}')
|
||
|
for ly in range(start_point[1], end_point[1]+1):
|
||
|
g[ly][lx] += 1
|
||
|
|
||
|
|
||
|
def draw_diagonal(g, dline):
|
||
|
x1 = dline[0][0]
|
||
|
y1 = dline[0][1]
|
||
|
x2 = dline[1][0]
|
||
|
y2 = dline[1][1]
|
||
|
|
||
|
hdir = 1
|
||
|
if x1 > x2:
|
||
|
hdir = -1
|
||
|
|
||
|
vdir = 1
|
||
|
if y1 > y2:
|
||
|
vdir = -1
|
||
|
|
||
|
lx = x1
|
||
|
ly = y1
|
||
|
for i in range(abs(x2-x1)+1):
|
||
|
g[ly][lx] += 1
|
||
|
lx += hdir
|
||
|
ly += vdir
|
||
|
|
||
|
|
||
|
hlines, vlines, dlines = parse_file('input.txt')
|
||
|
print(f'horizontal lines parsed: {len(hlines)}')
|
||
|
print(f'vertical lines parsed: {len(vlines)}')
|
||
|
print(f'diagonal lines parsed: {len(dlines)}')
|
||
|
|
||
|
# detect size of the grid (assumed 1000x1000, but why not ;-) )
|
||
|
maxx = 0
|
||
|
maxy = 0
|
||
|
for line in hlines + vlines + dlines:
|
||
|
startp = line[0]
|
||
|
endp = line[1]
|
||
|
if startp[0] > maxx:
|
||
|
maxx = startp[0]
|
||
|
if endp[0] > maxx:
|
||
|
maxx = endp[0]
|
||
|
if startp[1] > maxy:
|
||
|
maxy = startp[1]
|
||
|
if endp[1] > maxy:
|
||
|
maxy = endp[1]
|
||
|
|
||
|
print(f'detected grid size: {maxx} x {maxy}')
|
||
|
grid = [[0] * (maxx+1) for _ in range(maxy+1)]
|
||
|
|
||
|
# draw
|
||
|
for hl in hlines:
|
||
|
draw_horizontal(grid, hl)
|
||
|
|
||
|
for vl in vlines:
|
||
|
draw_vertical(grid, vl)
|
||
|
|
||
|
for dl in dlines:
|
||
|
draw_diagonal(grid, dl)
|
||
|
|
||
|
# count points
|
||
|
points = 0
|
||
|
for y in range(maxy+1):
|
||
|
for x in range(maxx+1):
|
||
|
if grid[y][x] > 1:
|
||
|
points += 1
|
||
|
|
||
|
print(f'There\'s {points} points with at least two lines')
|
||
|
|
||
|
# bonus (or debug with the sample), draw the grid
|
||
|
# print(' ', end='')
|
||
|
# for y in range(maxy+1):
|
||
|
# print(y, end='')
|
||
|
# print()
|
||
|
#
|
||
|
# for y in range(maxy+1):
|
||
|
# print(f'{y} ', end='')
|
||
|
# for x in range(maxx+1):
|
||
|
# if grid[y][x] == 0:
|
||
|
# print('.', end='')
|
||
|
# else:
|
||
|
# print(str(grid[y][x]), end='')
|
||
|
# print()
|