aoc

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

2.py (1963B) [raw]


      1 #!/usr/bin/env python3
      2 import sys
      3 
      4 def parse():
      5     G = []
      6     guard = (None, None)
      7     r = 0
      8     for l in sys.stdin:
      9         G.append([x for x in l.strip()])
     10         if "^" in l:
     11             guard = (r, l.index("^"))
     12         r += 1
     13 
     14     if not guard[0]:
     15         raise Exception("Unable to find Guard")
     16 
     17     return G, guard
     18 
     19 def turn(dir):
     20     if dir == "^":
     21         return ">"
     22     elif dir == ">":
     23         return "v"
     24     elif dir == "v":
     25         return "<"
     26     elif dir == "<":
     27         return "^"
     28     else:
     29         raise Exception(f"Bad direction {dir}")
     30 
     31 def move(G, guard, dir):
     32     if dir == "^":
     33         next = (guard[0] - 1, guard[1])
     34     elif dir == "v":
     35         next = (guard[0] + 1, guard[1])
     36     elif dir == ">":
     37         next = (guard[0], guard[1] + 1)
     38     elif dir == "<":
     39         next = (guard[0], guard[1] - 1)
     40     else:
     41         raise Exception(f"Bad direction {dir}")
     42 
     43     if next[0] >= len(G) or next[0] < 0 or next[1] >= len(G[0]) or next[1] < 0:
     44         # off the map
     45         return ((None, None), None)
     46 
     47     if G[next[0]][next[1]] == "#":
     48         dir = turn(dir)
     49         return (guard, dir)
     50 
     51     return (next, dir)
     52 
     53 def pprint(G, guard, dir):
     54     for i in range(len(G)):
     55         for j in range(len(G[0])):
     56             if (i, j) == guard:
     57                 print(dir, end='')
     58             else:
     59                 print(G[i][j], end='')
     60         print("")
     61 
     62 def check(G, guard, dir):
     63     seen = set()
     64     while guard[0] is not None:
     65         seen.add((guard, dir))
     66         guard, dir = move(G, guard, dir)
     67         if dir is None:
     68             return seen
     69         if (guard, dir) in seen:
     70             return None
     71 
     72 if __name__ == '__main__':
     73     G, guard = parse()
     74     dir = "^"
     75 
     76     regseen = check(G, guard, dir)
     77     sq2chk = { x[0] for x in regseen if x[0] != guard }
     78 
     79     c = 0
     80     for sq in sq2chk:
     81         print(sq)
     82         i, j = sq
     83         G[i][j] = '#'
     84         if check(G, guard, dir) is None:
     85             c += 1
     86         G[i][j] = '.'
     87 
     88     print(c)