Skip to content

Commit ddf3f78

Browse files
committed
2024 15
1 parent 94009ad commit ddf3f78

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

2024/15/main.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import sys
2+
3+
data = open(sys.argv[1]).read().strip()
4+
groups = data.split('\n\n')
5+
6+
grid = [list(row) for row in groups[0].split('\n')]
7+
8+
moves = list(''.join(groups[1].split('\n')))
9+
10+
ry, rx = 0, 0
11+
for y, row in enumerate(grid):
12+
for x, c in enumerate(row):
13+
if c == '@':
14+
ry, rx = y, x
15+
16+
for move in moves:
17+
match move:
18+
case '>':
19+
px = rx + 1
20+
while grid[ry][px] != '.' and grid[ry][px] != '#':
21+
px += 1
22+
if grid[ry][px] == '.':
23+
for i in range(px, rx, -1):
24+
grid[ry][i] = grid[ry][i-1]
25+
grid[ry][i-1] = '.'
26+
rx += 1
27+
case '<':
28+
px = rx - 1
29+
while grid[ry][px] != '.' and grid[ry][px] != '#':
30+
px -= 1
31+
if grid[ry][px] == '.':
32+
for i in range(px, rx):
33+
grid[ry][i] = grid[ry][i+1]
34+
grid[ry][i+1] = '.'
35+
rx -= 1
36+
case '^':
37+
py = ry - 1
38+
while grid[py][rx] != '.' and grid[py][rx] != '#':
39+
py -= 1
40+
if grid[py][rx] == '.':
41+
for i in range(py, ry):
42+
grid[i][rx] = grid[i+1][rx]
43+
grid[i+1][rx] = '.'
44+
ry -= 1
45+
case 'v':
46+
py = ry + 1
47+
while grid[py][rx] != '.' and grid[py][rx] != '#':
48+
py += 1
49+
if grid[py][rx] == '.':
50+
for i in range(py, ry, -1):
51+
grid[i][rx] = grid[i-1][rx]
52+
grid[i-1][rx] = '.'
53+
ry += 1
54+
55+
ans = 0
56+
for y, row in enumerate(grid):
57+
for x, c in enumerate(row):
58+
if c == 'O':
59+
ans += 100*y + x
60+
print(ans)
61+
62+
grid = [list(row) for row in groups[0].split('\n')]
63+
grid2 = []
64+
65+
for y, row in enumerate(grid):
66+
row2 = []
67+
for x, c in enumerate(row):
68+
match c:
69+
case '#':
70+
row2.extend(['#', '#'])
71+
case 'O':
72+
row2.extend(['[', ']'])
73+
case '.':
74+
grid[y][x] = '..'
75+
row2.extend(['.', '.'])
76+
case '@':
77+
row2.extend(['@', '.'])
78+
grid2.append(row2)
79+
80+
grid = grid2
81+
82+
ry, rx = 0, 0
83+
for y, row in enumerate(grid):
84+
for x, c in enumerate(row):
85+
if c == '@':
86+
ry, rx = y, x
87+
88+
for move_idx, move in enumerate(moves):
89+
match move:
90+
case '>':
91+
px = rx + 1
92+
while grid[ry][px] != '.' and grid[ry][px] != '#':
93+
px += 1
94+
if grid[ry][px] == '.':
95+
for i in range(px, rx, -1):
96+
grid[ry][i] = grid[ry][i-1]
97+
grid[ry][i-1] = '.'
98+
rx += 1
99+
case '<':
100+
px = rx - 1
101+
while grid[ry][px] != '.' and grid[ry][px] != '#':
102+
px -= 1
103+
if grid[ry][px] == '.':
104+
for i in range(px, rx):
105+
grid[ry][i] = grid[ry][i+1]
106+
grid[ry][i+1] = '.'
107+
rx -= 1
108+
case '^':
109+
ny = ry - 1
110+
next_cell = grid[ny][rx]
111+
if next_cell == '.':
112+
grid[ny][rx] = grid[ry][rx]
113+
grid[ry][rx] = '.'
114+
ry -= 1
115+
elif next_cell in '[]':
116+
frontier = []
117+
queue = [(ny, rx), (ny, rx + {'[': 1, ']': -1}[next_cell])]
118+
seen = set([(ry, rx)] + queue)
119+
while queue:
120+
cury, curx = queue.pop(0)
121+
nexty = cury - 1
122+
if grid[nexty][curx] in '[]' and (nexty, curx) not in seen:
123+
queue.append((nexty, curx))
124+
seen.add((nexty, curx))
125+
nbr = (nexty, curx+{'[': 1, ']': -1}[grid[nexty][curx]])
126+
queue.append(nbr)
127+
seen.add(nbr)
128+
else:
129+
frontier.append((cury, curx))
130+
for y, x in frontier:
131+
if grid[y-1][x] == '#':
132+
break
133+
else:
134+
seen = sorted(seen)
135+
for y, x in seen:
136+
grid[y-1][x], grid[y][x] = grid[y][x], '.'
137+
ry -= 1
138+
139+
case 'v':
140+
ny = ry + 1
141+
next_cell = grid[ny][rx]
142+
if next_cell == '.':
143+
grid[ny][rx] = grid[ry][rx]
144+
grid[ry][rx] = '.'
145+
ry += 1
146+
elif next_cell in '[]':
147+
frontier = []
148+
queue = [(ny, rx), (ny, rx + {'[': 1, ']': -1}[next_cell])]
149+
seen = set([(ry, rx)] + queue)
150+
while queue:
151+
cury, curx = queue.pop(0)
152+
nexty = cury + 1
153+
if grid[nexty][curx] in '[]' and (nexty, curx) not in seen:
154+
queue.append((nexty, curx))
155+
seen.add((nexty, curx))
156+
nbr = (nexty, curx+{'[': 1, ']': -1}[grid[nexty][curx]])
157+
queue.append(nbr)
158+
seen.add(nbr)
159+
else:
160+
frontier.append((cury, curx))
161+
frontier = sorted(frontier)
162+
for y, x in frontier:
163+
if grid[y+1][x] == '#':
164+
break
165+
else:
166+
seen = sorted(seen, reverse=True)
167+
for y, x in seen:
168+
grid[y+1][x], grid[y][x] = grid[y][x], '.'
169+
ry += 1
170+
171+
ans2 = 0
172+
for y, row in enumerate(grid):
173+
for x, c in enumerate(row):
174+
if c == '[':
175+
ans2 += 100*y + x
176+
print(ans2)

0 commit comments

Comments
 (0)