Changeset - e79c5818edfd
[Not reviewed]
default
0 1 1
Laman - 7 years ago 2017-10-16 22:16:03

algoritmus X
2 files changed with 97 insertions and 1 deletions:
0 comments (0 inline, 0 general)
dlx.py
Show inline comments
 
new file 100644
 
# 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
 
		self.col=col
 

	
 

	
 
class Column(Cell):
 
	def __init__(self,name,*args,**kwargs):
 
		super().__init__(*args,**kwargs)
 
		self.name=name
 
		self.size=0
 

	
 
	def cover(self):
 
		self.right.left=self.left
 
		self.left.right=self.right
 
		r=self.down
 
		while r is not self:
 
			c=r.right
 
			while c is not r:
 
				c.down.up=c.up
 
				c.up.down=c.down
 
				c.col.size-=1
 
				c=c.right
 
			r=r.down
 

	
 
	def uncover(self):
 
		r=self.up
 
		while r is not self:
 
			c=r.left
 
			while c is not r:
 
				c.col.size+=1
 
				c.down.up=c
 
				c.up.down=c
 
				c=c.left
 
			r=r.up
 
		self.right.left=self
 
		self.left.right=self
 

	
 

	
 
class Header:
 
	def __init__(self,left=None,right=None):
 
		self.left=left
 
		self.right=right
 
		self._res=[]
 

	
 
	def search(self,k=0):
 
		if self.right is self:
 
			self.print()
 
			return True
 
		if len(self._res)<=k:
 
			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=row.right
 
			c=row.left
 
			while c is not row:
 
				c.col.uncover()
 
				c=c.left
 
		col.uncover()
 

	
 
	def chooseCol(self):
 
		c=self.right
 
		best=c.size
 
		res=c
 
		while c is not self:
 
			if c.size<best:
 
				best=c.size
 
				res=c
 
			c=c.right
 
		return res
 

	
 
	def print(self):
 
		for r in self._res:
 
			c=r.right
 
			while c is not r:
 
				print(c.col.name,end=" ")
 
				c=c.right
 
			print()
 
		print()
tetris.py
Show inline comments
 
EMPTY="."
 
FULL="O"
 

	
 

	
 
class Piece:
 
	def __init__(self,variants):
 
		self.variants=variants
 

	
 

	
 
pieceSet=dict()
 

	
 
pieceSet["sq"]=Piece([
 
	# OO
 
	# OO
 
	((0,0),(0,1),(1,0),(1,1))
 
])
 

	
 
pieceSet["long"]=Piece([
 
	# OOOO
 
	((0,0),(0,1),(0,2),(0,3)),
 
	((0,0),(1,0),(2,0),(3,0))
 
])
 

	
 
pieceSet["boat"]=Piece([
 
	# OOO
 
	# .O.
 
	((0,0),(0,1),(0,2),(1,1)),
 
	((0,0),(1,0),(2,0),(1,1)),
 
	((0,0),(1,-1),(1,0),(1,1)),
 
	((0,0),(1,-1),(1,0),(2,0))
 
])
 

	
 
pieceSet["sz"]=Piece([
 
	# .OO
 
	# OO.
 
	((0,0),(0,1),(1,-1),(1,0)),
 
	((0,0),(1,0),(1,1),(2,1)),
 

	
 
	# OO.
 
	# .OO
 
	((0,0),(0,1),(1,1),(1,2)),
 
	((0,0),(1,0),(1,-1),(2,-1))
 
])
 

	
 
pieceSet["el"]=Piece([
 
	# OOO
 
	# O..
 
	((0,0),(1,0),(0,1),(0,2)),
 
	((0,0),(1,0),(2,0),(2,1)),
 
	((0,0),(1,-2),(1,-1),(1,0)),
 
	((0,0),(0,1),(1,1),(2,1)),
 

	
 
	# OOO
 
	# ..O
 
	((0,0),(0,1),(0,2),(1,2)),
 
	((0,0),(0,1),(1,0),(2,0)),
 
	((0,0),(1,0),(1,1),(1,2)),
 
	((0,0),(1,0),(2,0),(2,-1))
 
])
 

	
 
WIDTH=8
 
HEIGHT=5
 
board=[[EMPTY]*WIDTH for r in range(HEIGHT)]
 

	
 

	
 
def fill(board,pieces):
 
	point=firstEmpty(board)
 
	if not point: return True
 
	res=[]
 
	for (i,(k,p)) in enumerate(pieces):
 
		if k==0: continue
 
		for v in p.variants:
 
			if place(board,point,v):
 
				pieces[i][0]-=1
 
				partialRes=fill(board,pieces)
 
				if partialRes:
 
					res+=[((point,v), partialRes)]
 
					res.append(((point,v), partialRes))
 
				remove(board,point,v)
 
				pieces[i][0]+=1
 
	return res
 

	
 

	
 
def firstEmpty(board):
 
	for (r,row) in enumerate(board):
 
		for (c,cell) in enumerate(row):
 
			if cell==EMPTY:
 
				return (r,c)
 
	return None
 

	
 

	
 
def place(board,point,piece):
 
	(r,c)=point
 
	if not all(0<=r+ri<HEIGHT and 0<=c+ci<WIDTH and board[r+ri][c+ci]==EMPTY for (ri,ci) in piece):
 
		return False
 
	for (ri,ci) in piece:
 
		board[r+ri][c+ci]=FULL
 
	return True
 

	
 

	
 
def remove(board,point,piece):
 
	(r,c)=point
 
	for (ri,ci) in piece:
 
		board[r+ri][c+ci]=EMPTY
 

	
 

	
 
def visualise(board,tree,letter="A"):
 
	if tree is True:
 
		for row in board:
 
			print("".join(row))
 
		print()
 
		return
 
	for (((r,c),piece),rest) in tree:
 
		for (ri,ci) in piece:
 
			board[r+ri][c+ci]=letter
 
		visualise(board,rest,chr(ord(letter)+1))
 

	
 

	
 
res=fill(board,[[k,pieceSet[x]] for (k,x) in [(2,"sq"),(2,"el"),(2,"boat"),(2,"long"),(2,"sz")]])
 
if res:
 
	visualise(board,res)
 
else:
 
	print(res)
0 comments (0 inline, 0 general)