Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from itertools import product
- def rotate(queens):
- return ((7-queens[0][1],queens[0][0]),(7-queens[1][1],queens[1][0]),(7-queens[2][1],queens[2][0]))
- def reflect(queens):
- return ((7-queens[0][0],queens[0][1]),(7-queens[1][0],queens[1][1]),(7-queens[2][0],queens[2][1]))
- def canonicalize(queens):
- current = queens
- minq = sorted(queens)
- for ctr in range(3):
- current = rotate(current)
- minq = min(sorted(current),minq)
- current = reflect(queens)
- minq = min(sorted(current),minq)
- for ctr in range(3):
- current = rotate(current)
- minq = min(sorted(current),minq)
- return minq
- def iscoveredby(square,queens):
- x,y = square
- for queen in queens:
- if queen[0] == x or queen[1] == y or abs(queen[0]-x) == abs(queen[1]-y):
- return True
- return False
- def coverenough(queens):
- if sum([int(iscoveredby(sq,queens)) for sq in [[0,2],[0,5],[2,0],[2,7],[5,0],[5,7],[7,2],[7,5]]]) < 5:
- return False
- return True
- def coveredbyknightat(square):
- x,y = square
- gridmoves = [[x-2,y-1],[x-2,y+1],[x-1,y-2],[x-1,y+2],[x+1,y-2],[x+1,y+2],[x+2,y-1],[x+2,y+1]]
- return [(x,y)]+[(w,z) for [w,z] in gridmoves if 0 <= w < 8 and 0 <= z < 8]
- def centrality(square):
- return len(coveredbyknightat(square))
- def stillcoveredby(square,queens,knights):
- cbklist = coveredbyknightat(square)
- for knight in knights:
- if knight in cbklist:
- return True
- if square in queens:
- return True
- x,y = square
- for queen in queens:
- if queen[0] < x and x-queen[0] == y-queen[1]:
- interposed = False
- for i in range(1,x-queen[0]):
- if (queen[0]+i,queen[1]+i) in knights:
- interposed = True
- if not interposed:
- return True
- if queen[0] == x and queen[1] < y:
- interposed = False
- for i in range(1,y-queen[1]):
- if (queen[0],queen[1]+i) in knights:
- interposed = True
- if not interposed:
- return True
- if x < queen[0] and queen[0]-x == y-queen[1]:
- interposed = False
- for i in range(1,queen[0]):
- if (x+i,y-i) in knights:
- interposed = True
- if not interposed:
- return True
- if x < queen[0] and queen[1] == y:
- interposed = False
- for i in range(1,queen[0]-x):
- if (x+i,y) in knights:
- interposed = True
- if not interposed:
- return True
- if x < queen[0] and queen[0]-x == queen[1]-y:
- interposed = False
- for i in range(1,queen[0]-x):
- if (x+i,y+i) in knights:
- interposed = True
- if not interposed:
- return True
- if queen[0] == x and y < queen[1]:
- interposed = False
- for i in range(1,queen[1]-y):
- if (x,y+i) in knights:
- interposed = True
- if not interposed:
- return True
- if queen[0] < x and x-queen[0] == queen[1]-y:
- interposed = False
- for i in range(1,x-queen[0]):
- if (x-i,y+i) in knights:
- interposed = True
- if not interposed:
- return True
- if queen[0] < x and queen[1] == y:
- interposed = False
- for i in range(1,queen[0]-x):
- if (queen[0]+i,queen[1]) in knights:
- interposed = True
- if not interposed:
- return False
- return False
- # I am aware of the "for else" construction; I just wanted to make it more clear what was happening.
- def actuallyworks(queens,knights):
- if len(sorted(set(queens+knights))) != len(queens)+len(knights):
- return False
- for sq in product(range(8),range(8)):
- if not stillcoveredby(sq,queens,knights):
- return False
- return True
- candidates = set()
- for queen0x in range(4):
- for queen0y in range(queen0x+1):
- for queen1x in range(8):
- for queen1y in range(8):
- for queen2x in range(8):
- for queen2y in range(8):
- queens = ((queen0x,queen0y),(queen1x,queen1y),(queen2x,queen2y))
- if (queens[0] != queens[1]) and (queens[0] != queens[2]) and (queens[1] != queens[2]) and coverenough(queens):
- candidates.add(tuple(canonicalize(queens)))
- squaresfromoutside = sorted(product(range(8),range(8)),key=centrality)
- theremightbeasolution = False
- for queens in candidates:
- notcoveredbyqueens = [sq for sq in squaresfromoutside if not iscoveredby(sq,queens)]
- if len(notcoveredbyqueens) == 0:
- theremightbeasolution = True
- break
- for knight0 in coveredbyknightat(notcoveredbyqueens[0]):
- firstnotcovered = [sq for sq in notcoveredbyqueens if sq not in coveredbyknightat(knight0)]
- if len(firstnotcovered) == 0:
- theremightbeasolution = True
- break
- for knight1 in coveredbyknightat(firstnotcovered[0]):
- secondnotcovered = [sq for sq in firstnotcovered if sq not in coveredbyknightat(knight1)]
- if len(secondnotcovered) == 0:
- theremightbeasolution = True
- break
- for knight2 in coveredbyknightat(secondnotcovered[0]):
- thirdnotcovered = [sq for sq in secondnotcovered if sq not in coveredbyknightat(knight2)]
- if len(thirdnotcovered) == 0 and actuallyworks(queens,(knight0,knight1,knight2)):
- theremightbeasolution = True
- print(theremightbeasolution)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement