52 lines
2.1 KiB
Python
52 lines
2.1 KiB
Python
|
|
import itertools
|
||
|
|
from collections import defaultdict, Counter
|
||
|
|
|
||
|
|
from solutions import BaseSolution
|
||
|
|
|
||
|
|
|
||
|
|
class Solution(BaseSolution):
|
||
|
|
input_file = '06.in'
|
||
|
|
|
||
|
|
def __str__(self):
|
||
|
|
return 'Day 6: Chronal Coordinates'
|
||
|
|
|
||
|
|
def solve(self, puzzle_input):
|
||
|
|
locations = [tuple(map(int, pi.split(', '))) for pi in puzzle_input.splitlines()]
|
||
|
|
finite_locations, cols, rows = self._location_boundaries(locations)
|
||
|
|
closest = defaultdict(int)
|
||
|
|
for coordinate in itertools.product(cols, rows):
|
||
|
|
distances = self._manhattan_distance(coordinate, locations)
|
||
|
|
closest[coordinate] = '.' if distances[0][1] == distances[1][1] else distances[0][0]
|
||
|
|
_location, count = [lc for lc in Counter(closest.values()).most_common() if lc[0] not in finite_locations][0]
|
||
|
|
return count
|
||
|
|
|
||
|
|
def solve_again(self, puzzle_input):
|
||
|
|
return self.get_region(puzzle_input, 10000)
|
||
|
|
|
||
|
|
def get_region(self, puzzle_input, max_distance):
|
||
|
|
locations = [tuple(map(int, pi.split(', '))) for pi in puzzle_input.splitlines()]
|
||
|
|
finite_locations, cols, rows = self._location_boundaries(locations)
|
||
|
|
region = set()
|
||
|
|
for coordinate in itertools.product(cols, rows):
|
||
|
|
distances = self._manhattan_distance(coordinate, locations)
|
||
|
|
if sum(map(lambda x: x[1], distances)) < max_distance:
|
||
|
|
region.add(coordinate)
|
||
|
|
return len(region)
|
||
|
|
|
||
|
|
def _manhattan_distance(self, coordinate, locations):
|
||
|
|
distances = [(i, abs(abs(target[0] - coordinate[0]) + abs(target[1] - coordinate[1])))
|
||
|
|
for i, target in enumerate(locations)]
|
||
|
|
return sorted(distances, key=lambda x: x[1])
|
||
|
|
|
||
|
|
def _location_boundaries(self, locations):
|
||
|
|
min_width, min_height = map(min, zip(*locations))
|
||
|
|
max_width, max_height = map(max, zip(*locations))
|
||
|
|
finite_locations = [i for i, l in enumerate(locations) if l[0] not in (min_width, max_width)
|
||
|
|
and l[1] in (min_height, max_height)]
|
||
|
|
return finite_locations, range(min_width, max_width), range(min_height, max_height)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
solution = Solution()
|
||
|
|
solution.show_results()
|