Mercurial > hg > python
changeset 11:1b9daa849b0f
A bit further: red col working, finding middle of row 1, formatting off, outer loop in place, but fails overall after 3rd pass achieves nothing
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Sun, 15 Mar 2020 17:05:49 +0000 |
parents | 0a24625b33fa |
children | ede2551ae7d9 |
files | nono.py |
diffstat | 1 files changed, 68 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/nono.py Sat Mar 14 19:13:23 2020 +0000 +++ b/nono.py Sun Mar 15 17:05:49 2020 +0000 @@ -45,32 +45,37 @@ # compute the set of all possible layouts for runs self.rn=len(self.runs) rtot=sum(self.runs) - self.allRuns=list(self.seedList(0,0,0, + self.allRuns=list(self.seedList(0,0,self.margin0,self.marginN+1, sum(1+self.runs[k] for k in range(self.rn))-1)) self.nar=len(self.allRuns) - def seedList(self,i,j,pos,runLen): + def seedList(self,i,j,pos0,posN,runLen): """ :param i: starting skip before next run :type i: 0 if pos==0 else 1 :param j: next run number :type j: int - :param pos: left margin - :type pos: int + :param pos0: left margin + :type pos0: int + :param posN: right margin + :type posN: int """ - bound=self.n-(pos+runLen)+1 - #dprint('s',i,j,pos,runLen,bound) + bound=posN-(pos0+runLen)+1 + dprint('s',i,j,pos0,posN,runLen,bound) if j==self.rn: yield [] return r=self.runs[j] for v in range(i,bound): - for sub in self.seedList(1,j+1,pos+v+r,runLen-(r+1)): + for sub in self.seedList(1,j+1,pos0+v+r,posN,runLen-(r+1)): yield [-v,r]+sub def step(self): + if self.runs==[]: + return 0 scratch=[0 if c.val is None else c.val for c in self] wins=0 + changed=0 for k,runs in enumerate(self.allRuns): dprint('=====pass %s======'%k) if self.onepass(self.margin0,self.marginN+1,scratch,runs.copy()): @@ -87,6 +92,7 @@ maybeSeq=None if self[i].val is None: self.newBlob(i,True) # Check cross-vector + changed=1 elif self[i].val is True: # already there pass @@ -105,14 +111,15 @@ dprint('s4',inSeq,i) if inSeq is not None: self.checkNew(i) + return changed def onepass(self,i0,iBound,scratch,stack): """note that stack is not a simple run, but one with _negative_ numbers between and possibly before the positive ones, indicating obligatory skips """ i=i0 # starting index into self/scratch/maybe - maybe=[0]*(iBound-i0) - dprint('r: %s'%stack) + maybe=[0]*self.n + dprint('r: %s'%stack,i0,iBound) req=sum((-r if r<0 else r) for r in stack) while stack and i<iBound: r=rr=stack.pop(0) @@ -208,37 +215,31 @@ if self[f+1].val is None: self[f+1].setVal(False) self.found0(f) # pull in the start margin at least to f+2 - if f<self.marginN-2 and self[f+2].val is True: - dprint('n1a') - self.checkNew(f+2) # I think@@ else: dprint('x1a') - else: - dprint('x1b') - if self.runs[-1]==l: - # is it safely _right_ marginal, i.e. no blobs or big enough gaps _after_ us? - if self.marginal(range(self.marginN-1,f,-1),l): - changed=True - dprint('n2') - # mark our margins - for i in range(self.marginN-1,f,-1): - if self[i].val is None: - self[i].setVal(False) - if s>self.margin0+1: - if self[s-1].val is None: - self[s-1].setVal(False) - self.foundN(s) # pull in the finish margin at least to s-2 - if s>self.margin0+2 and self[s-2].val is True: - dprint('n2a') - self.checkNew(s-2) # I think@@ + if not changed: + if self.runs[-1]==l: + # is it safely _right_ marginal, i.e. no blobs or big enough gaps _after_ us? + if self.marginal(range(self.marginN-1,f,-1),l): + changed=True + dprint('n2') + # mark our margins + for i in range(self.marginN-1,f,-1): + if self[i].val is None: + self[i].setVal(False) + if s>self.margin0+1: + if self[s-1].val is None: + self[s-1].setVal(False) + self.foundN(s) # pull in the finish margin at least to s-2 + else: + dprint('x2a') else: - dprint('x2a') - else: - dprint('x2b') + dprint('x2b') if changed: self.resetAllRuns() def marginal(self,rng,l): + print('m',rng.start,rng.stop,rng.step) g=0 # length of a gap for i in rng: if self[i].val is True: @@ -263,7 +264,7 @@ r=self.runs.pop(0) self.initialComplete.append(r) self.margin0+=r+1 - self.updateHeader(r=r) + self.updateHeader(r=r,pre=True) def foundN(self,i): print('foundN called on %s at %s'%(self,i)) @@ -274,7 +275,7 @@ r=self.runs.pop() self.finalComplete=[r]+self.finalComplete self.marginN-=r+1 - self.updateHeader(r=r) + self.updateHeader(r=r,pre=False) class Row(Vector): @@ -316,23 +317,34 @@ self.height=self.myPrintSize() def updateHeader(self,*,maxHeight=None,r=None,pre=None): + dprint('CuH',r,pre) if maxHeight is None: # update if pre: - self.infix+=(RedFmt%r)+" " + for rc in str(r): + self.infix.append(RedFmt%rc) + self.infix.append("-") else: # post - self.suffix=" "+RedFmt%r+self.suffix - self.fmt="%s%s%%s%s"%(self.prespace,self.infix,self.suffix) + ins=["-"] + for rc in str(r): + ins.append(RedFmt%r) + self.suffix=ins+self.suffix + dprint('CuH1: |%s|,%s,%s,%s'%(self.prespace,self.infix,self.suffix,self.runs)) + self.header=(["-"]*self.prespace)+\ + self.infix+\ + ['-'.join(str(c) for c in self.runs)]+\ + self.suffix else: # init self.maxHeight=maxHeight - self.infix="" - self.suffix="" + self.infix=[] + self.suffix=[] + self.prespace=maxHeight - self.height # pad to same 'height' + self.fmt="%s%%s"%(' '*self.prespace) header=('-'.join(str(c) for c in self.runs)) - self.prespace=' '*(maxHeight - self.height) # pad to same 'height' - self.fmt="%s%%s"%self.prespace self.header=self.fmt%header + dprint(self.header) def newBlob(self,y,crossCheck=False): self[y].setVal(True) @@ -398,6 +410,19 @@ lines+=[str(r) for r in self.rows] return "\n".join(lines) + def solve(self): + someChanged=1 + while someChanged>0: + someChanged=0 + for c in self.columns: + someChanged+=c.step() + print(someChanged) + print(self) + for r in self.rows: + someChanged+=r.step() + print(someChanged) + print(self) + def dprint(*args): print(*args) @@ -422,12 +447,4 @@ rows=[[int(s) for s in l.split()] for l in f] solver=Nono(rows,cols) - print(solver) - for c in solver.columns: - c.step() - print() - print(solver) - for r in solver.rows: - r.step() - print() - print(solver) + solver.solve()