-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
57 lines (40 loc) · 1.84 KB
/
main.py
File metadata and controls
57 lines (40 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import time
def pos(p):
return tuple(map(int, p.split("at ")[1].strip().replace("x=", "").replace("y=", "").split(", ")))[::-1]
def parse(sensor, beacon):
return pos(sensor), pos(beacon)
def man_dist(sensor, beacon):
return abs(sensor[0]-beacon[0]) + abs(sensor[1]-beacon[1])
def main(input_file, stage, example):
sensor_map, blocked, boundaries = {}, set(), (2000000 if not example else 10) * stage
with open(input_file, "r") as f:
sensor_map = {s: (b, man_dist(s, b)) for s, b in [parse(*scan.split(":")) for scan in f.readlines()]}
rows = range(boundaries, boundaries+1) if stage == 1 else range(0, boundaries+1)
for questioned_row in rows:
blocked = set()
for sensor in sensor_map.keys():
dist_to_row = abs(sensor[0] - questioned_row)
if dist_to_row > sensor_map[sensor][1]:
continue
blocked_spots = (sensor_map[sensor][1] - dist_to_row ) * 2 + 1
blocked.add((sensor[1] - (blocked_spots-1)//2, sensor[1] + (blocked_spots-1)//2))
blocked = list(sorted(blocked, key=lambda x: (x[0], x[1])))
while len(blocked) > 1:
b1 = blocked.pop(0)
b2 = blocked.pop(0)
if (b1[0] <= b2[0] and b1[1] >= b2[0]) or b1[1]+1 == b2[0]:
blocked.insert(0, (b1[0], b2[1] if b2[1] > b1[1] else b1[1]))
continue
print((b1[1]+1) * 4000000 + questioned_row)
return
blocked = list(blocked)[0]
print(blocked[1]-blocked[0])
if __name__ == "__main__":
use_example = False
file_name = "example" if use_example else "input"
start = time.time()
main(file_name, 1, use_example)
print(f"Stage 1 time: {time.time() - start}")
start = time.time()
main(file_name, 2, use_example)
print(f"Stage 2 time: {time.time() - start}")