-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpart2.py
91 lines (72 loc) · 2.45 KB
/
part2.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
##############
# Read Input #
##############
def readInput():
directions = {
">": (0, 1),
"<": (0, -1),
"^": (-1, 0),
"v": (1, 0),
}
with open('input') as f:
f = [line.strip() for line in f]
height = len(f)
width = len(f[0])
blizzards = []
for y, line in enumerate(f[1:-1], 1):
for i, c in enumerate(line[1:-1], 1):
if c in "><^v":
blizzards.append(((y, i), directions[c]))
return height, width, blizzards
def solve(height, width, blizzards):
start = (0, 1)
target = (height - 1, width - 2)
areas = set()
for y in range(1, height - 1):
for x in range(1, width - 1):
areas.add((y, x))
areas.add(start)
areas.add(target)
targets = [target, start, target]
curr_target = targets.pop(0)
records = []
queue = {(start, 0)}
seen = set()
goal = False
while queue:
if not goal:
temp = []
for bliz_pos, bliz_dir in blizzards:
if bliz_dir[0] == 0:
new_pos = (bliz_pos[0], (bliz_pos[1] + bliz_dir[1] + width - 3) % (width - 2) + 1)
else:
new_pos = ((bliz_pos[0] + bliz_dir[0] + height - 3) % (height - 2) + 1, bliz_pos[1])
temp.append((new_pos, bliz_dir))
blizzards = temp
avaliable_areas = areas - set([i[0] for i in blizzards])
goal = False
new_queue = set()
for pos, history in queue:
if pos == curr_target:
records += [history]
if targets:
curr_target = targets.pop(0)
# new_queue = [(pos, [])]
new_queue = {(pos, 0)}
seen = set()
goal = True
break
else:
return str(sum(records))
state = (pos, history)
if state in seen:
continue
seen.add(state)
for d in [(0, 1), (1, 0), (0, -1), (-1, 0), (0, 0)]:
new_pos = (pos[0] + d[0], pos[1] + d[1])
if new_pos in avaliable_areas:
new_queue.add((new_pos, history + 1))
queue = new_queue
if __name__ == '__main__':
height, width, blizzards = readInput()
print("Part 2 : " + solve(height, width, blizzards))