changeset 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
files python/safe.py
diffstat 1 files changed, 50 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/python/safe.py	Wed May 26 09:18:49 2021 -0400
+++ b/python/safe.py	Wed May 26 13:16:36 2021 -0400
@@ -3,6 +3,7 @@
 import sys, math
 
 from util import *
+from bisect import insort_left as insort
 
 def usage():
   print("""Usage:  safe.py [-d n]
@@ -21,37 +22,60 @@
   n=10.0
 
 class Block:
-  pass
+  '''Shared by Air and Lava,
+  holds points and columns.
+  Columns are dictionaries indexed by (x,z) coords,
+  value is upward-ordered list of pairs, closed intervals of y'''
+  def __init__(self,filename):
+    with open(filename,'r') as file:
+      self.readHeaders(file)
+      self.readPoints(file)
 
-Block.__init__=readHeaders
+    cc=self.columns={}
+    tc={}
+    for p in self.points:
+      k=(p[0],p[2])
+      y=p[1]
+      try:
+        yy=tc[k]
+        insort(yy,y)
+      except KeyError:
+        tc[k]=[y]
+    # convert to lists of intervals
+    # Simplest case first
+    for k,yy in tc.items():
+      tyy=[yy]
+      ii=[]
+      while True:
+        clean=True
+        for j,yy in enumerate(tyy):
+          if len(yy)==1+(yy[-1]-yy[0]):
+            ii.append((yy[0],yy[-1]))
+          else:
+            clean=False
+            for i in range(len(yy)-1):
+              if yy[i]+1!=yy[i+1]:
+                ii+=(yy[0],yy[i])
+                tyy=[yy[i+1:]]+tyy[j+1:]
+            break
+        if clean:
+          break
+      self.columns[k]=ii
+
+  def readPoints(self,file):
+    file.readline()
+    self.points=[[float(i) for i in l.split('\t')[2].split(',')] for l in file]
+
+Block.readHeaders=readHeaders # from util
 
 class Air(Block):
-  def __init__(self,filename):
-    with open(filename,'r') as air:
-      Block.__init__(self,air)
-      air.readline()
-      aa=self.blocks=[[float(i) for i in l.split('\t')[2].split(',')] for l in air]
-    ad=self.columns={}
-    for a in aa:
-      k=(a[0],a[2])
-      h=ad.get(k,500.0)
-      if a[1]<h:
-        ad[k]=a[1]
+  pass
 
 A=Air('air.tsv')
 
 class Lava(Block):
-  def __init__(self,filename):
-    with open(filename,'r') as lava:
-      Block.__init__(self,lava)
-      lava.readline()
-      ll=self.columns={}
-      for l in lava:
-        x=[float(i) for i in l.split('\t')[2].split(',')]
-        k=(x[0],x[2])
-        kk=ll.setdefault(k,list())
-        kk.append(x[1])
-  
+  pass
+
 L=Lava('lava.tsv')
 
 def d(p1,p2):
@@ -61,13 +85,14 @@
   return math.sqrt((dx*dx)+(dy*dy)+(dz*dz))
 
 def unsafe(p):
-  ka=[(a[0],a[2]) for a in A.blocks if d(a,p)<=n]
+  ka=[(a[0],a[2]) for a in A.points if d(a,p)<=n]
   return [(k,A.columns[k],L.columns[k]) for k in ka if k in L.columns]
 
 readHeaders(sys.modules['__main__'],sys.stdin,False)
 for l in sys.stdin:
   c=eval(l)
   s=[(p,unsafe(p)) for p in c]
+  
   print(s if s else 'No air',c)