#!/usr/bin/env python3 import sys, math import numpy as np def dijkstra(graph, s, v, a): Q = [n for n in graph.keys()] lq = len(Q) while len(Q) > 0: u = min([u for u in Q], key=lambda x: a[x]) Q.remove(u) for vo in graph[u]: if vo in Q: distance_update(graph, u,vo,a,v) return v, a def distance_update(g, u, vo, a, v): dist = 1 if vo[2] == u[2] else 1000 alt = a[u] + dist if alt <= a[vo]: v[vo].add(u) v[vo] = v[vo].union(set(v[u])) if alt < a[vo]: a[vo] = alt def count_set(edges): edg = set([]) for e in edges: edg.add((e[0], e[1])) return len(edg) if __name__ == '__main__': lab = [list(line.strip('\n')) for line in open(sys.argv[1])] rot90 = {(0,-1): [(-1,0),(1,0)], (1,0): [(0,-1),(0,1)], (0,1): [(1,0),(-1, 0)], (-1,0): [(0,1),(0,-1)]} start = (1, len(lab)-2, (1,0)) end = (len(lab[0])-2, 1) graph = {} distance = {} pred = {} for y, l in enumerate(lab): for x, f in enumerate(lab[y]): if f == '#': continue for d in [(0,1), (0,-1), (1,0), (-1,0)]: distance[(x,y,d)] = math.inf pred[(x,y,d)] = set([]) graph[(x,y,d)] = [] for d1 in rot90[d]: graph[(x,y,d)].append((x,y,d1)) if lab[y+d[1]][x+d[0]] == '.' or lab[y+d[1]][x+d[0]] == 'E': graph[(x,y,d)].append((x+d[0], y+d[1], d)) distance[start] = 0 v, a = dijkstra(graph, start, pred, distance) print([a[end[0], end[1], d] for d in [(0,1), (0,-1), (1,0), (-1,0)]], [1+count_set(v[end[0], end[1], d]) for d in [(0,1), (0,-1), (1,0), (-1,0)]]) # challenge 1 res1 = min([a[end[0], end[1], d] for d in [(0,1), (0,-1), (1,0), (-1,0)]]) print(f"challenge 1:\n{res1}\n") # challenge 2 ind = [a[end[0], end[1], d] for d in [(0,1), (0,-1), (1,0), (-1,0)]].index(res1) d = [(0,1), (0,-1), (1,0), (-1,0)][ind] res2 = 1+count_set(v[end[0], end[1], d]) print(f"challenge 2:\n{res2}")