# based god Donald Knuth
# http://www-cs-faculty.stanford.edu/~uno/papers/dancing-color.ps.gz
# sám bych to asi nevymyslel
class Cell:
def __init__(self,left=None,right=None,up=None,down=None,col=None):
self.left=left
self.right=right
self.up=up
self.down=down
def __init__(self,col):
self.left=self
self.right=self
self.up=self
self.down=self
self.col=col
def attachRight(self,c):
"""...-(b)-(self)-> <-(c)-(d)-..."""
self.right.left=c.left
c.left.right=self.right
self.right=c
c.left=self
def attachDown(self,c):
self.down.up=c.up
c.up.down=self.down
self.down=c
c.up=self
class Column(Cell):
def __init__(self,name,*args,**kwargs):
super().__init__(*args,up=self,down=self,**kwargs)
def __init__(self,name):
super().__init__(self)
self.name=name
self.size=0
def cover(self):
self.right.left=self.left
self.left.right=self.right
@@ -45,14 +58,13 @@ class Column(Cell):
self.left.right=self
class Header(Column):
def __init__(self):
super().__init__("head")
self.up=self.down=self.size=None
self._res=[]
def search(self,k=0):
if self.right is self:
self.print()
return True
@@ -60,23 +72,23 @@ class Header(Column):
self._res.append(None)
col=self.chooseCol()
col.cover()
row=col.down
while row is not col:
row=row.down
self._res[k]=row
c=row.right
while c is not row:
c.col.cover()
self.search(k+1)
c=c.right
c=row.left
c.col.uncover()
c=c.left
col.uncover()
def chooseCol(self):
c=self.right
best=c.size
res=c
@@ -86,12 +98,13 @@ class Header(Column):
return res
def print(self):
for r in self._res:
print(r.col.name,end=" ")
c=r.right
while c is not r:
print(c.col.name,end=" ")
print()
@@ -24,33 +24,28 @@ for (name,piece) in pieces:
if fit is not False:
row=[0]*len(header)
row[index[name]]=1
for coords in fit: row[index[coords]]=1
matrix.append(row)
# print(header)
# for row in matrix: print(row)
print(header)
for row in matrix: print(row)
columns=[]
head=Header()
for label in header:
c=Column(label)
head.left.right=c
c.left=head.left
head.left=c
c.right=head
c.attachRight(head)
columns.append(c)
for row in matrix:
cells=[]
for (item,col) in zip(row,columns):
if item!=1: continue
c=Cell(up=col.up,down=col,col=col)
col.up.down=c
col.up=c
c=Cell(col)
c.attachDown(col)
cells.append(c)
c.right=cells[0]
c.left=cells[0].left
c.left.right=c
c.right.left=c
c.attachRight(cells[0])
col.size+=1
head.search()
Status change: