From 4a12de2729f223b706c2e7094a03d985c670318d Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Thu, 15 Dec 2022 07:36:26 +0100 Subject: [PATCH] day15 - needs serious optimizations --- day15.py | 104 ++++++++++++++++++++++++++++++++++++++++++++ inputs/input15 | 23 ++++++++++ inputs/input15_test | 14 ++++++ 3 files changed, 141 insertions(+) create mode 100644 day15.py create mode 100644 inputs/input15 create mode 100644 inputs/input15_test diff --git a/day15.py b/day15.py new file mode 100644 index 0000000..0338cd9 --- /dev/null +++ b/day15.py @@ -0,0 +1,104 @@ +from collections import defaultdict + +from tools.aoc import AOCDay +from typing import Any + + +def flatten(what: set) -> set: + found_something = True + while found_something: + found_something = False + liqlist = [] + for c in what: + for c2 in liqlist: + if c[0] <= c2[0] and c[1] >= c2[1]: + found_something = True + c2[0] = c[0] + c2[1] = c[1] + elif c[0] >= c2[0] and c[1] <= c2[1]: + found_something = True + break + elif c2[0] <= c[1] < c2[1]: + found_something = True + c2[0] = c[0] + break + elif c2[0] <= c[0] < c2[1]: + found_something = True + c2[1] = c[1] + break + else: + liqlist.append([c[0], c[1]]) + + what = set((x[0], x[1]) for x in liqlist) + + return what + + +class Day(AOCDay): + inputs = [ + [ + (26, "input15_test"), + (6275922, "input15"), + ], + [ + (56000011, "input15_test"), + (11747175442119, "input15"), + ] + ] + + def get_sensor_beacon_dict(self): + sensors = {} + for line in self.getInput(): + sp = line.split(" ") + sx, sy, bx, by = sp[2], sp[3], sp[8], sp[9] + sx = int(sx[2:-1]) + sy = int(sy[2:-1]) + bx = int(bx[2:-1]) + by = int(by[2:]) + sensors[(sx, sy)] = (bx, by) + + return sensors + + def part1(self) -> Any: + liq = 10 if self._current_test_file.endswith("_test") else 2000000 + liqset = set() + for sensor, beacon in self.get_sensor_beacon_dict().items(): + d = abs(sensor[0] - beacon[0]) + abs(sensor[1] - beacon[1]) + if sensor[1] - d > liq > sensor[1] + d: + continue + + r = 2 * (d - abs(sensor[1] - liq)) + 1 + if r < 1: + continue + x_min, x_max = sensor[0] - r // 2, sensor[0] + r // 2 + liqset.add((x_min, x_max)) + + liqset = flatten(liqset) + return sum(x[1] - x[0] for x in liqset) + + def part2(self) -> Any: + max_c = 20 if self._current_test_file.endswith("_test") else 4000000 + occ = defaultdict(set) + for sensor, beacon in self.get_sensor_beacon_dict().items(): + d = abs(sensor[0] - beacon[0]) + abs(sensor[1] - beacon[1]) + for y in range(-d, d + 1): + r = 2 * (d - abs(y)) + 1 + if 0 <= sensor[1] + y <= max_c: + occ[sensor[1] + y].add((max(0, sensor[0] - r // 2), min(sensor[0] + r // 2, max_c))) + + for y, occs in occ.items(): + occs = flatten(occs) + assert len(occs) in [1, 2] + if len(occs) == 2: + f = list(occs) + min_y = min(x[1] for x in f) + max_x = max(x[0] for x in f) + if max_x - min_y == 2: + return (min_y + 1) * 4000000 + y + + return "" + + +if __name__ == '__main__': + day = Day(2022, 15) + day.run(verbose=True) diff --git a/inputs/input15 b/inputs/input15 new file mode 100644 index 0000000..4fe9d5e --- /dev/null +++ b/inputs/input15 @@ -0,0 +1,23 @@ +Sensor at x=3289936, y=2240812: closest beacon is at x=3232809, y=2000000 +Sensor at x=30408, y=622853: closest beacon is at x=-669401, y=844810 +Sensor at x=3983196, y=3966332: closest beacon is at x=3232807, y=4625568 +Sensor at x=929672, y=476353: closest beacon is at x=-669401, y=844810 +Sensor at x=1485689, y=3597734: closest beacon is at x=1951675, y=3073734 +Sensor at x=69493, y=1886070: closest beacon is at x=-669401, y=844810 +Sensor at x=2146060, y=3999371: closest beacon is at x=2300657, y=4128792 +Sensor at x=3228558, y=3890086: closest beacon is at x=3232807, y=4625568 +Sensor at x=3031444, y=2295853: closest beacon is at x=2928827, y=2611422 +Sensor at x=374444, y=3977240: closest beacon is at x=-888612, y=4039783 +Sensor at x=1207660, y=2710720: closest beacon is at x=1951675, y=3073734 +Sensor at x=3851310, y=61626: closest beacon is at x=4807592, y=976495 +Sensor at x=3195193, y=3022787: closest beacon is at x=2928827, y=2611422 +Sensor at x=1784895, y=2111901: closest beacon is at x=1951675, y=3073734 +Sensor at x=2894075, y=2427030: closest beacon is at x=2928827, y=2611422 +Sensor at x=3301867, y=803327: closest beacon is at x=3232809, y=2000000 +Sensor at x=2506616, y=3673347: closest beacon is at x=2300657, y=4128792 +Sensor at x=2628426, y=3054377: closest beacon is at x=1951675, y=3073734 +Sensor at x=2521975, y=1407505: closest beacon is at x=3232809, y=2000000 +Sensor at x=2825447, y=2045173: closest beacon is at x=3232809, y=2000000 +Sensor at x=2261212, y=2535886: closest beacon is at x=2928827, y=2611422 +Sensor at x=3956000, y=1616443: closest beacon is at x=3232809, y=2000000 +Sensor at x=3870784, y=2872668: closest beacon is at x=2928827, y=2611422 diff --git a/inputs/input15_test b/inputs/input15_test new file mode 100644 index 0000000..a612424 --- /dev/null +++ b/inputs/input15_test @@ -0,0 +1,14 @@ +Sensor at x=2, y=18: closest beacon is at x=-2, y=15 +Sensor at x=9, y=16: closest beacon is at x=10, y=16 +Sensor at x=13, y=2: closest beacon is at x=15, y=3 +Sensor at x=12, y=14: closest beacon is at x=10, y=16 +Sensor at x=10, y=20: closest beacon is at x=10, y=16 +Sensor at x=14, y=17: closest beacon is at x=10, y=16 +Sensor at x=8, y=7: closest beacon is at x=2, y=10 +Sensor at x=2, y=0: closest beacon is at x=2, y=10 +Sensor at x=0, y=11: closest beacon is at x=2, y=10 +Sensor at x=20, y=14: closest beacon is at x=25, y=17 +Sensor at x=17, y=20: closest beacon is at x=21, y=22 +Sensor at x=16, y=7: closest beacon is at x=15, y=3 +Sensor at x=14, y=3: closest beacon is at x=15, y=3 +Sensor at x=20, y=1: closest beacon is at x=15, y=3