lines = open("input.txt", "r").read().splitlines() def parse_lines(lines: list) -> (set, set): sensors = [] beacons = [] for line in lines: _, _, sx, sy, _, _, _, _, bx, by = line.split(" ") sensors.append((int(sx.split("=")[1][:-1]), int(sy.split("=")[1][:-1]))) beacons.append((int(bx.split("=")[1][:-1]), int(by.split("=")[1]))) return sensors, beacons def manhatten(a, b): return abs(a[0] - b[0]) + abs(a[1] - b[1]) def build_search_space(sensors, beacons): space = set() for sensor, beacon in zip(sensors, beacons): space.update(sensor_diamond(sensor, beacon)) return space def sensor_diamond(sensor, beacon): points = set() d = manhatten(sensor, beacon) xr = range(d + 2) yr = xr[::-1] xrneg = range(0, (d + 2) * -1, -1) yrneg = xrneg[::-1] for x, y, xneg, yneg in zip(xr, yr, xrneg, yrneg): points.add((sensor[0] + x, sensor[1] + y)) points.add((sensor[0] + xneg, sensor[1] + y)) points.add((sensor[0] + x, sensor[1] + yneg)) points.add((sensor[0] + xneg, sensor[1] + yneg)) return points def search_candidates(sensors, beacons, space): candidates = set() counter = 0 for point in space: is_candidate = False if x_min <= point[0] <= x_max and y_min <= point[1] <= y_max: is_candidate = True for sensor, beacon in zip(sensors, beacons): if manhatten(sensor, point) <= manhatten(sensor, beacon): is_candidate = False if is_candidate: print("candidate found") candidates.add(point) counter += 1 if counter % 100000 == 0: print(f"{counter} points searched") return candidates x_min, x_max = 0, 4000000 y_min, y_max = 0, 4000000 sensors, beacons = parse_lines(lines) space = build_search_space(sensors, beacons) print("space set up") candidates = search_candidates(sensors, beacons, space) print(candidates) x, y = candidates.pop() print(x * 4000000 + y)