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
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))
|
|
|
|
|