aoc

Advent of Code Solutions
git clone git://git.alexkarle.com.com/aoc
Log | Files | Refs | README | LICENSE

1.py (1911B) [raw]


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