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 math
import sys
from pprint import pprint
import shared
from scanf import scanf
from typing import Optional
from dataclasses import dataclass
LIMIT = 4000000
#def fuckoff_ill_do_my_own_cityblock(y1,x1, y2,x2):
def cityblock(y1,x1, y2,x2):
return abs(y2-y1) + abs(x2-x1)
@ -15,6 +21,7 @@ class Sensor:
sY: int
bX: int
bY: int
_d: int = None
@property
def s(self):
@ -26,7 +33,9 @@ class Sensor:
@property
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):
return cityblock(self.sY,self.sX, bY, bX)
@ -44,11 +53,93 @@ class Sensor:
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
def part1(rows):
for sensor in sensors:
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 = []
sensor_points = []
beacon_points = []
@ -67,51 +158,34 @@ def part1(rows):
for sensor in sensors:
beacon_points.append(sensor.b)
CHECK_ROW = 10
CHECK_ROW = 2000000
#coord_range = (0, LIMIT)
coord_range = (0, 20)
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():
sample = False
if sys.argv[-1] == "--sample":
sample = True
rows = [row for row in shared.load_rows(15)]
with shared.elapsed_timer() as elapsed:
part1(rows)
part1(rows, sample)
print("🕒", elapsed())
with shared.elapsed_timer() as elapsed:
part2(rows)
print("🕒", elapsed())
#with shared.elapsed_timer() as elapsed:
# part2(rows)
# print("🕒", elapsed())
if __name__ == "__main__":