drawing
This commit is contained in:
parent
00acd198d1
commit
75fe308ae0
@ -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__":
|
||||
|
Loading…
Reference in New Issue
Block a user