2.py (2224B) [raw]
1 #!/usr/bin/env python3 2 import sys 3 import os 4 5 def dupe(c): 6 if c == "#": 7 return ["#", "#"] 8 if c == "O": 9 return ["[", "]"] 10 if c == "@": 11 return ["@", "."] 12 if c == ".": 13 return [".", "."] 14 else: 15 raise RuntimeException(f"Unknown char {c}") 16 17 def parse(): 18 G = [] 19 moves = [] 20 rob = None 21 for l in sys.stdin: 22 if l[0] == "#": 23 row = [] 24 for c in l.strip(): 25 row += dupe(c) 26 G.append(row) 27 if l[0] in {">", "<", "^", "v"}: 28 moves += [c for c in l.strip()] 29 for i in range(len(G)): 30 for j in range(len(G[0])): 31 if G[i][j] == "@": 32 rob = (i, j) 33 return G, moves, rob 34 35 def debug(msg): 36 if os.getenv("DEBUG"): 37 print(msg) 38 39 def pprint(G): 40 for row in G: 41 debug("".join(row)) 42 43 velocity = { 44 "^": (-1, 0), 45 ">": (0, 1), 46 "v": (1, 0), 47 "<": (0, -1), 48 } 49 50 def get(G, pos): 51 if pos[0] < 0 or pos[0] > len(G) or pos[1] < 0 or pos[1] > len(G[0]): 52 return None 53 return G[pos[0]][pos[1]] 54 55 def step(pos, move): 56 dy, dx = velocity[move] 57 return (pos[0] + dy, pos[1] + dx) 58 59 def hasopen(G, move, rob): 60 curr = step(rob, move) 61 while get(G, curr): 62 if get(G, curr) == ".": 63 return True 64 if get(G, curr) == "#": 65 return False 66 curr = step(curr, move) 67 return False 68 69 def move(G, move, rob): 70 dy, dx = velocity[move] 71 if not hasopen(G, move, rob): 72 return rob 73 74 # we have an open spot to shift into 75 curr = rob 76 cval = get(G, curr) 77 while True: 78 next = step(curr, move) 79 nval = get(G, next) 80 G[next[0]][next[1]] = cval 81 cval = nval 82 curr = next 83 if nval == ".": 84 break 85 G[rob[0]][rob[1]] = "." 86 return step(rob, move) 87 88 def score(G): 89 s = 0 90 for i in range(len(G)): 91 for j in range(len(G[0])): 92 if G[i][j] == "O": 93 s += 100 * i + j 94 return s 95 96 if __name__ == '__main__': 97 G, moves, rob = parse() 98 pprint(G) 99 for m in moves: 100 debug(f"Move {m}:") 101 rob = move(G, m, rob) 102 pprint(G) 103 debug("") 104 print(score(G))