Posted by Jonathan on Mon 31 Aug 03:53
report abuse | View followups from Jonathan and Jonathan | download | new post
- import numpy, matplotlib, pylab
- pieces = [
- numpy.matrix([[1,-1,1,-1],[0,0,0,1]]),
- numpy.matrix([[1,-1,1,-1],[-1,0,0,0]]),
- numpy.matrix([[-1,1,0],[0,-1,0],[0,1,-1]]),
- numpy.matrix([[-1,0],[1,-1],[0,1]]),
- numpy.matrix([[0,-1,1],[0,1,0],[1,-1,0]]),
- numpy.matrix([[-1,1,-1,1],[0,-1,0,0]]),
- numpy.matrix([[1,0,0],[-1,1,-1]]),
- numpy.matrix([[0,-1,0],[-1,1,-1]]),
- numpy.matrix([[1,0,0],[-1,1,0],[0,-1,1]]),
- numpy.matrix([[1,-1,1,0],[0,0,-1,1]]),
- numpy.matrix([[1,-1,1],[-1,0,0]]),
- numpy.matrix([[0,0,1,-1],[-1,1,-1,0]]),
- numpy.matrix([[0,1,0,0],[1,-1,1,-1]])
- ]
- board = numpy.zeros([8,8], dtype=int)
- board[6,6]=1
- board[7,6]=1
- board[7,7]=1
- positions = [(0,0) for piece in pieces] # starting positions of pieces
- rotations = [0 for piece in pieces] # n of counterclockwise rotations [0..3]
- placed = [False for piece in pieces]
- curpiece = 0
- def placePiece(curpiece):
- """Returns true if piece placed correctly, False if not valid position.
- Doesn't check boundaries."""
- # check inouty
- piece = pieces[curpiece]
- position = positions[curpiece]
- for x in range(piece.shape[0]):
- for y in range(piece.shape[1]):
- if (piece[x,y] != 0 and
- not inouty(position[0]+x, position[1]+y) == piece[x,y]
- ):
- return False
- if piece[x,y] != 0 and board[position[0]+x, position[1]+y] == 1:
- return False
- return True
- def incpos(curpiece):
- while True:
- if rotations[curpiece] < 3:
- rotations[curpiece] += 1
- pieces[curpiece] = numpy.rot90(pieces[curpiece])
- elif 8-positions[curpiece][1]-min(pieces[curpiece].shape)>0:
- positions[curpiece] = (positions[curpiece][0], positions[curpiece][1]+1)
- rotations[curpiece] = 0
- pieces[curpiece] = numpy.rot90(pieces[curpiece])
- elif 8-positions[curpiece][0]-min(pieces[curpiece].shape)>0:
- positions[curpiece] = (positions[curpiece][0]+1, 0)
- rotations[curpiece] = 0
- pieces[curpiece] = numpy.rot90(pieces[curpiece])
- else:
- return False
- # break if position valid
- if (8-positions[curpiece][1]-pieces[curpiece].shape[1]>=0 and
- 8-positions[curpiece][0]-pieces[curpiece].shape[0]>=0):
- return True
- def inouty(x,y):
- """+1 if male square, -1 if female square. Anomalous square hard-coded."""
- return ((x+y+1)%2)*2-1
- def tobin(piece, position):
- n=0L
- for x in range(piece.shape[0]):
- for y in range(piece.shape[1]):
- if piece[x,y] != 0:
- n = n | (2**((x+position[0])*8+y+position[1]))
- return n
- def frombin(piece, n):
- mat = numpy.zeros([8,8],int)
- for s in range(8**2):
- if n & 2**s:
- mat[s // 8, s % 8] = piece+1
- return mat
- allpositions = []
- for i in range(len(pieces)):
- if placePiece(i):
- allpositions.append((i, tobin(pieces[i], positions[i])))
- while incpos(i):
- if placePiece(i):
- allpositions.append((i, tobin(pieces[i], positions[i])))
- fixedpiece = tobin(board, (0,0))
- def findSolution(boardstate, usedpieces, remainingpieces, uptosquare):
- if len(remainingpieces) == 0:
- return usedpieces
- if boardstate & 2**uptosquare:
- return findSolution(boardstate, usedpieces, remainingpieces, uptosquare + 1)
- else:
- for piece in remainingpieces:
- if (boardstate & piece[1]) == 0 and (piece[1] & 2**uptosquare) != 0:
- result = findSolution(boardstate | piece[1], usedpieces + [piece],
- [p for p in remainingpieces if p[0] != piece[0]], uptosquare+1)
- if result != None:
- return result
- return None
- solution = findSolution(fixedpiece, [], allpositions, 0)
- pylab.matshow(sum([frombin(*piecet) for piecet in solution]))
- pylab.show()
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.