diff --git a/2022/day15.py b/2022/day15.py new file mode 100644 index 0000000..f2c141c --- /dev/null +++ b/2022/day15.py @@ -0,0 +1,51 @@ +# -*- encoding: utf-8 -*- + +import sys + +import numpy as np +import parse +from docplex.mp.model import Model + +lines = sys.stdin.read().splitlines() + +sensor_to_beacon: dict[tuple[int, int], tuple[int, int]] = {} + +for line in lines: + r = parse.parse( + "Sensor at x={sx}, y={sy}: closest beacon is at x={bx}, y={by}", line + ) + sensor_to_beacon[int(r["sx"]), int(r["sy"])] = (int(r["bx"]), int(r["by"])) + +xy_max = 4_000_000 if max(sensor_to_beacon) > (1_000, 0) else 20 +row = 2_000_000 if max(sensor_to_beacon) > (1_000, 0) else 10 + +no_beacons_row_l: list[np.ndarray] = [] + +for (sx, sy), (bx, by) in sensor_to_beacon.items(): + d = abs(sx - bx) + abs(sy - by) # closest + + no_beacons_row_l.append(sx - np.arange(0, d - abs(sy - row) + 1)) + no_beacons_row_l.append(sx + np.arange(0, d - abs(sy - row) + 1)) + +beacons_at_row = set(bx for (bx, by) in sensor_to_beacon.values() if by == row) +no_beacons_row = set(np.concatenate(no_beacons_row_l)).difference(beacons_at_row) + +print(f"answer 1 is {len(no_beacons_row)}") + +# === part 2 === + +m = Model() + +x, y = m.continuous_var_list(2, ub=xy_max, name=["x", "y"]) + +for (sx, sy), (bx, by) in sensor_to_beacon.items(): + d = abs(sx - bx) + abs(sy - by) + m.add_constraint(m.abs(x - sx) + m.abs(y - sy) >= d + 1, ctname=f"ct_{sx}_{sy}") + +m.set_objective("min", x + y) + +s = m.solve() + +# 10621647166538 +answer_2 = 4_000_000 * int(s.get_value(x)) + int(s.get_value(y)) +print(f"answer 2 is {answer_2}") diff --git a/2022/inputs/day15.txt b/2022/inputs/day15.txt new file mode 100644 index 0000000..81d039a --- /dev/null +++ b/2022/inputs/day15.txt @@ -0,0 +1,30 @@ +Sensor at x=2332081, y=2640840: closest beacon is at x=2094728, y=2887414 +Sensor at x=3048293, y=3598671: closest beacon is at x=3872908, y=3598272 +Sensor at x=2574256, y=3973583: closest beacon is at x=2520711, y=4005929 +Sensor at x=3011471, y=2514567: closest beacon is at x=2999559, y=2558817 +Sensor at x=3718881, y=2593817: closest beacon is at x=2999559, y=2558817 +Sensor at x=2388052, y=2201955: closest beacon is at x=2163809, y=1961540 +Sensor at x=3783125, y=3897169: closest beacon is at x=3872908, y=3598272 +Sensor at x=1864613, y=3918152: closest beacon is at x=2520711, y=4005929 +Sensor at x=2850099, y=689863: closest beacon is at x=3231146, y=2000000 +Sensor at x=3431652, y=2328669: closest beacon is at x=3231146, y=2000000 +Sensor at x=3480248, y=3999492: closest beacon is at x=3872908, y=3598272 +Sensor at x=455409, y=3347614: closest beacon is at x=-399822, y=4026621 +Sensor at x=2451938, y=2950107: closest beacon is at x=2094728, y=2887414 +Sensor at x=1917790, y=3194437: closest beacon is at x=2094728, y=2887414 +Sensor at x=3947393, y=3625984: closest beacon is at x=3872908, y=3598272 +Sensor at x=1615064, y=2655330: closest beacon is at x=2094728, y=2887414 +Sensor at x=3630338, y=1977851: closest beacon is at x=3231146, y=2000000 +Sensor at x=3878266, y=3019867: closest beacon is at x=3872908, y=3598272 +Sensor at x=2837803, y=2395749: closest beacon is at x=2999559, y=2558817 +Sensor at x=3979396, y=3697962: closest beacon is at x=3872908, y=3598272 +Sensor at x=109399, y=250528: closest beacon is at x=929496, y=-688981 +Sensor at x=2401381, y=3518884: closest beacon is at x=2520711, y=4005929 +Sensor at x=3962391, y=71053: closest beacon is at x=5368730, y=-488735 +Sensor at x=1751119, y=97658: closest beacon is at x=929496, y=-688981 +Sensor at x=2932155, y=2967347: closest beacon is at x=2999559, y=2558817 +Sensor at x=3326630, y=2845463: closest beacon is at x=2999559, y=2558817 +Sensor at x=3959042, y=1734156: closest beacon is at x=3231146, y=2000000 +Sensor at x=675279, y=1463916: closest beacon is at x=2163809, y=1961540 +Sensor at x=3989603, y=3500749: closest beacon is at x=3872908, y=3598272 +Sensor at x=1963470, y=2288355: closest beacon is at x=2163809, y=1961540