#!/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}")