advent-of-code/2018-python/solutions/day_06.py

52 lines
2.1 KiB
Python
Raw Normal View History

2021-11-01 16:40:46 +01:00
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()