changeset 70:578cb569d815 simple

Maybe fixed previous bug, pbly need to start returning changed flags and looping
author Henry Thompson <ht@markup.co.uk>
date Sun, 04 Jun 2023 16:24:20 +0100
parents c22f83e049a9
children eea4bcb657bc
files nono.py
diffstat 1 files changed, 42 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/nono.py	Sat Jun 03 22:11:12 2023 +0100
+++ b/nono.py	Sun Jun 04 16:24:20 2023 +0100
@@ -14,6 +14,9 @@
     yield from vals
 
 class Run:
+  '''What we're looking for, converted eventually into what
+     we've found.
+     "left" and "right" make sense for Rows, for Columns read "above" and "below"'''
   def __init__(self,n,i,j):
     # A run of length n, starting within [i,j]
     self.n=n
@@ -21,6 +24,15 @@
     self.j=j
     self.s=j-i
     self.done=False
+    self.left=self.right=None
+
+  def leftEdge(self):
+    return self.i
+
+  def rightEdge(self):
+    if self.done:
+      return self.i+self.n-1
+    return self.j+self.n-1
 
   def __str__(self):
     return str(self.n)
@@ -29,6 +41,10 @@
   def __init__(self,n,i,j):
     # A space of length 1..n, starting within [i,j]
     # Once done, length == n
+    # i and j don't change, but s, which is used by check0
+    #  to decide where to look, is optimistic and may need to
+    #  be restricted if there is an overlap with the next (forward or backward)
+    #  run (see self.right and self.left, if any, respectively)
     assert n>0
     self.n=n
     self.i=i
@@ -66,6 +82,12 @@
         if runs:
           self.runs.append(Space(space,pos,pos+space))
           pos+=1
+      # Adjacent pairs mutually restrict possible starting points
+      for i in range(0,self.rn-1):
+        left=self.runs[2*i]
+        right=self.runs[(2*i)+2]
+        left.right=right
+        right.left=left
     self.initDisp()
 
   def __str__(self):
@@ -373,14 +395,22 @@
         self[p].setVal(True)
 
   def check0(self):
-    # check 1st and last not-done runs for completeness
-    # forwards
+    # Check 1st and last not-done runs for completeness
+    # Have to restrict lookahead/behind if there's overlap between runs...
+    # Forwards
+    # ****Assumes margin0 is 0***** and marginN is n
     for i in range(0,len(self.runs),2):
       run=self.runs[i]
       if not run.done:
         # look for first True cell
-        for p in range(run.i,run.i+run.s+1):
+        for p in range(run.i,min(run.i+run.s+1,
+                                 run.right.leftEdge()-run.n if (run.right and run.i>run.n) else 100)):
           if self[p].val:
+            if p>0 and self[p-1].val==False:
+              # We're pinned, force start here from now on
+              self.i=p
+              self.s=p+1
+              self.right=None #Maybe?
             l=self.trueRun(p,run.n)
             if l==run.n:
               if p!=0:
@@ -398,8 +428,13 @@
       run=self.runs[m-i]
       if not run.done:
         # look for first True cell
-        for p in range(run.i+run.s,run.i-1,-1):
+        for p in range(run.i+run.s+(run.n-1),
+                       max(run.i-1,run.left.rightEdge()+run.n if (run.left and run.i<self.n-run.n) else 0),-1):
           if self[p].val:
+            if p<self.n-1 and self[p+1]==False:
+              self.i=p
+              self.s=p+1
+              self.left=None # Maybe?
             l=self.trueRun(p,run.n,-1)
             if l==run.n:
               e=p-l
@@ -597,10 +632,13 @@
   def pass0(self): # do columns of empty layout
     for c in self.columns:
       c.pass0()
+    print(self)
     for r in self.rows:
       r.pass0()
+    print(self)
     for c in self.columns:
       c.check0()
+    print(self)
     for r in self.rows:
       r.check0()