Skip to content

Commit 43ba19f

Browse files
committed
day 15
1 parent 41264aa commit 43ba19f

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

Diff for: 15/sample-input.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
2+
Sensor at x=9, y=16: closest beacon is at x=10, y=16
3+
Sensor at x=13, y=2: closest beacon is at x=15, y=3
4+
Sensor at x=12, y=14: closest beacon is at x=10, y=16
5+
Sensor at x=10, y=20: closest beacon is at x=10, y=16
6+
Sensor at x=14, y=17: closest beacon is at x=10, y=16
7+
Sensor at x=8, y=7: closest beacon is at x=2, y=10
8+
Sensor at x=2, y=0: closest beacon is at x=2, y=10
9+
Sensor at x=0, y=11: closest beacon is at x=2, y=10
10+
Sensor at x=20, y=14: closest beacon is at x=25, y=17
11+
Sensor at x=17, y=20: closest beacon is at x=21, y=22
12+
Sensor at x=16, y=7: closest beacon is at x=15, y=3
13+
Sensor at x=14, y=3: closest beacon is at x=15, y=3
14+
Sensor at x=20, y=1: closest beacon is at x=15, y=3

Diff for: 15/solve.py

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import re
2+
3+
from dataclasses import dataclass
4+
from itertools import chain
5+
from operator import attrgetter
6+
from sys import argv as args
7+
8+
path = args[1] if len(args) >= 2 else "sample-input.txt"
9+
with open(path) as f:
10+
lines = f.read().splitlines()
11+
12+
@dataclass(frozen=True)
13+
class Point:
14+
x : int
15+
y : int
16+
17+
def distance(self, other):
18+
return abs(self.x - other.x) + abs(self.y - other.y)
19+
20+
@dataclass(frozen=True)
21+
class Sensor:
22+
pos : Point
23+
beacon_pos : Point
24+
25+
def in_range(self, p):
26+
return self.pos.distance(p) <= self.pos.distance(self.beacon_pos)
27+
28+
sensors = []
29+
beacons = set()
30+
31+
for line in lines:
32+
nums = [int(x) for x in re.findall("[-\d]+", line)]
33+
beacon = Point(nums[2], nums[3])
34+
beacons.add(beacon)
35+
sensors.append(Sensor(
36+
pos =Point(nums[0], nums[1]),
37+
beacon_pos=beacon
38+
))
39+
40+
Y = 2000000
41+
42+
xlo = min(chain((s.pos.x for s in sensors), (s.beacon_pos.x for s in sensors))) * 2
43+
xhi = max(chain((s.pos.x for s in sensors), (s.beacon_pos.x for s in sensors))) * 2
44+
45+
count = 0
46+
for x in range(xlo, xhi + 1):
47+
p = Point(x, Y)
48+
49+
if p in beacons:
50+
continue
51+
52+
if any(s.in_range(p) for s in sensors):
53+
count += 1
54+
55+
print(count)
56+
57+
@dataclass(frozen=True)
58+
class Range:
59+
lo : int
60+
hi : int
61+
62+
def analyze_column(x):
63+
ranges = []
64+
for sensor in sensors:
65+
xDelta = abs(sensor.pos.x - x)
66+
distance = sensor.pos.distance(sensor.beacon_pos)
67+
yPos = sensor.pos.y
68+
yDelta = distance - xDelta
69+
70+
yLo = yPos - yDelta
71+
yHi = yPos + yDelta
72+
if yLo <= yHi:
73+
ranges.append(Range(yLo, yHi))
74+
75+
ranges.sort(key=attrgetter("lo"))
76+
77+
for i in range(len(ranges) - 1):
78+
r1 = ranges[i]
79+
r2 = ranges[i + 1]
80+
maybe_gap = r1.hi < r2.lo - 1
81+
if maybe_gap:
82+
gap_y = r1.hi + 1
83+
if all(gap_y < r.lo or gap_y > r.hi for r in ranges):
84+
return Point(x, gap_y)
85+
return None
86+
87+
def tuning_frequency(p):
88+
return p.x * 4000000 + p.y
89+
90+
for x in range(4000001):
91+
p = analyze_column(x)
92+
if p:
93+
print(tuning_frequency(p))
94+
break

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ Organized in a fairly self-explanatory way; `01` has the first day and so on. My
2020
| Day 12 | `00:18:51` | `00:22:30` |
2121
| Day 13 | `00:09:30` | `00:15:29` |
2222
| Day 14 | `00:18:18` | `00:21:25` |
23+
| Day 15 | `00:15:43` | `00:40:24` |
2324

0 commit comments

Comments
 (0)