131 lines
3.6 KiB
Python
131 lines
3.6 KiB
Python
#!/usr/bin/python3
|
|
import glob
|
|
import os
|
|
import sys
|
|
TRANSFER_TIME = 2
|
|
|
|
class Line (dict):
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.stations = []
|
|
def get_next_freq(L, p, tm, rev=False) :
|
|
off = L.stations[p][1]
|
|
o = "offset"
|
|
if rev :
|
|
off = L.stations[-1][1] - L.stations[p][1]
|
|
o = "roffset"
|
|
k = (L[o] + off) % L["frequency"]
|
|
while k < tm :
|
|
k += L["frequency"]
|
|
return k
|
|
class Station (dict) :
|
|
def __init__(self, code, line, pos):
|
|
self.code = code
|
|
self.lines = [(line,pos)]
|
|
def getlines(self):
|
|
return [i[0] for i in self.lines]
|
|
def nexttrains(self, tm):
|
|
# find next trains departing at stn around tm
|
|
trains = []
|
|
for l,p in self.lines :
|
|
L = lines[l]
|
|
if p < L.nstations-1 :
|
|
trains.append((get_next_freq(L,p,tm), l,False))
|
|
if L["rev"] and p > 0:
|
|
trains.append((get_next_freq(L,p,tm,True), l,True))
|
|
trains.sort(key=lambda x: x[1])
|
|
return trains
|
|
def reachablestations(self, tm, exclude=[]) :
|
|
stns = []
|
|
for l,p in self.lines :
|
|
if l in exclude:
|
|
continue
|
|
L = lines[l]
|
|
if p < L.nstations-1 :
|
|
dep = get_next_freq(L,p,tm)
|
|
ors = L.stations[p]
|
|
for k in range(p+1,L.nstations) :
|
|
stn = L.stations[k]
|
|
arr = stn[1] - ors[1] + dep
|
|
stns.append((stn[0],dep,arr,L.name,False))
|
|
if L["rev"] and p > 0:
|
|
dep = get_next_freq(L,p,tm,True)
|
|
ors = L.stations[p]
|
|
for k in range(0,p) :
|
|
stn = L.stations[k]
|
|
arr = ors[1] - stn[1] + dep
|
|
stns.append((stn[0],dep,arr,L.name,True))
|
|
|
|
stns.sort(key=lambda x: x[2])
|
|
return stns
|
|
|
|
|
|
lines = {}
|
|
stations = {}
|
|
for k in glob.glob("lines/*") :
|
|
if k.endswith("~") :
|
|
continue
|
|
f = open(k,"r")
|
|
l = Line(os.path.basename(k))
|
|
for j in f :
|
|
o = j.split()
|
|
if j.startswith(" ") :
|
|
l[o[0].lower()] = int(o[1])
|
|
else :
|
|
l.stations.append((o[0],int(o[1])))
|
|
if not o[0] in stations :
|
|
stations[o[0]] = Station(o[0], l.name, len(l.stations)-1)
|
|
else :
|
|
stations[o[0]].lines.append((l.name, len(l.stations)-1))
|
|
l.nstations = len(l.stations)
|
|
lines[l.name] = l
|
|
time = 10
|
|
|
|
start = sys.argv[1]
|
|
end = sys.argv[2]
|
|
end = sys.argv[2]
|
|
|
|
if len(sys.argv) > 3 :
|
|
TRANSFER_TIME = int(sys.argv[3])
|
|
|
|
|
|
|
|
|
|
|
|
#print(stations["Mar"].reachablestations(49))
|
|
#print(stations["MoC"].reachablestations(49))
|
|
|
|
|
|
Q = stations[start].reachablestations(time)
|
|
klines = stations[start].getlines()
|
|
prev = {}
|
|
d = {}
|
|
for k in Q :
|
|
prev[k[0]] = (start, k[1], k[2],k[3],k[4])
|
|
d[k[0]] = k[2]
|
|
while Q :
|
|
u = Q.pop(0)
|
|
if u[0] == end :
|
|
break
|
|
stu = stations[u[0]]
|
|
if len(stu.lines)>1 :
|
|
R = stu.reachablestations(u[2]+TRANSFER_TIME,klines)
|
|
for k in R :
|
|
if k[0] not in d or k[2] < d[k[0]] :
|
|
prev[k[0]] = (u[0], u[1],u[2],u[3],u[4])
|
|
d[k[0]] = k[2]
|
|
Q.append(k)
|
|
klines += stu.getlines()
|
|
Q.sort(key=lambda i: i[2])
|
|
|
|
translist = []
|
|
while True :
|
|
translist.insert(0,u)
|
|
u = prev[u[0]]
|
|
if u[0] == start :
|
|
break
|
|
print("Number of Changes: %d, Time needed: %d minutes" % (len(translist)-1, translist[-1][2]-translist[0][1]))
|
|
for j in translist :
|
|
print("Take line %s to %s at :%02d, arrival :%02d" % (j[3],j[0],j[1] %60,j[2] %60))
|
|
|