Skip to content

Commit

Permalink
[2022][day 15] adding part 2 solution
Browse files Browse the repository at this point in the history
  • Loading branch information
IAjimi committed Dec 15, 2022
1 parent c1d42f7 commit 941b357
Showing 1 changed file with 67 additions and 28 deletions.
95 changes: 67 additions & 28 deletions 2022/AOC15.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,96 @@
from typing import List, Tuple, Set
import datetime
from typing import List, Tuple, Set, Dict
import parse
from _utils import read_input, timer, Solution, Point

from _utils import read_input, timer, Solution

MAX_Y = 4_000_000

SENSOR, BEACON = 1, -1

Y = 2_000_000


def process_input(filename: str):
def process_input(filename: str) -> Tuple[Dict[Point, int], Set[Point]]:
_input = read_input(filename)

import parse

grid = set()
empty = set()
sensors = {}
beacons = set()
for line in _input:
x1, y1, x2, y2 = tuple(
parse.parse(
"Sensor at x={:d}, y={:d}: closest beacon is at x={:d}, y={:d}", line
).fixed
)
grid.add((x1, y1))
grid.add((x2, y2))

distance = manhattan_distance((x1, y1), (x2, y2))
sensors[(x1, y1)] = manhattan_distance((x1, y1), (x2, y2))
beacons.add((x2, y2))
return sensors, beacons


def manhattan_distance(t1: Point, t2: Point) -> int:
x1, y1 = t1
x2, y2 = t2
return abs(x1 - x2) + abs(y1 - y2)


class Solution:
def merge(self, intervals: List[List[Point]]) -> List[List[Point]]:
intervals = sorted(intervals, key=lambda i: i[0])
l, r = 0, 1

while r <= len(intervals) - 1:
if intervals[l][0] <= intervals[r][0] <= intervals[l][1]:
intervals[l][0] = min(intervals[l][0], intervals[r][0])
intervals[l][1] = max(intervals[l][1], intervals[r][1])
del intervals[r]
else:
l += 1
r += 1

return intervals


def check_line(sensors: Dict[Point, int], Y: int, part1: bool) -> List[List[Point]]:
intervals = []

for pos, distance in sensors.items():
x1, y1 = pos
distance_to_y = abs(y1 - Y)
remaining_distance = distance - distance_to_y

if remaining_distance >= 0:
for dx in range(-remaining_distance, remaining_distance + 1):
empty.add((x1 + dx, Y))
if part1:
intervals.append([x1 - remaining_distance, x1 + remaining_distance])
else:
min_x = max(0, x1 - remaining_distance)
max_x = min(MAX_Y, x1 + remaining_distance)
if min_x <= MAX_Y:
intervals.append([min_x, max_x])

for pos in grid:
if pos in empty:
empty.remove(pos)
return len(empty)
return Solution().merge(intervals)


def manhattan_distance(t1, t2):
x1, y1 = t1
x2, y2 = t2
return abs(x1 - x2) + abs(y1 - y2)
def part1(sensors: Dict[Point, int]):
intervals = check_line(sensors, 2_000_000, part1=True)
interval_length = intervals[0][1] - intervals[0][0]
return interval_length


def part2(sensors: Dict[Point, int]):
for y in range(MAX_Y, 0, -1):
intervals = check_line(sensors, y, part1=False)
if len(intervals) != 1:
x = intervals[0][1] + 1
return x * MAX_Y + y
return 0


@timer
def main(filename: str) -> Solution:
grid = process_input(filename)
part_1_solution = grid
part_2_solution = 0
sensors, beacons = process_input(filename)
part_1_solution = part1(sensors)
part_2_solution = part2(sensors)
return part_1_solution, part_2_solution


if __name__ == "__main__":
part_1_solution, part_2_solution = main("aoc15.txt")
print(f"PART 1: {part_1_solution}") # 4907780
print(f"PART 2: {part_2_solution}") #
print(f"PART 2: {part_2_solution}") # 13639962836448 (3409990, 2836448)

0 comments on commit 941b357

Please sign in to comment.