You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.3 KiB
Python
89 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
from pprint import pprint
|
|
|
|
with open('input.txt', 'r') as f:
|
|
coords = [x.strip().split(', ') for x in f.readlines()]
|
|
coords = [tuple(map(lambda y: int(y), x)) for x in coords]
|
|
|
|
# print(coords)
|
|
|
|
def distance(p1, p2):
|
|
"""Manhattan distance"""
|
|
return abs(p2[0] - p1[0]) + abs(p2[1] - p1[1])
|
|
|
|
def get_closest_idx(coords, point):
|
|
"""Returns the index of the point that is closest to the point or None"""
|
|
distances = [distance(x, point) for x in coords]
|
|
min_dist = min(distances)
|
|
return distances.index(min_dist) if distances.count(min_dist) == 1 else None
|
|
|
|
def is_infinite_area(coords, idx, delta=10000):
|
|
"""Determines if point coords[idx] has infinite area
|
|
|
|
A point has infinite area if it is closest to any of the four points:
|
|
* (x, y + delta)
|
|
* (x, y - delta)
|
|
* (x + delta, y)
|
|
* (x - delte, y)
|
|
"""
|
|
point = coords[idx]
|
|
far_points = [
|
|
(point[0], point[1] + delta),
|
|
(point[0], point[1] - delta),
|
|
(point[0] + delta, point[1]),
|
|
(point[0] - delta, point[1])
|
|
]
|
|
|
|
for far in far_points:
|
|
if get_closest_idx(coords, far) == idx:
|
|
return True
|
|
return False
|
|
|
|
def get_circle(point, radius):
|
|
"""Returns an array of all points with distance radius to point"""
|
|
if radius == 0:
|
|
return [point]
|
|
|
|
x = point[0]
|
|
y = point[1]
|
|
d_x = radius
|
|
d_y = 0
|
|
circle = list()
|
|
|
|
while d_y < radius:
|
|
circle.append((x + d_x, y + d_y))
|
|
circle.append((x - d_x, y - d_y))
|
|
circle.append((x + d_y, y - d_x))
|
|
circle.append((x - d_y, y + d_x))
|
|
|
|
d_x -= 1
|
|
d_y += 1
|
|
|
|
return circle
|
|
|
|
def main():
|
|
areas = list()
|
|
area_map = dict()
|
|
|
|
for idx, point in enumerate(coords):
|
|
if is_infinite_area(coords, idx):
|
|
continue
|
|
|
|
is_relevant = True
|
|
radius = 0
|
|
area = 0
|
|
while is_relevant:
|
|
# print(f'Radius {radius}')
|
|
is_relevant = False
|
|
for p2 in get_circle(point, radius):
|
|
if idx == get_closest_idx(coords, p2):
|
|
is_relevant = True
|
|
area += 1
|
|
radius += 1
|
|
areas.append(area)
|
|
print(f'Point {point}: Area: {area}')
|
|
|
|
print('Largest Area', max(areas))
|
|
main()
|