import matrix import math from pprint import pprint import shared from scanf import scanf from dataclasses import dataclass #def fuckoff_ill_do_my_own_cityblock(y1,x1, y2,x2): def cityblock(y1,x1, y2,x2): return abs(y2-y1) + abs(x2-x1) @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): return cityblock(self.sY,self.sX, self.bY, self.bX) def distance_to(self, bY, bX): return cityblock(self.sY,self.sX, bY, bX) def on_line(self, y): midpoint = (y,self.s[1]) d = self.distance_to(*midpoint) if d > self.distance: return [] need = self.distance - d start = (y, midpoint[1] - need) end = (y, midpoint[1] + need) return list(range(start[1],end[1]+1)) #@shared.profile def part1(rows): 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: beacon_points.append(sensor.b) CHECK_ROW = 10 CHECK_ROW = 2000000 print(beacon_points) print("") ineligible = set() for s in sensors: coll = s.on_line(CHECK_ROW) ineligible.update(coll) #print(coll) count_ignoring_current_beacons = 0 for i in ineligible: if (CHECK_ROW, i) not in beacon_points: count_ignoring_current_beacons += 1 #print(ineligible) print(len(ineligible), "without removing beacons") print(count_ignoring_current_beacons, "with removing beacons, final answer") # 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()