You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

112 lines
3.2 KiB

#!/usr/bin/env python3
import sys, os, time
from copy import deepcopy
def show(m):
for line in m:
sys.stdout.write("\r"+''.join(line)+'\n')
sys.stdout.flush()
time.sleep(0.2)
def gps(x, y):
return 100*y + x
def move_stone(m, x, y, move):
dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
nx, ny = x+dir[move][0], y+dir[move][1]
if m[ny][nx] == '#': return
if m[ny][nx] == 'O': move_stone(m, nx, ny, move)
if m[ny][nx] == '.':
m[ny][nx] = 'O'
m[y][x] = '.'
return
def move_box_h(m, x, y, move):
dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
nx, ny = x+dir[move][0], y
sym = m[y][x]
if m[ny][nx] == '#': return
if m[ny][nx] in ['[', ']']: move_box_h(m, nx, ny, move)
if m[ny][nx] == '.':
m[ny][nx] = sym
m[y][x] = '.'
return
def move_box_v(m, x, y, move):
dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
if m[y][x] == '[': x1, x2 = x, x+1
else: x1, x2 = x-1, x
nx1, nx2, ny = x1+dir[move][0], x2+dir[move][0], y+dir[move][1]
if m[ny][nx1] == '#' or m[ny][nx2] == '#': return m
if m[ny][nx1] == ']' and m[ny][nx2] == '[':
mp = deepcopy(m)
mp = move_box_v(mp, nx1, ny, move)
mp = move_box_v(mp, nx2, ny, move)
if mp[ny][nx1] == '.' and mp[ny][nx2] == '.': m = deepcopy(mp)
elif m[ny][nx1] in ['[', ']']: m = move_box_v(m, nx1, ny, move)
elif m[ny][nx2] in ['[', ']']: m = move_box_v(m, nx2, ny, move)
if m[ny][nx1] == '.' and m[ny][nx2] == '.':
m[ny][nx1] = '['
m[ny][nx2] = ']'
m[y][x1] = '.'
m[y][x2] = '.'
return m
return m
def move(m, x, y, move):
dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
nx, ny = x+dir[move][0], y+dir[move][1]
if m[ny][nx] == '#': return m, x, y
if m[ny][nx] == 'O': move_stone(m, nx, ny, move)
if m[ny][nx] in ['[',']'] and move in ['v', '^']:
m = move_box_v(m, nx, ny, move)
elif m[ny][nx] in ['[',']'] and move in ['<', '>']:
move_box_h(m, nx, ny, move)
if m[ny][nx] == '.':
m[ny][nx] = '@'
m[y][x] = '.'
return m, nx, ny
else: return m, x, y
if __name__ == '__main__':
mp, moves = open(sys.argv[1]).read().split('\n\n')
mp = [list(y.strip('\n')) for y in mp.split('\n')]
moves = list(''.join([m.strip('\n') for m in moves]))
wm = []
for y, l in enumerate(mp):
line = []
for x, r in enumerate(l):
if r == '#': line += ['#', '#']
elif r == '.': line += ['.', '.']
elif r == 'O': line += ['[', ']']
elif r == '@':
wrx, wry = len(line), y
line += ['@', '.']
rx, ry = x, y
wm.append(line)
for mov in moves:
mp, rx, ry = move(mp, rx, ry, mov)
wm, wrx, wry = move(wm, wrx, wry, mov)
# challenge 1
res1 = 0
for y, m in enumerate(mp):
for x, t in enumerate(m):
if t == 'O': res1 += gps(x, y)
print(f"challenge 1:\n{res1}\n")
# challenge 2
res2 = 0
for y, m in enumerate(wm):
for x, t in enumerate(m):
if t == '[': res2 += gps(x, y)
print(f"challenge 2:\n{res2}")