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()