-
Notifications
You must be signed in to change notification settings - Fork 0
/
day20.py
118 lines (103 loc) · 3.69 KB
/
day20.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
from boilerplates import read_text_from_file
from astar import astar_with_portals
from copy import deepcopy
def get_adjecents(b, p):
l = r = u = d= "#"
try:
u = b[p[1] - 1][p[0]]
except:
pass
try:
r = b[p[1]][p[0] + 1]
except:
pass
try:
d = b[p[1] + 1][p[0]]
except:
pass
try:
l = b[p[1]][p[0] - 1]
except:
pass
return u, r, d, l
def print_board(b, s, e, p = None):
if p == None:
p = []
for y in range(len(b)):
row = ""
for x in range(len(b[y])):
if (x, y) == s:
row += "@"
elif (x, y) == e:
row += "="
elif (x, y) in p:
row += "O"
else:
row += b[y][x]
print(row)
def try_portal_set(p_keys):
c_board = board[:]
for y in range(len(c_board)):
for x in range(len(c_board[y])):
if c_board[y][x] == "X":
if portals[(x, y)] not in p_keys:
c_board[y] = c_board[y][:x] + "#" + c_board[y][x + 1:]
c_portals = {}
#print(p_keys)
for p in portals:
if portals[p] in p_keys:
c_portals[p] = portals[p]
#print(c_portals)
return astar_with_portals(c_board, start_pos, end_pos, c_portals, walkable=".")
board = read_text_from_file("day20", nostrip=True)
orig_board = board[:]
portals = {}
portal_keys = []
start_pos = (0, 0)
end_pos = (0, 0)
for y in range(len(board)):
for x in range(len(board[y])):
if ord(board[y][x]) > 64:
adjecents = get_adjecents(board, (x, y))
portal = board[y][x]
if "." in adjecents:
if ord(adjecents[0]) > 64:
portal = adjecents[0] + portal
if portal != "AA" and portal != "ZZ":
board[y] = board[y][:x] + "X" + board[y][x + 1:]
board[y - 1] = board[y - 1][:x] + " " + board[y - 1][x + 1:]
elif ord(adjecents[1]) > 64:
portal = portal + adjecents[1]
if portal != "AA" and portal != "ZZ":
board[y] = board[y][:x] + "X " + board[y][x + 2:]
elif ord(adjecents[2]) > 64:
portal = portal + adjecents[2]
if portal != "AA" and portal != "ZZ":
board[y] = board[y][:x] + "X" + board[y][x + 1:]
board[y + 1] = board[y + 1][:x] + " " + board[y + 1][x + 1:]
else:
portal = adjecents[3] + portal
if portal != "AA" and portal != "ZZ":
board[y] = board[y][:x - 1] + " X" + board[y][x + 1:]
if portal == "AA":
to_add = {0: (0, -1), 1: (1, 0), 2:(0, 1), 3:(-1, 0)}[adjecents.index(".")]
start_pos = (x + to_add[0], y + to_add[1])
elif portal == "ZZ":
to_add = {0: (0, -1), 1: (1, 0), 2: (0, 1), 3: (-1, 0)}[adjecents.index(".")]
end_pos = (x + to_add[0], y + to_add[1])
else:
if portal not in portal_keys:
portal_keys.append(portal)
portals[(x, y)] = portal
print_board(orig_board, start_pos, end_pos)
min_length = len(try_portal_set(portal_keys)) - 1
print(min_length)
for portal in portal_keys:
copy_keys = deepcopy(portal_keys)
copy_keys.remove(portal)
path = try_portal_set(copy_keys)
#print_board(orig_board, start_pos, end_pos, path)
if len(path) - 1 < min_length:
min_length = len(path) - 1
print("Removed", portal, "Length:", len(path) - 1)
print(min_length)