This commit is contained in:
Tyrel Souza 2022-12-15 13:02:54 -05:00
parent 00acd198d1
commit 75fe308ae0

View File

@ -1,10 +1,16 @@
import matrix import matrix
import math import math
import sys
from pprint import pprint from pprint import pprint
import shared import shared
from scanf import scanf from scanf import scanf
from typing import Optional
from dataclasses import dataclass from dataclasses import dataclass
LIMIT = 4000000
#def fuckoff_ill_do_my_own_cityblock(y1,x1, y2,x2): #def fuckoff_ill_do_my_own_cityblock(y1,x1, y2,x2):
def cityblock(y1,x1, y2,x2): def cityblock(y1,x1, y2,x2):
return abs(y2-y1) + abs(x2-x1) return abs(y2-y1) + abs(x2-x1)
@ -15,6 +21,7 @@ class Sensor:
sY: int sY: int
bX: int bX: int
bY: int bY: int
_d: int = None
@property @property
def s(self): def s(self):
@ -26,7 +33,9 @@ class Sensor:
@property @property
def distance(self): def distance(self):
return cityblock(self.sY,self.sX, self.bY, self.bX) if self._d is None:
self._d = cityblock(self.sY,self.sX, self.bY, self.bX)
return self._d
def distance_to(self, bY, bX): def distance_to(self, bY, bX):
return cityblock(self.sY,self.sX, bY, bX) return cityblock(self.sY,self.sX, bY, bX)
@ -44,11 +53,93 @@ class Sensor:
return list(range(start[1],end[1]+1)) return list(range(start[1],end[1]+1))
def in_diamond(self):
sX,sY = self.sX, self.sY
up_lim = sY - self.distance
dn_lim = sY + self.distance
le_lim = sX - self.distance
ri_lim = sX + self.distance
u = (up_lim, sX)
d = (dn_lim, sX)
l = (sY, le_lim)
r = (sY, ri_lim)
infliction = 1
height = -1
for idx, x in enumerate(range(l[1],r[1]+1)):
height += infliction
if (sY, x) == self.s:
infliction = -1
for y in range(sY-height, sY+height+1):
yield (y,x)
def part1(rows, sample=False):
sensors = []
sensor_points = []
beacon_points = []
ineligible_points = set()
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)
#@shared.profile for sensor in sensors:
def part1(rows): sensor_points.append(sensor.s)
beacon_points.append(sensor.b)
if sample:
for yx in sensor.in_diamond():
ineligible_points.add(yx)
CHECK_ROW = 2000000
if sample:
CHECK_ROW = 10
ineligible = set()
for s in sensors:
coll = s.on_line(CHECK_ROW)
ineligible.update(coll)
count_ignoring_current_beacons = 0
for i in ineligible:
if (CHECK_ROW, i) not in beacon_points:
count_ignoring_current_beacons += 1
print(count_ignoring_current_beacons, "with removing beacons, final answer")
if not sample:
return
mx = matrix.matrix_of_size(maxX+1, maxY+1)
for yx in ineligible_points:
y,x = yx
if y >= 0 and x >= 0:
if y <= maxY and x <= maxX:
mx[y][x] = "#"
for yx in beacon_points:
y,x = yx
if y >= 0 and x >= 0:
if y <= maxY and x <= maxX:
mx[y][x] = "B"
for yx in sensor_points:
y,x = yx
if y >= 0 and x >= 0:
if y <= maxY and x <= maxX:
mx[y][x] = "S"
print(matrix.ppmx(mx, pad=False,space=True))
tuning = lambda y,x: y + (LIMIT * x)
def part2(rows):
sensors = [] sensors = []
sensor_points = [] sensor_points = []
beacon_points = [] beacon_points = []
@ -67,51 +158,34 @@ def part1(rows):
for sensor in sensors: for sensor in sensors:
beacon_points.append(sensor.b) beacon_points.append(sensor.b)
CHECK_ROW = 10 #coord_range = (0, LIMIT)
CHECK_ROW = 2000000 coord_range = (0, 20)
print(beacon_points)
print("")
ineligible = set() ineligible = set()
for s in sensors: for s in sensors:
coll = s.on_line(CHECK_ROW) coll = s.on_line(CHECK_ROW)
ineligible.update(coll) ineligible.update(coll)
#print(coll)
count_ignoring_current_beacons = 0 count_ignoring_current_beacons = 0
for i in ineligible: for i in ineligible:
if (CHECK_ROW, i) not in beacon_points: if (CHECK_ROW, i) not in beacon_points:
count_ignoring_current_beacons += 1 count_ignoring_current_beacons += 1
#print(ineligible)
print(len(ineligible), "without removing beacons")
print(count_ignoring_current_beacons, "with removing beacons, final answer") 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(): def main():
sample = False
if sys.argv[-1] == "--sample":
sample = True
rows = [row for row in shared.load_rows(15)] rows = [row for row in shared.load_rows(15)]
with shared.elapsed_timer() as elapsed: with shared.elapsed_timer() as elapsed:
part1(rows) part1(rows, sample)
print("🕒", elapsed()) print("🕒", elapsed())
with shared.elapsed_timer() as elapsed: #with shared.elapsed_timer() as elapsed:
part2(rows) # part2(rows)
print("🕒", elapsed()) # print("🕒", elapsed())
if __name__ == "__main__": if __name__ == "__main__":