comparison nono.py @ 10:0a24625b33fa

checkNew improving, reverse pass failing
author Henry S. Thompson <ht@inf.ed.ac.uk>
date Sat, 14 Mar 2020 19:13:23 +0000
parents 28a7b0e992cb
children 1b9daa849b0f
comparison
equal deleted inserted replaced
9:28a7b0e992cb 10:0a24625b33fa
74 for k,runs in enumerate(self.allRuns): 74 for k,runs in enumerate(self.allRuns):
75 dprint('=====pass %s======'%k) 75 dprint('=====pass %s======'%k)
76 if self.onepass(self.margin0,self.marginN+1,scratch,runs.copy()): 76 if self.onepass(self.margin0,self.marginN+1,scratch,runs.copy()):
77 wins+=1 77 wins+=1
78 dprint(wins, scratch) 78 dprint(wins, scratch)
79 newSeq=False 79 maybeSeq=None
80 inSeq=False 80 inSeq=None
81 for i in range(self.n): 81 for i in range(self.n):
82 if scratch[i]==wins: 82 if scratch[i]==wins:
83 # If blobby in _every_ pass, then must be a blob 83 # If blobby in _every_ pass, then must be a blob
84 if inSeq: 84 if inSeq is None:
85 newSeq=False 85 inSeq=i if maybeSeq is None else maybeSeq
86 else: 86 dprint('s1',inSeq)
87 inSeq=True 87 maybeSeq=None
88 newSeq=True
89 if self[i].val is None: 88 if self[i].val is None:
90 self.newBlob(i,newSeq) 89 self.newBlob(i,True) # Check cross-vector
91 elif self[i].val is True: 90 elif self[i].val is True:
92 # already there 91 # already there
93 pass 92 pass
94 else: 93 else:
95 print("Shouldn't happen: attempt to blob where x already present! %s at %s"%(self,i),file=sys.stderr) 94 print("Shouldn't happen: attempt to blob where x already present! %s at %s"%(self,i),file=sys.stderr)
96 exit(101) 95 exit(101)
97 else: 96 elif inSeq is not None:
98 inSeq=newSeq=False 97 if self[i].val is not True:
98 inSeq=None
99 maybeSeq=None
100 dprint('s2',i-1)
101 self.checkNew(i-1)
102 elif self[i].val is True and maybeSeq is None:
103 dprint('s3',i)
104 maybeSeq=i
105 dprint('s4',inSeq,i)
106 if inSeq is not None:
107 self.checkNew(i)
99 108
100 def onepass(self,i0,iBound,scratch,stack): 109 def onepass(self,i0,iBound,scratch,stack):
101 """note that stack is not a simple run, but one with _negative_ numbers between 110 """note that stack is not a simple run, but one with _negative_ numbers between
102 and possibly before the positive ones, indicating obligatory skips 111 and possibly before the positive ones, indicating obligatory skips
103 """ 112 """
182 l=(f-s)+1 # our length 191 l=(f-s)+1 # our length
183 print('%s:%s,%s,%s,%s:<%s>'%(str(self.__class__.__name__)[0],s,f,l,self.runs,self)) 192 print('%s:%s,%s,%s,%s:<%s>'%(str(self.__class__.__name__)[0],s,f,l,self.runs,self))
184 c=self.runs.count(l) 193 c=self.runs.count(l)
185 if c==0: 194 if c==0:
186 # not big enough yet 195 # not big enough yet
187 dprint('n0') 196 dprint('x0')
188 return 197 return
189 if self.runs[0]==l: 198 if self.runs[0]==l:
190 # is it safely left marginal, i.e. no blobs or big enough gaps before us? 199 # is it safely left marginal, i.e. no blobs or big enough gaps before us?
191 if self.marginal(range(self.margin0,s),l): 200 if self.marginal(range(self.margin0,s),l):
192 changed=True 201 changed=True
202 dprint('n1')
193 # mark our margins 203 # mark our margins
194 for i in range(self.margin0+1,s): 204 for i in range(self.margin0+1,s):
195 if self[i].val is None: 205 if self[i].val is None:
196 self[i].setVal(False) 206 self[i].setVal(False)
197 if f<self.marginN-1: 207 if f<self.marginN-1:
198 if self[f+1].val is None: 208 if self[f+1].val is None:
199 self[f+1].setVal(False) 209 self[f+1].setVal(False)
200 if f<self.marginN-2 and self[f+2].val is True:
201 dprint('n1')
202 self.checkNew(f+2) # I think@@
203 self.found0(f) # pull in the start margin at least to f+2 210 self.found0(f) # pull in the start margin at least to f+2
211 if f<self.marginN-2 and self[f+2].val is True:
212 dprint('n1a')
213 self.checkNew(f+2) # I think@@
214 else:
215 dprint('x1a')
216 else:
217 dprint('x1b')
204 if self.runs[-1]==l: 218 if self.runs[-1]==l:
205 # is it safely _right_ marginal, i.e. no blobs or big enough gaps _after_ us? 219 # is it safely _right_ marginal, i.e. no blobs or big enough gaps _after_ us?
206 if self.marginal(range(self.marginN-1,f,-1),l): 220 if self.marginal(range(self.marginN-1,f,-1),l):
207 changed=True 221 changed=True
222 dprint('n2')
208 # mark our margins 223 # mark our margins
209 for i in range(self.marginN-1,f,-1): 224 for i in range(self.marginN-1,f,-1):
210 if self[i].val is None: 225 if self[i].val is None:
211 self[i].setVal(False) 226 self[i].setVal(False)
212 if s>self.margin0+1: 227 if s>self.margin0+1:
213 if self[s-1].val is None: 228 if self[s-1].val is None:
214 self[s-1].setVal(False) 229 self[s-1].setVal(False)
215 if s>self.margin0+2 and self[s-2].val is True:
216 dprint('n2')
217 self.checkNew(s-2) # I think@@
218 self.foundN(s) # pull in the finish margin at least to s-2 230 self.foundN(s) # pull in the finish margin at least to s-2
231 if s>self.margin0+2 and self[s-2].val is True:
232 dprint('n2a')
233 self.checkNew(s-2) # I think@@
234 else:
235 dprint('x2a')
236 else:
237 dprint('x2b')
219 if changed: 238 if changed:
220 self.resetAllRuns() 239 self.resetAllRuns()
221 240
222 def marginal(self,rng,l): 241 def marginal(self,rng,l):
223 g=0 # length of a gap 242 g=0 # length of a gap
224 for i in rng: 243 for i in rng:
225 if self[i].val is True: 244 if self[i].val is True:
245 dprint('mx0')
226 return False 246 return False
227 if self[i].val is False: 247 if self[i].val is False:
228 g=0 248 g=0
229 else: 249 else:
230 # None 250 # None
231 g+=1 251 g+=1
232 if g==l: 252 if g==l:
253 dprint('mx1')
233 return False 254 return False
234 return True 255 return True
235 256
236 def found0(self,i): 257 def found0(self,i):
237 print('found0 called on %s at %s'%(self,i)) 258 print('found0 called on %s at %s'%(self,i))
264 285
265 def __str__(self): 286 def __str__(self):
266 return ((self.fmt%(' '.join(str(r) for r in self.runs)))+ 287 return ((self.fmt%(' '.join(str(r) for r in self.runs)))+
267 Vector.__str__(self)) 288 Vector.__str__(self))
268 289
269 def updateHeader(self,maxWidth=None,r=None,pre=None): 290 def updateHeader(self,*,maxWidth=None,r=None,pre=None):
270 if maxWidth is None: 291 if maxWidth is None:
271 # update 292 # update
272 if pre: 293 if pre:
273 self.infix+=(RedFmt%r)+" " 294 self.infix+=(RedFmt%r)+" "
274 else: 295 else:
281 self.prespace=' '*(maxWidth-self.width) 302 self.prespace=' '*(maxWidth-self.width)
282 self.fmt="%s%%s|"%self.prespace 303 self.fmt="%s%%s|"%self.prespace
283 self.infix="" 304 self.infix=""
284 self.suffix="" 305 self.suffix=""
285 306
286 def newBlob(self,x,newSeq): 307 def newBlob(self,x,crossCheck=False):
287 self[x].setVal(True) 308 self[x].setVal(True)
288 self[x].column.checkNew(self.y) 309 if crossCheck:
289 if newSeq: 310 self[x].column.checkNew(self.y)
290 # We don't always check ourself, to avoid unnecessary duplication...
291 self.checkNew(x)
292 311
293 class Column(Vector): 312 class Column(Vector):
294 def __init__(self,n,m,runs,pos): 313 def __init__(self,n,m,runs,pos):
295 Vector.__init__(self,n,m,runs) 314 Vector.__init__(self,n,m,runs)
296 self.x=pos 315 self.x=pos
297 self.height=self.myPrintSize() 316 self.height=self.myPrintSize()
298 317
299 def updateHeader(self,maxHeight): 318 def updateHeader(self,*,maxHeight=None,r=None,pre=None):
300 self.maxHeight=maxHeight 319 if maxHeight is None:
301 self.fmt="%s%%s"%(' '*(maxHeight - self.height)) 320 # update
302 header=('-'.join(str(c) for c in self.runs)) 321 if pre:
303 self.header=self.fmt%header # pad to same 'height' 322 self.infix+=(RedFmt%r)+" "
304 323 else:
305 def newBlob(self,y,newSeq): 324 # post
325 self.suffix=" "+RedFmt%r+self.suffix
326 self.fmt="%s%s%%s%s"%(self.prespace,self.infix,self.suffix)
327 else:
328 # init
329 self.maxHeight=maxHeight
330 self.infix=""
331 self.suffix=""
332 header=('-'.join(str(c) for c in self.runs))
333 self.prespace=' '*(maxHeight - self.height) # pad to same 'height'
334 self.fmt="%s%%s"%self.prespace
335 self.header=self.fmt%header
336
337 def newBlob(self,y,crossCheck=False):
306 self[y].setVal(True) 338 self[y].setVal(True)
307 self[y].row.checkNew(self.x) 339 if crossCheck:
308 if newSeq: 340 self[y].row.checkNew(self.x)
309 # We don't always check ourself, to avoid unnecessary duplication...
310 self.checkNew(y)
311 341
312 class Cell: 342 class Cell:
313 def __init__(self,row,y,column,x): 343 def __init__(self,row,y,column,x):
314 # At the intersection of row and column Vectors 344 # At the intersection of row and column Vectors
315 self.row=row 345 self.row=row
350 self.cc=runsPerCol 380 self.cc=runsPerCol
351 # print col nums>9 vertically :-( 381 # print col nums>9 vertically :-(
352 self.columns=cc=[Column(n,self,runsPerCol[i],i) for i in range(n)] 382 self.columns=cc=[Column(n,self,runsPerCol[i],i) for i in range(n)]
353 self.maxCRheight=maxCRheight=max(col.height for col in cc) 383 self.maxCRheight=maxCRheight=max(col.height for col in cc)
354 for c in cc: 384 for c in cc:
355 c.updateHeader(maxCRheight) 385 c.updateHeader(maxHeight=maxCRheight)
356 self.rows=rr=[Row(n,self,runsPerRow[i],i) for i in range(n)] 386 self.rows=rr=[Row(n,self,runsPerRow[i],i) for i in range(n)]
357 maxRRwidth=max(row.width for row in rr) 387 maxRRwidth=max(row.width for row in rr)
358 for r in rr: 388 for r in rr:
359 r.updateHeader(maxRRwidth) 389 r.updateHeader(maxWidth=maxRRwidth)
360 self.rowfmt="%s|%%s|"%(' '*maxRRwidth) 390 self.rowfmt="%s|%%s|"%(' '*maxRRwidth)
361 for x in range(n): 391 for x in range(n):
362 for y in range(n): 392 for y in range(n):
363 self[(x,y)]=Cell(rr[y],y,cc[x],x) 393 self[(x,y)]=Cell(rr[y],y,cc[x],x)
364 394