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='' 24 Red=''
9 eRed='' 25 eRed=''
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)