advent/2018/06.py

102 lines
2.4 KiB
Python
Raw Normal View History

2018-12-08 22:44:57 +00:00
from collections import Counter, defaultdict
import string
import pdb
with open('data/06.txt') as f:
data = []
for line in f:
x, y = line.strip().split(', ')
data.append((int(x), int(y)))
# data = {(1, 1), (1, 6), (8, 3), (3, 4), (5, 5), (8, 9)}
def distance(a, b):
(x1, y1), (x2, y2) = a, b
return abs(x1 - x2) + abs(y1 - y2)
def iter_grid(points):
xmin = ymin = float('inf')
xmax = ymax = 0
for x, y in points:
if x < xmin: xmin = x
if x > xmax: xmax = x
if y < ymin: ymin = y
if y > ymax: ymax = y
for y in range(ymin, ymax + 1):
for x in range(xmin, xmax + 1):
edge = x == xmin or x == xmax or y == ymin or y == ymax
yield (x, y), edge
has_infinite_region = set()
grid = {}
collisions = defaultdict(list)
coords = Counter()
total_distances = {}
for point, edge in iter_grid(data):
total = 0
distances = {}
for coord in data:
d = distance(point, coord)
total += d
distances[coord] = d
total_distances[point] = total
closest_coords = []
min_dist = float('inf')
for coord, dist in sorted(distances.items(), key=lambda d: d[1]):
if dist > min_dist:
break
closest_coords.append(coord)
min_dist = dist
if len(closest_coords) == 1:
c = closest_coords[0]
grid[point] = c
coords[c] += 1
if edge:
has_infinite_region.add(c)
else:
for c in closest_coords:
collisions[point].append(c)
'''
plane = []
xmin = ymin = float('inf')
xmax = ymax = 0
for x, y in data:
if x < xmin: xmin = x
if x > xmax: xmax = x
if y < ymin: ymin = y
if y > ymax: ymax = y
for y in range(ymax + 2):
plane.append(['.'] * (xmax + 2))
reps = {coord: name for coord, name in zip(data, string.printable)}
# reps = {(1, 1): 'a', (1, 6): 'b', (8, 3): 'c', (3, 4): 'd', (5, 5): 'e', (8, 9): 'f'}
for (x, y), coord in grid.items():
if (x, y) == coord:
name = ' '
else:
name = reps[coord]
plane[y][x] = name
s = '\n'.join(''.join(row) for row in plane)
with open('grid.txt', 'w', encoding='utf-8') as f:
f.write(s)
'''
for coord, size in coords.most_common():
if coord not in has_infinite_region:
print(f'Part 1: {size}\n')
break
print(f'Part 2: {sum(1 for d in total_distances.values() if d < 10000)}\n')
pdb.set_trace()