Mercurial > hg > python
comparison nono.py @ 72:15e540c190d5 simple
derive Nono from list, not dict, and get [x,y] working
| author | Henry Thompson <ht@markup.co.uk> |
|---|---|
| date | Sat, 09 Aug 2025 15:48:34 -0400 |
| parents | eea4bcb657bc |
| children | 63e87db2bc31 |
comparison
equal
deleted
inserted
replaced
| 71:eea4bcb657bc | 72:15e540c190d5 |
|---|---|
| 1 #!/usr/bin/python3 | 1 #!/usr/bin/python3 |
| 2 # New version, input taken from Nonograms Outer HTML plus | 2 # New version, input taken from Nonograms Outer HTML plus |
| 3 # > fgrep 'task = ' nono10.xhtml|tr ';' '\n' | fgrep task\ = | sed 's/^.*= //'| tr -d \' | 3 # > fgrep 'task = ' nono10.xhtml|tr ';' '\n' | fgrep task\ = | sed 's/^.*= //'| tr -d \' |
| 4 # E.g. 8/5.1/2.3/2.1/4.3/3.4/2/1.1/3/5.2/2.2/2.2/1.3.2/5.1/3.1.1/2/2.3.1/7.1/1.1.2/3.2 | 4 # E.g. 8/5.1/2.3/2.1/4.3/3.4/2/1.1/3/5.2/2.2/2.2/1.3.2/5.1/3.1.1/2/2.3.1/7.1/1.1.2/3.2 |
| 5 | |
| 6 ####### New Plan ####### | |
| 7 # All that matters is runs of incomplete cells. We begin with n+n runs, the maximum number is | |
| 8 # sum(len(rn) for rn in rows U cols) | |
| 9 # My own strategy seems to be FIFO for pass 0, then LIFO, for the queue of new/changed runs | |
| 10 # By cases, wrt types of change of a cell in its runs | |
| 11 # Change at the margin: | |
| 12 # New fill: complete the run and discard it, kill the other end and queue it | |
| 13 # dead: advance margin and add fill to any internal sequences of fills (always?), queue the new fill(s) | |
| 14 # Change in the middle | |
| 15 # New dead: If deterministic, split the run in two and requeue the cell (now in two runs) | |
| 16 # fill: If deterministic single gap at any end, kill, split, and requeue the cell (now in two runs) | |
| 17 #---------- | |
| 18 # Doesn't yet cover everything, e.g. killing gaps that are too small to be filled | |
| 19 # Do we need to actually represent run-internal segments, e.g. skips and bars? | |
| 20 | |
| 5 | 21 |
| 6 import sys | 22 import sys |
| 7 | 23 |
| 8 Red='[31m' | 24 Red='[31m' |
| 9 eRed='[39m' | 25 eRed='[39m' |
| 261 if self.val is not None: | 277 if self.val is not None: |
| 262 eprint("Reset not allowed: %s -> %s at %s,%s"%(self.val, v, self.x,self.y),err=103) | 278 eprint("Reset not allowed: %s -> %s at %s,%s"%(self.val, v, self.x,self.y),err=103) |
| 263 self.val=v | 279 self.val=v |
| 264 return True | 280 return True |
| 265 | 281 |
| 266 class Nono(dict): | 282 class Nono(list): |
| 283 | |
| 267 # 0,0 is upper left, so increasing y goes _downwards_, to match the standard layout | 284 # 0,0 is upper left, so increasing y goes _downwards_, to match the standard layout |
| 268 def __init__(self,runsPerRow,runsPerCol,debug): | 285 def __getitem__(self,xy): |
| 286 return list.__getitem__(self,xy[1])[xy[0]] | |
| 287 | |
| 288 def __setitem__(self,xy,v): | |
| 289 list.__getitem__(self,xy[1])[xy[0]] = v | |
| 290 | |
| 291 def __init__(self,runsPerRow: list[int], | |
| 292 runsPerCol: list[int], | |
| 293 debug: bool) -> list[list[Cell]]: | |
| 269 global SOLVER | 294 global SOLVER |
| 270 self.loop=0 | 295 self.loop=0 |
| 271 self.dp='' # old depth hack | 296 self.dp='' # old depth hack |
| 272 self.debug = debug | 297 self.debug = debug |
| 273 self.dstate=[] | 298 self.dstate=[] |
| 274 SOLVER=self | 299 SOLVER=self |
| 275 n=self.n=len(runsPerCol) | 300 n=self.n=len(runsPerCol) |
| 301 list.__init__(self,list(list(list(range(n)) for _ in range(n)))) | |
| 276 if n!=len(runsPerRow): | 302 if n!=len(runsPerRow): |
| 277 print("losing r:%s x c:%s"%(len(runsPerRow),n),sys.stderr) | 303 print("losing r:%s x c:%s"%(len(runsPerRow),n),sys.stderr) |
| 278 exit(1) | 304 exit(1) |
| 279 self.rc=runsPerRow | 305 self.rc=runsPerRow |
| 280 self.cc=runsPerCol | 306 self.cc=runsPerCol |
| 281 # print col nums>9 vertically :-( | 307 # print col nums>9 vertically :-( |
| 282 self.columns=cc=[Column(n,self,i) for i in range(n)] | 308 self.columns=cc=[Column(n,self,i) for i in range(n)] |
| 283 self.rows=rr=[Row(n,self,i) for i in range(n)] | 309 self.rows=rr=[Row(n,self,i) for i in range(n)] |
| 284 for x in range(n): | 310 for x in range(n): |
| 285 for y in range(n): | 311 for y in range(n): |
| 286 self[(x,y)]=Cell(rr[y],y,cc[x],x) | 312 self[x,y]=Cell(rr[y],y,cc[x],x) |
| 287 # Need cells in place for the following | 313 # Need cells in place for the following |
| 288 for row,runs in zip(rr,runsPerRow): | 314 for row,runs in zip(rr,runsPerRow): |
| 289 row.initRuns(runs) | 315 row.initRuns(runs) |
| 290 for col,runs in zip(cc,runsPerCol): | 316 for col,runs in zip(cc,runsPerCol): |
| 291 col.initRuns(runs) | 317 col.initRuns(runs) |
