Mercurial > hg > python
diff nono.py @ 7:13f600be3a1b
implemented newBlob and found0, refactoring display
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Wed, 11 Mar 2020 17:13:05 +0000 |
parents | a56d5285575b |
children | 3276cf6ee6df |
line wrap: on
line diff
--- a/nono.py Tue Mar 10 19:56:07 2020 +0000 +++ b/nono.py Wed Mar 11 17:13:05 2020 +0000 @@ -28,8 +28,8 @@ self.margin0=0 # a run can start here, so if >0 then self[m0-1].val must be False self.marginN=n-1 # a run can end here, so if <n-1 then self[mN+1].val ditto self.runs=self.origRuns=runs - self.initialComplete=[] - self.finalComplete=[] + self.initialComplete="" + self.finalComplete="" self.resetAllRuns() def __repr__(self): @@ -38,6 +38,9 @@ def __str__(self): return '%s|'%('|'.join(str(c) for c in self)) + def myPrintSize(self): + return sum(len(str(run)) for run in self.runs)+len(self.runs)-1 + def resetAllRuns(self): # compute the set of all possible layouts for runs self.rn=len(self.runs) @@ -71,17 +74,26 @@ dprint('=====pass %s======'%k) self.onepass(0,self.n,scratch,runs.copy()) dprint(scratch) + newSeq=False + inSeq=False for i in range(self.n): if scratch[i]==self.nar: # If blobby in _every_ pass, then must be a blob + if inSeq: + newSeq=False + else: + inSeq=True + newSeq=True if self[i].val is None: - self[i].setVal(True) + self.newBlob(i,newSeq) elif self[i].val is True: # already there pass else: print("Shouldn't happen: attempt to blob where x already present! %s at %s"%(self,i),file=sys.stderr) exit(101) + else: + inSeq=newSeq=False def onepass(self,i0,iBound,scratch,stack): """note that stack is not a simple run, but one with _negative_ numbers between @@ -199,7 +211,7 @@ changed=False # First, find our boundaries: s=pos # start index of our run - while s>self.marginO and self[s-1].val is True: + while s>self.margin0 and self[s-1].val is True: s-=1 f=pos # finish index of our run while f<self.marginN and self[f+1].val is True: @@ -213,16 +225,16 @@ j=self.runs.index(l) if j==0: # is it safely left marginal, i.e. no blobs or big enough gaps before us? - if marginal(range(self.margin0,s)): + if self.marginal(range(self.margin0,s),l): changed=True # mark our margins - for i in range(margin0+1,s): + for i in range(self.margin0+1,s): if self[i].val is None: self[i].setVal(False) - if f<marginN-1: + if f<self.marginN-1: if self[f+1].val is None: self[f+1].setVal(False) - if f<marginN-2 and self[f+2].val is True: + if f<self.marginN-2 and self[f+2].val is True: dprint('n1') self.checkNew(f+2) # I think@@ self.found0(f) # pull in the start margin at least to f+2 @@ -231,13 +243,13 @@ if self.marginal(range(self.marginN-1,r,-1),l): changed=True # mark our margins - for i in range(marginN-1,f,-1): + for i in range(self.marginN-1,f,-1): if self[i].val is None: self[i].setVal(False) - if s>margin0+1: + if s>self.margin0+1: if self[s-1].val is None: self[s-1].setVal(False) - if s>margin0+2 and self[s-2].val is True: + if s>self.margin0+2 and self[s-2].val is True: dprint('n2') self.checkNew(s-2) # I think@@ self.foundN(s) # pull in the finish margin at least to s-2 @@ -258,29 +270,59 @@ return False return True + def found0(self,i): + dprint('found0 called on %s at %s'%(self,i)) + i=self.margin0 + while self[i].val is False: + i+=1 + if self[i].val is True: + r=self.runs.pop(0) + self.initialComplete+=(RedFmt%r) + self.margin0+=r+1 + + def foundN(self,i): + print('foundN called on %s at %s'%(self,i),file=sys.stderr) + class Row(Vector): - def __init__(self,n,m,runs,pos,dprintWidth): + def __init__(self,n,m,runs,pos): Vector.__init__(self,n,m,runs) self.y=pos - self.dprintWidth=dprintWidth - self.fmt="%%%ss|"%dprintWidth + self.width=self.myPrintSize() def __str__(self): return ((self.fmt%(' '.join(str(r) for r in self.runs)))+ Vector.__str__(self)) + def updateHeader(self,maxWidth): + self.maxWidth=maxWidth + self.fmt="%s%%s|"%(' '*(maxWidth-self.width)) + + def newBlob(self,x,newSeq): + self[x].setVal(True) + self[x].column.checkNew(self.y) + if newSeq: + # We don't always check ourself, to avoid unnecessary duplication... + self.checkNew(x) + class Column(Vector): - def __init__(self,n,m,runs,pos,dprintHeight): + def __init__(self,n,m,runs,pos): Vector.__init__(self,n,m,runs) self.x=pos - self.dprintHeight=dprintHeight - self.fmt="%%%ss"%self.dprintHeight - self.updateHeader() + self.height=self.myPrintSize() - def updateHeader(self): + def updateHeader(self,maxHeight): + self.maxHeight=maxHeight + self.fmt="%s%%s"%(' '*(maxHeight - self.height)) header=('-'.join(str(c) for c in self.runs)) self.header=self.fmt%header # pad to same 'height' + def newBlob(self,y,newSeq): + self[y].setVal(True) + self[y].row.checkNew(self.x) + if newSeq: + # We don't always check ourself, to avoid unnecessary duplication... + self.checkNew(y) + class Cell: def __init__(self,row,y,column,x): # At the intersection of row and column Vectors @@ -306,9 +348,6 @@ # No-op return self.val=v - self.row.checkNew(self.x) - self.column.checkNew(self.y) - # @@ check row/col completed else: if self.val is not None: print("Warning: %s -> %s at %s,%s"%(self.val,v,self.x,self.y),file=sys.stderr) @@ -316,26 +355,30 @@ class Nono(dict): # 0,0 is upper left, so increasing y goes _downwards_, to match the standard layout - def __init__(self,rows,cols): - n=self.n=len(cols) - if n!=len(rows): - print("losing r:%s x c:%s"%(len(rows),n),sys.stderr) + def __init__(self,runsPerRow,runsPerCol): + n=self.n=len(runsPerCol) + if n!=len(runsPerRow): + print("losing r:%s x c:%s"%(len(runsPerRow),n),sys.stderr) exit(1) - self.rc=rows - rowDprintWidth=max(sum(len(str(r)) for r in row)+len(row)-1 for row in rows) - self.rowfmt="%s|%%s"%(' '*rowDprintWidth) - self.cc=cols - # dprint col nums>9 vertically :-( - self.colDprintHeight=max(sum(len(str(c)) for c in col)+len(col)-1 for col in cols) - self.columns=cc=[Column(n,self,cols[i],i,self.colDprintHeight) for i in range(20)] - self.rows=rr=[Row(n,self,rows[i],i,rowDprintWidth) for i in range(20)] + self.rc=runsPerRow + self.cc=runsPerCol + # print col nums>9 vertically :-( + self.columns=cc=[Column(n,self,runsPerCol[i],i) for i in range(20)] + self.maxCRheight=maxCRheight=max(col.height for col in cc) + for c in cc: + c.updateHeader(maxCRheight) + self.rows=rr=[Row(n,self,runsPerRow[i],i) for i in range(20)] + maxRRwidth=max(row.width for row in rr) + for r in rr: + r.updateHeader(maxRRwidth) + self.rowfmt="%s|%%s|"%(' '*maxRRwidth) for x in range(20): for y in range(20): self[(x,y)]=Cell(rr[y],y,cc[x],x) def __str__(self): lines=[self.rowfmt%('|'.join([(self.columns[i]).header[j] for i in range(self.n)])) # 'rotate' - for j in range(self.colDprintHeight)] + for j in range(self.maxCRheight)] lines+=[str(r) for r in self.rows] return "\n".join(lines)