Mercurial > hg > lib > markup
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 |