import matrix import math from pprint import pprint import shared from scanf import scanf from dataclasses import dataclass from scipy.spatial.distance import cityblock def manhattan(a, b): return abs(b[0] - a[0]) + abs(b[1] - a[1]) @dataclass class Sensor: sX: int sY: int bX: int bY: int @property def s(self): return (self.sY, self.sX) @property def b(self): return (self.bY, self.bX) @property def distance(self): a,b = zip(self.s, self.b) return cityblock(a, b) def distance_to(self, y,x): a,b = zip(self.s, (y,x)) return cityblock(a, b) #@shared.profile def part1(rows): CHECK_ROW = 10 CHECK_ROW = 2000000 sensors = [] sensor_points = [] beacon_points = [] xSet = set() ySet = set() for row in rows: x,y,bx,by = scanf("Sensor at x=%d, y=%d: closest beacon is at x=%d, y=%d", row) xSet.add(x) xSet.add(bx) ySet.add(y) ySet.add(by) sensors.append(Sensor(sX=x,sY=y,bX=bx,bY=by)) minX, maxX = min(xSet),max(xSet) minY, maxY = min(ySet),max(ySet) for sensor in sensors: sensor_points.append(sensor.s) beacon_points.append(sensor.b) ineligible = set() for x in range(minX,maxX): point = (CHECK_ROW, x) if x % 10000 == 0: print(point) if point in beacon_points: continue if point in sensor_points: continue for s in sensors: d = s.distance_to(*point) if d <= s.distance: ineligible.add(point) pprint(ineligible) print(len(ineligible)) # mx[sensor.sY][sensor.sX] = "S" # mx[sensor.bY][sensor.bX] = "B" #@shared.profile def part2(rows): pass def main(): rows = [row for row in shared.load_rows(15)] with shared.elapsed_timer() as elapsed: part1(rows) print("🕒", elapsed()) with shared.elapsed_timer() as elapsed: part2(rows) print("🕒", elapsed()) if __name__ == "__main__": main()