You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

75 lines
2.0 KiB

#!/usr/bin/env python3
import sys, math
import numpy as np
def dijkstra(graph, 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
# joining the sets does not work because we never remove the older nodes!
if alt <= a[vo]:
if alt < a[vo]:
v[vo] = set([])
a[vo] = alt
v[vo].add(u)
v[vo] = v[vo].union(set(v[u]))
def count_set(edges, lab):
edg = set([])
for e in edges:
edg.add((e[0], e[1]))
lab[e[1]][e[0]] = 'O'
return 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, (0,-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]:
if not lab[y+d1[1]][x+d1[0]] == '#': graph[(x,y,d)].append((x,y,d1))
if lab[y+d[1]][x+d[0]] != '#':
graph[(x,y,d)].append((x+d[0], y+d[1], d))
distance[start] = 0
v1, a1 = dijkstra(graph, pred, distance)
d1 = count_set(v1[end], lab)
# challenge 1
res1 = a1[end]
print(f"challenge 1:\n{res1}\n")
# challenge 2, needed some reddit help again...
d1.add((end[0],end[1]))
d1.add((start[0], start[1]))
res2 = len(d1)
print(f"challenge 2:\n{res2}")
for line in lab:
print(''.join(line))