import re,math,collections,sys
def load(path):
s=open(path,encoding="utf-8-sig").read()
w=re.search(r"(.*?)",s,re.S).group(1)
g=lambda t:re.search(rf"<{t}>(.*?){t}>",w,re.S).group(1)
ids=[int(v) for v in g("id").split(",")]
X=[float(v) for v in g("x").split(",")]; Z=[float(v) for v in g("z").split(",")]
sp=lambda t:[[int(v) for v in e.split(",") if v not in("","-1")] for e in g(t).split(";")]
out=sp("out"); inc=sp("incoming"); fl=[int(v) for v in g("flags").split(",")]
N={i:dict(x=X[k],z=Z[k],out=out[k],inc=inc[k],fl=fl[k]) for k,i in enumerate(ids)}
mk=[(int(a),b) for a,b in re.findall(r'b og b->c er reelle kanter
if b not in N[a]["out"]: continue
t,l1,l2=ang(N,a,b,c)
if t>135: rev+=1; continue # U-vending / bakke-par, ikke et sving
if t>45: sharp.append((round(t),a,b,c,len(n["inc"]),len(n["out"]),round(l1,1),round(l2,1)))
kinds=collections.Counter("kæde" if (x[4]==1 and x[5]==1) else "kryds" for x in sharp)
print("sving >45°:",len(sharp),kinds,"(>135° udeladt:",rev,")")
print("fordeling:",collections.Counter(min(x[0]//15*15,135) for x in sharp))
nodes={x[2] for x in sharp}; print("unikke knæk-noder",len(nodes))