Mercurial > hg > python
diff nono.py @ 6:a56d5285575b
drafted Vector.checkNew, still need found0 and foundN
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Tue, 10 Mar 2020 19:56:07 +0000 |
parents | fee51ab07d09 |
children | 13f600be3a1b |
line wrap: on
line diff
--- a/nono.py Mon Mar 09 17:39:38 2020 +0000 +++ b/nono.py Tue Mar 10 19:56:07 2020 +0000 @@ -25,7 +25,20 @@ def __init__(self,n,m,runs): list.__init__(self,list(range(n))) self.n=n - self.runs=runs + 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.resetAllRuns() + + def __repr__(self): + return "V@%s%s:%s"%(self.x,self.origRuns,list.__repr__(self)) + + def __str__(self): + return '%s|'%('|'.join(str(c) for c in self)) + + def resetAllRuns(self): # compute the set of all possible layouts for runs self.rn=len(self.runs) rtot=sum(self.runs) @@ -52,12 +65,6 @@ for sub in self.seedList(1,j+1,pos+v+r,runLen-(r+1)): yield [-v,r]+sub - def __repr__(self): - return "V@%s%s:%s"%(self.x,self.runs,list.__repr__(self)) - - def __str__(self): - return '%s|'%('|'.join(str(c) for c in self)) - def step(self): scratch=[0 if c.val is None else c.val for c in self] for k,runs in enumerate(self.allRuns): @@ -185,6 +192,72 @@ for k in range(iBound): scratch[k]+=maybe[k] + def checkNew(self,pos): + # New blob at pos, can we complete anything? + # Assuming @@ FTTB that it's never possible to definitively complete a + # non-marginal run, which is wrong if the length is unique and it's bounded... + changed=False + # First, find our boundaries: + s=pos # start index of our run + while s>self.marginO 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: + f+=1 + l=(f-s)+1 # our length + c=self.runs.count(l) + if c==0: + # not big enough yet + dprint('n0') + return + 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)): + changed=True + # mark our margins + for i in range(margin0+1,s): + if self[i].val is None: + self[i].setVal(False) + if f<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: + dprint('n1') + self.checkNew(f+2) # I think@@ + self.found0(f) # pull in the start margin at least to f+2 + elif j==self.rn-1: + # is it safely _right_ marginal, i.e. no blobs or big enough gaps _after_ us? + if self.marginal(range(self.marginN-1,r,-1),l): + changed=True + # mark our margins + for i in range(marginN-1,f,-1): + if self[i].val is None: + self[i].setVal(False) + if s>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: + dprint('n2') + self.checkNew(s-2) # I think@@ + self.foundN(s) # pull in the finish margin at least to s-2 + if changed: + self.resetAllRuns() + + def marginal(self,rng,l): + g=0 # length of a gap + for i in rng: + if self[i].val is True: + return False + if self[i].val is False: + g=0 + else: + # None + g+=1 + if g==l: + return False + return True + class Row(Vector): def __init__(self,n,m,runs,pos,dprintWidth): Vector.__init__(self,n,m,runs) @@ -228,15 +301,18 @@ def setVal(self,v): if v is True: if self.val is False: - dprint("Warning: x -> * at %s,%s"%(self.x,self.y)) + print("Warning: x -> * at %s,%s"%(self.x,self.y),file=sys.stderr) elif self.val is True: # 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: - dprint("Warning: %s -> %s at %s,%s"%(self.val,v,self.x,self.y)) - self.val=v + print("Warning: %s -> %s at %s,%s"%(self.val,v,self.x,self.y),file=sys.stderr) + self.val=v class Nono(dict): # 0,0 is upper left, so increasing y goes _downwards_, to match the standard layout