-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path20_RaceCondition.py
96 lines (68 loc) · 2.03 KB
/
20_RaceCondition.py
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import collections
from lib import *
G = get_input()
sy,sx = find_grid(G, "S")
ey,ex = find_grid(G, "E")
def get_end_map():
Q = collections.deque([(ey,ex,0)])
SEEN = set()
DIST = collections.defaultdict(lambda: float("inf"))
while Q:
y,x,d = Q.popleft()
if (y,x) in SEEN:
continue
SEEN.add((y,x))
if G[y][x] == "#":
continue
DIST[y,x] = d
for yy,xx in iterate_positions(y,x, get_positions(diagonal=False), G):
Q.append((yy,xx,d+1))
return DIST
def find_path(sy,sx):
SEEN = set()
Q = collections.deque([(sy,sx,0,[])])
while Q:
y,x,d,path = Q.popleft()
if (y,x) in SEEN:
continue
SEEN.add((y,x))
path.append((y,x))
if (y,x) == (ey,ex):
return d, path
for yy,xx in iterate_positions(y,x, get_positions(diagonal=False), G):
if G[y][x] == "#":
continue
Q.append((yy,xx,d+1,list(path)))
def find_cheats(sy,sx,max_cheat):
Q = collections.deque([(sy,sx,0)])
SEEN = set()
res = collections.defaultdict(set)
while Q:
y,x,d = Q.popleft()
if (y,x) in SEEN:
continue
SEEN.add((y,x))
if d > max_cheat:
continue
for yy,xx in iterate_positions(y,x, get_positions(diagonal=False), G):
Q.append((yy,xx,d+1))
if G[y][x] != "#" and d>1:
res[(y,x)].add(d)
return [(y,x,min(d)) for (y,x),d in res.items()]
def get_combined_dist(sd, cheat):
cy, cx, cd = cheat
dist = sd + cd + END_DIST[(cy,cx)]
return WITHOUT_CHEAT - dist
WITHOUT_CHEAT, PATH = find_path(sy,sx)
END_DIST = get_end_map()
p1 = 0
p2 = 0
for sd, (y,x) in enumerate(PATH):
for cheat in find_cheats(y,x,2):
if get_combined_dist(sd, cheat) >= (10 if IS_EXAMPLE else 100):
p1 += 1
for cheat in find_cheats(y,x,20):
if get_combined_dist(sd, cheat) >= (50 if IS_EXAMPLE else 100):
p2 += 1
print(p1)
print(p2)