adventofcode2024/day15/sol.py

135 lines
3.1 KiB
Python

def parse(file):
map = []
for line in file:
line = line.strip()
if not line:
break
map.append(line)
moves = ""
for line in file:
moves += line.strip().replace("&lt;","<").replace("&gt;",">")
return map, moves
def solve(file):
map, moves = parse(file)
map = [list(x) for x in map]
for y,line in enumerate(map):
if '@' in line:
x = line.index('@')
cur = x,y
print(moves)
for m in moves:
next, ok = move(map, cur, m)
cur = next
print(cur)
t = 0
for y,line in enumerate(map):
for x,c in enumerate(line):
if c == 'O':
t += y*100 + x
print("".join(line))
print(t)
def solve2(file):
map, moves = parse(file)
map2 = []
for line in map:
l2 = []
for c in line:
if c == '#': c = '##'
elif c == 'O': c = '[]'
elif c == '.': c = '..'
elif c == '@': c = '@.'
l2.extend(c)
map2.append(l2)
map = map2
for y,line in enumerate(map):
if '@' in line:
x = line.index('@')
cur = x,y
#print(show(map), cur)
#print(moves)
for m in moves:
#print(m)
assert map[cur[1]][cur[0]] == '@'
next, ok = move(map, cur, m)
cur = next
#print(cur)
t = 0
for y,line in enumerate(map):
for x,c in enumerate(line):
if c == '[':
t += y*100 + x
print("".join(line))
print(t)
def move(map, cur, m):
if m == 'v': d = (0,1)
if m == '<': d = (-1,0)
if m == '>': d = (1,0)
if m == '^': d = (0,-1)
n = (cur[0]+d[0], cur[1]+d[1])
c = map[n[1]][n[0]]
if c == 'O':
_, ok = move(map, n, m)
if not ok:
return cur, False
elif c in "[]":
if m in '<>':
_, ok = move(map, n, m)
if not ok:
return cur, False
else:
blocks = set()
ok = canpush(map, n, d, blocks)
if not ok:
return cur, False
#print(blocks)
#print("before push\n", show(map))
for x,y in sorted(blocks, key=lambda a:( a[1]*-d[1],a[0])):
map[y+d[1]][x+d[0]] = map[y][x]
map[y][x] = '.'
#print("after push\n", show(map))
elif c == '#':
return cur, False
map[n[1]][n[0]] = map[cur[1]][cur[0]]
map[cur[1]][cur[0]] = '.'
return n, True
def show(map):
return '\n'.join(''.join(x) for x in map)
def canpush(map, cur, d, blocks):
if cur in blocks:
return True
c = map[cur[1]][cur[0]]
if c == '.':
return True
if c not in '[]':
return False
blocks.add(cur)
nx, ny = (cur[0]+d[0], cur[1]+d[1])
if c == '[':
blocks.add((cur[0]+1, cur[1]))
nx2 = nx+1
else:
blocks.add((cur[0]-1, cur[1]))
nx2 = nx-1
return canpush(map, (nx,ny), d, blocks) and canpush(map, (nx2,ny), d, blocks)
solve(open("sample1.in"))
solve(open("sample2.in"))
solve2(open('sample1.in'))
solve(open("input"))
solve2(open('input'))