comparison python/safe.py @ 8:fcef94b6324c

move all the action to Block
author Henry S. Thompson <ht@inf.ed.ac.uk>
date Wed, 26 May 2021 13:16:36 -0400
parents 3ee329b129c6
children 0d1670ab37df
comparison
equal deleted inserted replaced
7:3ee329b129c6 8:fcef94b6324c
1 #!/usr/bin/python3 1 #!/usr/bin/python3
2 '''Find a safe landing space (i.e. in air, not above lava) near a cluster''' 2 '''Find a safe landing space (i.e. in air, not above lava) near a cluster'''
3 import sys, math 3 import sys, math
4 4
5 from util import * 5 from util import *
6 from bisect import insort_left as insort
6 7
7 def usage(): 8 def usage():
8 print("""Usage: safe.py [-d n] 9 print("""Usage: safe.py [-d n]
9 n is maximum distance of landing to some point in the cluster, default is 10. 10 n is maximum distance of landing to some point in the cluster, default is 10.
10 11
19 n=float(sys.argv.pop(1)) 20 n=float(sys.argv.pop(1))
20 else: 21 else:
21 n=10.0 22 n=10.0
22 23
23 class Block: 24 class Block:
24 pass 25 '''Shared by Air and Lava,
26 holds points and columns.
27 Columns are dictionaries indexed by (x,z) coords,
28 value is upward-ordered list of pairs, closed intervals of y'''
29 def __init__(self,filename):
30 with open(filename,'r') as file:
31 self.readHeaders(file)
32 self.readPoints(file)
25 33
26 Block.__init__=readHeaders 34 cc=self.columns={}
35 tc={}
36 for p in self.points:
37 k=(p[0],p[2])
38 y=p[1]
39 try:
40 yy=tc[k]
41 insort(yy,y)
42 except KeyError:
43 tc[k]=[y]
44 # convert to lists of intervals
45 # Simplest case first
46 for k,yy in tc.items():
47 tyy=[yy]
48 ii=[]
49 while True:
50 clean=True
51 for j,yy in enumerate(tyy):
52 if len(yy)==1+(yy[-1]-yy[0]):
53 ii.append((yy[0],yy[-1]))
54 else:
55 clean=False
56 for i in range(len(yy)-1):
57 if yy[i]+1!=yy[i+1]:
58 ii+=(yy[0],yy[i])
59 tyy=[yy[i+1:]]+tyy[j+1:]
60 break
61 if clean:
62 break
63 self.columns[k]=ii
64
65 def readPoints(self,file):
66 file.readline()
67 self.points=[[float(i) for i in l.split('\t')[2].split(',')] for l in file]
68
69 Block.readHeaders=readHeaders # from util
27 70
28 class Air(Block): 71 class Air(Block):
29 def __init__(self,filename): 72 pass
30 with open(filename,'r') as air:
31 Block.__init__(self,air)
32 air.readline()
33 aa=self.blocks=[[float(i) for i in l.split('\t')[2].split(',')] for l in air]
34 ad=self.columns={}
35 for a in aa:
36 k=(a[0],a[2])
37 h=ad.get(k,500.0)
38 if a[1]<h:
39 ad[k]=a[1]
40 73
41 A=Air('air.tsv') 74 A=Air('air.tsv')
42 75
43 class Lava(Block): 76 class Lava(Block):
44 def __init__(self,filename): 77 pass
45 with open(filename,'r') as lava: 78
46 Block.__init__(self,lava)
47 lava.readline()
48 ll=self.columns={}
49 for l in lava:
50 x=[float(i) for i in l.split('\t')[2].split(',')]
51 k=(x[0],x[2])
52 kk=ll.setdefault(k,list())
53 kk.append(x[1])
54
55 L=Lava('lava.tsv') 79 L=Lava('lava.tsv')
56 80
57 def d(p1,p2): 81 def d(p1,p2):
58 dx=p1[0]-p2[0] 82 dx=p1[0]-p2[0]
59 dz=p1[1]-p2[1] 83 dz=p1[1]-p2[1]
60 dy=p1[2]-p2[2] 84 dy=p1[2]-p2[2]
61 return math.sqrt((dx*dx)+(dy*dy)+(dz*dz)) 85 return math.sqrt((dx*dx)+(dy*dy)+(dz*dz))
62 86
63 def unsafe(p): 87 def unsafe(p):
64 ka=[(a[0],a[2]) for a in A.blocks if d(a,p)<=n] 88 ka=[(a[0],a[2]) for a in A.points if d(a,p)<=n]
65 return [(k,A.columns[k],L.columns[k]) for k in ka if k in L.columns] 89 return [(k,A.columns[k],L.columns[k]) for k in ka if k in L.columns]
66 90
67 readHeaders(sys.modules['__main__'],sys.stdin,False) 91 readHeaders(sys.modules['__main__'],sys.stdin,False)
68 for l in sys.stdin: 92 for l in sys.stdin:
69 c=eval(l) 93 c=eval(l)
70 s=[(p,unsafe(p)) for p in c] 94 s=[(p,unsafe(p)) for p in c]
95
71 print(s if s else 'No air',c) 96 print(s if s else 'No air',c)
72 97
73 98