Puzzling Asked by Tweakimp on May 14, 2021
Place three Knights, three Bishops and three Rooks on this board snippet.
The only rule: each piece has to be attacked exactly once.
Notes:
Ignore color, so every piece attacks every other piece whose square it can move to.
I don’t know how many solutions there are, but there is at least one (and its symmetric twins).
This seems to be a possible solution:
The knight on "c5" could also be moved to d2, and b4 could be on d5. Combined with symmetry (across both diagonals), that gives a total of 16 variations of this solution.
Correct answer by Doorknob on May 14, 2021
Here’s a solution using only the top three rows of the board
Answered by Bass on May 14, 2021
This is similar to the question Two Knights, two Bishops, two Rooks and two Kings on a 4x4 chessboard and I could heavily reuse the code I wrote for that one to answer the question how many solutions there are.
There are
I considered a 5x5 board with the squares named like this
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
and just excluded 0, 1, 5, 19, 23 and 24.
Each solution consists of 9 numbers, e.g., (2, 3, 4, 6, 18, 20, 14, 16, 17)
. The first three numbers correspond to the placement of the knights, the next three of the rooks and the last three of the bishops. There are too many unique solutions to provide a visual representation, so I'll just list the piece coordinates for each
(2, 3, 4, 6, 18, 20, 14, 16, 17)
(2, 3, 4, 8, 14, 22, 10, 17, 20)
(2, 3, 4, 8, 14, 22, 16, 20, 21)
(2, 3, 4, 9, 16, 22, 15, 18, 20)
(2, 3, 4, 10, 18, 21, 8, 9, 22)
(2, 3, 4, 11, 18, 20, 8, 9, 22)
(2, 3, 4, 14, 20, 22, 6, 7, 17)
(2, 3, 4, 14, 20, 22, 6, 15, 17)
(2, 3, 7, 4, 15, 20, 6, 13, 22)
(2, 3, 7, 4, 20, 22, 6, 15, 17)
(2, 3, 7, 8, 15, 20, 4, 6, 17)
(2, 3, 7, 8, 15, 20, 4, 6, 22)
(2, 3, 7, 8, 20, 22, 4, 6, 17)
(2, 3, 7, 13, 15, 17, 4, 6, 22)
(2, 3, 7, 13, 15, 17, 6, 20, 22)
(2, 3, 7, 13, 17, 20, 4, 6, 21)
(2, 3, 8, 9, 16, 22, 15, 18, 20)
(2, 3, 8, 14, 15, 22, 6, 7, 16)
(2, 3, 8, 14, 17, 20, 6, 7, 16)
(2, 3, 8, 14, 20, 22, 4, 6, 7)
(2, 3, 8, 17, 20, 21, 7, 10, 14)
(2, 3, 10, 4, 7, 15, 18, 20, 21)
(2, 3, 10, 9, 15, 21, 7, 8, 18)
(2, 3, 10, 9, 15, 22, 4, 11, 18)
(2, 3, 10, 9, 17, 20, 15, 16, 18)
(2, 3, 15, 4, 10, 18, 8, 17, 22)
(2, 3, 15, 4, 17, 20, 13, 16, 18)
(2, 3, 15, 8, 14, 16, 4, 10, 17)
(2, 3, 15, 9, 13, 20, 4, 10, 18)
(2, 3, 16, 14, 20, 22, 10, 15, 17)
(2, 3, 18, 4, 6, 20, 8, 13, 22)
(2, 3, 18, 4, 7, 10, 16, 17, 22)
(2, 3, 18, 4, 7, 10, 20, 21, 22)
(2, 3, 18, 6, 20, 22, 14, 15, 17)
(2, 3, 18, 8, 14, 16, 4, 10, 17)
(2, 3, 18, 8, 14, 22, 4, 10, 17)
(2, 3, 18, 8, 14, 22, 10, 17, 20)
(2, 3, 18, 10, 16, 20, 4, 7, 8)
(2, 3, 18, 14, 20, 22, 6, 7, 17)
(2, 3, 18, 14, 20, 22, 6, 15, 17)
(2, 3, 20, 7, 14, 18, 4, 15, 22)
(2, 3, 20, 8, 14, 21, 4, 10, 17)
(2, 3, 20, 9, 10, 17, 15, 16, 18)
(2, 3, 20, 9, 16, 22, 4, 15, 18)
(2, 3, 20, 9, 16, 22, 7, 8, 18)
(2, 3, 21, 9, 10, 22, 7, 8, 18)
(2, 3, 21, 9, 17, 20, 4, 11, 22)
(2, 3, 21, 10, 17, 22, 4, 7, 8)
(2, 3, 21, 14, 15, 22, 6, 7, 16)
(2, 3, 21, 14, 17, 22, 4, 6, 7)
(2, 3, 22, 9, 17, 20, 7, 8, 21)
(2, 3, 22, 10, 16, 20, 4, 8, 9)
(2, 3, 22, 14, 15, 18, 6, 16, 17)
(2, 3, 22, 14, 18, 20, 4, 6, 17)
(2, 3, 22, 14, 18, 20, 6, 16, 21)
(2, 4, 6, 10, 18, 21, 8, 9, 22)
(2, 4, 6, 11, 18, 20, 8, 9, 22)
(2, 4, 8, 3, 10, 21, 7, 17, 22)
(2, 4, 8, 6, 12, 14, 3, 10, 15)
(2, 4, 8, 9, 10, 16, 6, 7, 20)
(2, 4, 8, 9, 16, 22, 15, 18, 20)
(2, 4, 8, 9, 20, 21, 6, 7, 22)
(2, 4, 8, 14, 15, 22, 18, 20, 21)
(2, 4, 8, 14, 17, 20, 15, 16, 18)
(2, 4, 8, 14, 17, 21, 15, 18, 20)
(2, 4, 10, 8, 14, 22, 3, 18, 20)
(2, 4, 10, 14, 16, 22, 15, 18, 20)
(2, 4, 12, 3, 6, 15, 10, 17, 18)
(2, 4, 12, 3, 6, 15, 10, 17, 20)
(2, 4, 15, 6, 10, 18, 14, 16, 17)
(2, 4, 15, 10, 18, 21, 14, 16, 17)
(2, 4, 16, 3, 8, 15, 17, 18, 21)
(2, 4, 16, 3, 8, 22, 17, 18, 20)
(2, 4, 21, 8, 14, 20, 6, 16, 22)
(2, 4, 22, 3, 10, 20, 7, 18, 21)
(2, 4, 22, 6, 12, 14, 10, 15, 17)
(2, 6, 7, 3, 14, 20, 11, 12, 21)
(2, 6, 7, 4, 8, 21, 17, 20, 22)
(2, 6, 8, 4, 14, 22, 7, 10, 20)
(2, 6, 8, 10, 12, 16, 3, 14, 20)
(2, 6, 8, 10, 12, 16, 9, 14, 20)
(2, 6, 8, 10, 12, 16, 14, 20, 21)
(2, 6, 10, 4, 18, 21, 7, 20, 22)
(2, 6, 12, 4, 14, 18, 10, 11, 22)
(2, 6, 12, 4, 14, 18, 10, 21, 22)
(2, 6, 16, 3, 10, 20, 4, 17, 18)
(2, 6, 16, 3, 10, 20, 4, 18, 21)
(2, 6, 16, 4, 10, 20, 7, 12, 17)
(2, 6, 16, 4, 10, 20, 7, 12, 21)
(2, 6, 18, 4, 8, 14, 15, 16, 20)
(2, 6, 18, 4, 8, 14, 16, 17, 20)
(2, 6, 18, 4, 8, 14, 16, 20, 21)
(2, 6, 18, 10, 16, 20, 3, 4, 8)
(2, 6, 18, 10, 16, 20, 4, 7, 8)
(2, 6, 20, 10, 12, 16, 3, 21, 22)
(2, 6, 20, 12, 16, 21, 4, 7, 8)
(2, 6, 21, 4, 8, 14, 15, 16, 20)
(2, 6, 21, 4, 8, 14, 16, 17, 20)
(2, 6, 21, 4, 10, 22, 7, 18, 20)
(2, 6, 21, 7, 14, 20, 3, 4, 22)
(2, 6, 21, 9, 10, 22, 7, 8, 18)
(2, 6, 22, 4, 8, 14, 16, 17, 20)
(2, 6, 22, 10, 12, 16, 3, 20, 21)
(2, 6, 22, 10, 16, 20, 3, 4, 8)
(2, 6, 22, 10, 16, 20, 4, 8, 9)
(2, 6, 22, 12, 16, 18, 7, 8, 9)
(2, 6, 22, 12, 16, 18, 7, 8, 21)
(2, 7, 8, 4, 6, 10, 17, 18, 20)
(2, 7, 8, 4, 6, 10, 18, 20, 21)
(2, 7, 8, 4, 10, 21, 15, 18, 20)
(2, 7, 8, 4, 10, 22, 18, 20, 21)
(2, 7, 8, 16, 20, 22, 4, 6, 9)
(2, 7, 12, 3, 6, 22, 10, 17, 20)
(2, 7, 12, 4, 6, 22, 10, 17, 20)
(2, 7, 12, 8, 15, 21, 4, 6, 22)
(2, 7, 15, 4, 20, 21, 3, 10, 18)
(2, 7, 21, 11, 15, 17, 4, 6, 22)
(2, 7, 21, 11, 15, 17, 6, 20, 22)
(2, 7, 22, 4, 15, 21, 3, 6, 17)
(2, 7, 22, 8, 15, 21, 4, 6, 17)
(2, 8, 10, 6, 12, 16, 9, 15, 18)
(2, 8, 10, 14, 16, 22, 4, 18, 20)
(2, 8, 14, 6, 15, 22, 3, 13, 18)
(2, 8, 15, 3, 6, 14, 7, 17, 22)
(2, 8, 15, 4, 6, 14, 7, 16, 17)
(2, 8, 16, 3, 10, 14, 7, 17, 20)
(2, 8, 16, 3, 10, 20, 7, 17, 22)
(2, 8, 16, 9, 10, 21, 6, 15, 18)
(2, 8, 16, 9, 20, 21, 6, 7, 18)
(2, 8, 16, 12, 14, 21, 3, 4, 15)
(2, 8, 16, 14, 15, 20, 4, 6, 18)
(2, 8, 16, 14, 20, 21, 4, 6, 18)
(2, 8, 18, 4, 14, 20, 3, 10, 12)
(2, 8, 18, 4, 14, 20, 7, 12, 17)
(2, 8, 18, 4, 14, 20, 12, 15, 17)
(2, 8, 18, 4, 14, 21, 3, 6, 20)
(2, 8, 18, 4, 14, 21, 7, 20, 22)
(2, 8, 20, 3, 6, 10, 7, 18, 22)
(2, 8, 20, 3, 14, 21, 7, 15, 22)
(2, 8, 20, 4, 6, 14, 7, 12, 21)
(2, 8, 20, 12, 14, 21, 3, 4, 15)
(2, 8, 20, 12, 16, 21, 6, 7, 14)
(2, 8, 20, 14, 15, 22, 4, 18, 21)
(2, 8, 21, 4, 14, 22, 3, 16, 20)
(2, 8, 21, 4, 14, 22, 7, 16, 20)
(2, 8, 22, 4, 6, 14, 10, 15, 17)
(2, 8, 22, 12, 14, 16, 4, 7, 10)
(2, 8, 22, 12, 16, 18, 6, 7, 9)
(2, 8, 22, 12, 16, 18, 6, 7, 21)
(2, 8, 22, 18, 20, 21, 3, 6, 7)
(2, 10, 14, 6, 15, 22, 3, 13, 18)
(2, 10, 14, 12, 16, 22, 9, 15, 20)
(2, 12, 18, 3, 6, 15, 4, 10, 17)
(2, 12, 18, 3, 6, 15, 10, 17, 20)
(2, 12, 18, 4, 6, 14, 10, 15, 22)
(2, 12, 18, 16, 20, 22, 3, 10, 13)
(2, 14, 20, 6, 8, 12, 15, 16, 21)
(2, 15, 16, 3, 8, 14, 17, 21, 22)
(2, 15, 16, 4, 14, 18, 7, 17, 22)
(2, 15, 16, 4, 14, 22, 3, 10, 17)
(2, 15, 16, 4, 14, 22, 7, 17, 20)
(2, 15, 16, 8, 12, 21, 3, 14, 17)
(2, 15, 18, 4, 8, 14, 16, 20, 21)
(2, 15, 18, 4, 14, 22, 3, 6, 17)
(2, 15, 20, 4, 14, 21, 3, 10, 17)
(2, 15, 21, 4, 6, 18, 7, 16, 17)
(2, 15, 21, 7, 11, 18, 3, 4, 20)
(2, 15, 21, 7, 13, 20, 3, 4, 16)
(2, 16, 17, 3, 10, 22, 4, 7, 18)
(2, 16, 17, 3, 10, 22, 4, 15, 18)
(2, 16, 17, 3, 14, 20, 7, 12, 21)
(2, 16, 17, 9, 12, 20, 4, 15, 22)
(2, 16, 17, 14, 18, 20, 3, 4, 6)
(2, 16, 17, 14, 18, 20, 4, 6, 7)
(2, 16, 17, 14, 18, 20, 4, 6, 15)
(2, 16, 18, 3, 20, 22, 4, 15, 17)
(2, 16, 20, 3, 14, 15, 7, 17, 18)
(2, 16, 20, 3, 14, 21, 7, 17, 18)
(2, 16, 20, 8, 10, 21, 6, 14, 15)
(2, 16, 21, 4, 10, 18, 3, 8, 17)
(2, 16, 21, 8, 10, 22, 3, 14, 20)
(2, 16, 21, 8, 12, 15, 3, 14, 17)
(2, 17, 18, 4, 15, 21, 3, 8, 22)
(2, 17, 18, 4, 15, 22, 3, 6, 16)
(2, 17, 18, 14, 15, 22, 6, 7, 16)
(2, 17, 21, 4, 7, 11, 3, 18, 20)
(2, 17, 21, 4, 15, 22, 3, 6, 16)
(2, 17, 21, 9, 15, 22, 6, 7, 16)
(2, 17, 21, 13, 15, 22, 3, 6, 16)
(2, 18, 20, 6, 8, 12, 3, 16, 21)
(2, 20, 21, 9, 13, 17, 4, 15, 22)
(3, 4, 8, 9, 10, 21, 7, 17, 22)
(3, 4, 8, 9, 15, 22, 10, 11, 13)
(3, 4, 8, 9, 15, 22, 11, 13, 18)
(3, 4, 8, 9, 20, 22, 6, 11, 13)
(3, 4, 8, 9, 20, 22, 6, 13, 15)
(3, 4, 8, 14, 17, 20, 6, 15, 16)
(3, 4, 8, 14, 17, 21, 10, 15, 20)
(3, 4, 9, 2, 10, 11, 18, 20, 21)
(3, 4, 9, 2, 10, 21, 16, 17, 18)
(3, 4, 9, 2, 11, 20, 16, 17, 18)
(3, 4, 9, 6, 17, 20, 11, 14, 16)
(3, 4, 11, 2, 9, 20, 13, 15, 18)
(3, 4, 11, 2, 10, 21, 13, 16, 18)
(3, 4, 11, 7, 10, 21, 9, 14, 16)
(3, 4, 11, 7, 10, 21, 9, 16, 18)
(3, 4, 15, 7, 10, 21, 2, 9, 20)
(3, 4, 16, 14, 20, 22, 10, 15, 17)
(3, 4, 18, 2, 6, 20, 8, 17, 22)
(3, 4, 18, 2, 6, 20, 13, 14, 16)
(3, 4, 18, 2, 6, 20, 14, 16, 17)
(3, 4, 18, 8, 14, 22, 10, 17, 20)
(3, 4, 18, 14, 20, 22, 6, 15, 17)
(3, 4, 20, 2, 11, 18, 8, 21, 22)
(3, 4, 21, 6, 15, 22, 11, 14, 20)
(3, 4, 21, 6, 17, 20, 8, 11, 22)
(3, 4, 21, 6, 17, 20, 11, 14, 16)
(3, 4, 21, 13, 17, 20, 6, 8, 11)
(3, 4, 21, 13, 17, 20, 8, 11, 22)
(3, 4, 21, 14, 17, 20, 6, 9, 16)
(3, 7, 8, 2, 9, 21, 10, 17, 18)
(3, 7, 8, 2, 15, 20, 4, 6, 22)
(3, 7, 8, 4, 10, 21, 15, 18, 20)
(3, 7, 8, 4, 10, 22, 18, 20, 21)
(3, 7, 8, 4, 18, 21, 10, 13, 20)
(3, 7, 9, 4, 20, 21, 2, 11, 22)
(3, 7, 9, 4, 20, 21, 6, 11, 22)
(3, 7, 9, 8, 15, 20, 4, 6, 22)
(3, 7, 11, 13, 15, 22, 2, 4, 21)
(3, 7, 11, 13, 15, 22, 4, 6, 21)
(3, 7, 17, 4, 11, 20, 13, 15, 18)
(3, 7, 17, 4, 11, 20, 13, 15, 22)
(3, 7, 20, 2, 9, 11, 8, 18, 21)
(3, 8, 9, 2, 10, 21, 13, 16, 18)
(3, 8, 9, 2, 11, 15, 20, 21, 22)
(3, 8, 9, 2, 11, 20, 13, 16, 18)
(3, 8, 9, 2, 11, 20, 16, 18, 21)
(3, 8, 13, 17, 20, 21, 2, 7, 18)
(3, 8, 13, 17, 20, 21, 4, 7, 10)
(3, 8, 13, 17, 20, 21, 4, 7, 18)
(3, 8, 13, 17, 20, 21, 7, 10, 14)
(3, 8, 15, 2, 14, 20, 10, 13, 16)
(3, 8, 15, 14, 16, 22, 2, 9, 20)
(3, 8, 16, 2, 15, 20, 6, 13, 14)
(3, 8, 16, 9, 10, 20, 7, 17, 22)
(3, 8, 16, 9, 10, 21, 6, 7, 17)
(3, 8, 16, 9, 20, 22, 10, 11, 13)
(3, 8, 16, 14, 20, 21, 4, 6, 7)
(3, 8, 16, 14, 20, 22, 4, 10, 15)
(3, 8, 18, 2, 14, 15, 6, 16, 21)
(3, 8, 18, 14, 20, 22, 4, 6, 15)
(3, 8, 20, 2, 9, 15, 6, 13, 21)
(3, 8, 20, 2, 9, 15, 10, 13, 21)
(3, 8, 20, 7, 15, 16, 9, 13, 18)
(3, 8, 21, 14, 15, 22, 6, 7, 16)
(3, 8, 21, 14, 17, 20, 6, 7, 16)
(3, 9, 15, 2, 10, 11, 4, 13, 20)
(3, 9, 15, 2, 10, 21, 13, 16, 18)
(3, 9, 15, 2, 10, 21, 16, 17, 18)
(3, 9, 15, 2, 11, 20, 16, 17, 18)
(3, 9, 15, 4, 10, 11, 8, 18, 20)
(3, 9, 15, 10, 18, 21, 2, 17, 20)
(3, 9, 15, 11, 18, 20, 2, 16, 17)
(3, 9, 16, 6, 20, 22, 8, 11, 13)
(3, 9, 20, 4, 7, 10, 8, 15, 22)
(3, 11, 16, 2, 9, 20, 4, 13, 15)
(3, 11, 16, 2, 9, 20, 4, 17, 18)
(3, 11, 16, 4, 10, 22, 6, 8, 13)
(3, 11, 16, 4, 10, 22, 6, 8, 21)
(3, 11, 16, 9, 18, 20, 2, 4, 17)
(3, 11, 21, 4, 7, 17, 10, 15, 20)
(3, 13, 18, 9, 15, 21, 7, 8, 10)
(3, 13, 18, 15, 17, 21, 4, 9, 10)
(3, 15, 18, 2, 11, 20, 13, 14, 16)
(3, 15, 18, 4, 11, 17, 8, 13, 20)
(3, 15, 18, 8, 14, 16, 4, 10, 17)
(3, 16, 17, 4, 9, 20, 18, 21, 22)
(3, 16, 18, 6, 20, 22, 13, 14, 15)
(3, 16, 18, 6, 20, 22, 14, 15, 17)
(3, 16, 18, 9, 20, 22, 6, 8, 11)
(3, 16, 18, 9, 20, 22, 6, 8, 15)
(3, 16, 18, 14, 20, 22, 4, 6, 15)
(3, 16, 20, 8, 15, 22, 2, 18, 21)
(3, 17, 18, 9, 12, 20, 2, 15, 22)
(3, 18, 20, 4, 10, 16, 2, 8, 13)
(4, 6, 12, 9, 10, 18, 11, 14, 16)
(4, 6, 12, 9, 10, 21, 11, 14, 16)
(4, 6, 12, 9, 16, 22, 11, 14, 20)
(4, 6, 12, 9, 18, 21, 11, 14, 20)
(4, 6, 12, 9, 18, 21, 11, 20, 22)
(4, 6, 16, 2, 10, 11, 9, 14, 21)
(4, 6, 16, 3, 10, 20, 2, 17, 22)
(4, 8, 16, 2, 9, 15, 3, 6, 18)
(4, 8, 16, 2, 12, 15, 9, 14, 21)
(4, 8, 16, 3, 10, 12, 9, 20, 21)
(4, 8, 16, 3, 10, 12, 9, 21, 22)
(4, 8, 16, 3, 10, 21, 6, 15, 18)
(4, 8, 16, 3, 15, 22, 6, 11, 18)
(4, 8, 16, 3, 20, 21, 6, 11, 18)
(4, 8, 16, 3, 20, 22, 6, 10, 15)
(4, 8, 20, 2, 9, 10, 3, 6, 18)
(4, 8, 20, 2, 9, 15, 3, 10, 18)
(4, 8, 20, 2, 10, 21, 6, 14, 15)
(4, 8, 20, 2, 12, 15, 9, 14, 21)
(4, 8, 20, 3, 10, 22, 6, 15, 18)
(4, 8, 20, 3, 12, 15, 9, 18, 21)
(4, 11, 16, 8, 14, 20, 6, 21, 22)
(4, 11, 16, 9, 12, 20, 10, 18, 21)
(4, 12, 16, 3, 6, 22, 2, 17, 18)
(4, 12, 16, 3, 15, 22, 2, 17, 18)
(6, 7, 8, 4, 10, 22, 18, 20, 21)
(6, 7, 8, 4, 12, 15, 2, 9, 20)
(6, 7, 8, 4, 12, 15, 2, 20, 22)
(6, 7, 8, 4, 12, 20, 2, 9, 16)
(6, 7, 8, 4, 12, 20, 2, 16, 21)
(6, 7, 12, 4, 8, 20, 2, 16, 17)
(6, 7, 12, 4, 10, 18, 2, 11, 20)
(6, 7, 12, 4, 13, 21, 2, 11, 22)
(6, 7, 12, 4, 18, 21, 2, 11, 20)
(6, 7, 12, 4, 18, 21, 10, 11, 20)
(6, 8, 12, 2, 4, 18, 10, 11, 22)
(6, 8, 12, 2, 4, 18, 10, 21, 22)
(6, 8, 12, 2, 4, 21, 7, 14, 20)
(6, 8, 12, 4, 14, 18, 10, 11, 22)
(6, 8, 12, 4, 14, 18, 10, 21, 22)
(6, 8, 16, 2, 4, 15, 9, 14, 18)
(6, 8, 16, 2, 4, 21, 9, 14, 18)
(6, 8, 18, 2, 4, 15, 10, 13, 20)
(6, 8, 18, 2, 16, 22, 4, 9, 20)
(6, 8, 18, 2, 16, 22, 4, 13, 20)
(7, 8, 13, 2, 11, 15, 12, 21, 22)
(7, 11, 12, 3, 6, 17, 10, 14, 21)
(7, 11, 12, 3, 17, 21, 10, 13, 14)
(7, 12, 13, 3, 6, 15, 8, 17, 22)
(7, 12, 13, 3, 17, 21, 10, 11, 14)
(7, 12, 13, 3, 18, 21, 8, 10, 11)
I used various shortcuts to cut down the time, but it's a big board, with quite a few pieces and not that restricting conditions, so the code still takes 5 minutes to run.
from collections import defaultdict
import itertools as it
SIZE = 5
SQUARES = [s for s in range(SIZE**2) if s not in (0, 1, 5, 19, 23, 24)]
def flatten(rank, file):
return rank * SIZE + file
def is_in_bounds(square):
return 0 <= square < SIZE
def square_exists(rank, file):
return (is_in_bounds(rank) and
is_in_bounds(file) and
flatten(rank, file) in SQUARES)
def rook_moves(rank, file):
moves = [[flatten(r, file) for r in range(rank-1, -1, -1) if square_exists(r, file)]]
moves += [[flatten(r, file) for r in range(rank+1, SIZE) if square_exists(r, file)]]
moves += [[flatten(rank, f) for f in range(file-1, -1, -1) if square_exists(rank, f)]]
moves += [[flatten(rank, f) for f in range(file+1, SIZE) if square_exists(rank, f)]]
return moves
def bishop_moves(rank, file):
down = range(-1, -rank-1, -1)
up = range(1, SIZE-rank)
moves = [[flatten(rank+i, file-i) for i in down if square_exists(rank+i, file-i)]]
moves += [[flatten(rank+i, file+i) for i in down if square_exists(rank+i, file+i)]]
moves += [[flatten(rank+i, file-i) for i in up if square_exists(rank+i, file-i)]]
moves += [[flatten(rank+i, file+i) for i in up if square_exists(rank+i, file+i)]]
return moves
def knight_moves(rank, file):
offsets = ((-2, -1), (-2, 1),
(-1, -2), (-1, 2),
(1, -2), (1, 2),
(2, -1), (2, 1))
moves = [flatten(rank+x, file+y) for x, y in offsets
if square_exists(rank+x, file+y)]
return moves
def filter_ray_moves(moves, occupied):
filtered_moves = []
for direction in moves:
for square in direction:
if square not in occupied:
filtered_moves.append(square)
else:
filtered_moves.append(square)
break
return filtered_moves
def solve(piece_moves_from, rook_adjacent_to):
solutions = []
attack_rule = [1] * 9
for n1, n2, n3 in it.combinations(SQUARES, 3):
knight_attacks = (piece_moves_from['N'][n1] +
piece_moves_from['N'][n2] +
piece_moves_from['N'][n3])
# if two knights gang up on the other, skip
if any(knight_attacks.count(knight) for knight in (n1, n2, n3)):
continue
attack_counter = defaultdict(int)
for coord in (n1, n2, n3):
for square in piece_moves_from['N'][coord]:
attack_counter[square] += 1
rook_allowed = [s for s in SQUARES
if s not in (n1, n2, n3) and knight_attacks.count(s) < 2]
for r1, r2, r3 in it.combinations(rook_allowed, 3):
# We can't know all the squares a rook can attack until all
# pieces are on the board. However, the four adjacent squares
# are guaranteed to be attacked, so we can use those find
# pieces under double attack and other double attacked squares
# we can exclude when placing the bishops.
rook_attacks = (rook_adjacent_to[r1] +
rook_adjacent_to[r2] +
rook_adjacent_to[r3])
for piece in (n1, n2, n3, r1, r2, r3):
if attack_counter[piece] + rook_attacks.count(piece) > 1:
continue
forbidden = [s for s in rook_allowed
if attack_counter[s] + rook_attacks.count(s) > 1]
forbidden += [r1, r2, r3]
bishop_allowed = [s for s in rook_allowed if s not in forbidden]
for b1, b2, b3 in it.combinations(bishop_allowed, 3):
piece_coords = (n1, n2, n3, r1, r2, r3, b1, b2, b3)
counter = attack_counter.copy()
for coord in (r1, r2, r3):
for square in filter_ray_moves(
piece_moves_from['R'][coord], piece_coords):
counter[square] += 1
for coord in (b1, b2, b3):
for square in filter_ray_moves(
piece_moves_from['B'][coord], piece_coords):
counter[square] += 1
attacks = [counter[piece] for piece in piece_coords]
if attacks == attack_rule:
solutions.append(piece_coords)
return solutions
piece_moves = {'N': knight_moves,
'R': rook_moves,
'B': bishop_moves,
}
piece_moves_from = {}
for piece, moves in piece_moves.items():
piece_moves_from[piece] = {}
for rank in range(SIZE):
for file in range(SIZE):
square = flatten(rank, file)
if square in SQUARES:
piece_moves_from[piece][square] = moves(rank, file)
rook_adjacent_to = {}
for square in SQUARES:
rank = square // SIZE
file = square % SIZE
adjacent = []
for f in (file-1, file+1):
if square_exists(rank, f):
adjacent.append(flatten(rank, f))
for r in (rank-1, rank+1):
if square_exists(r, file):
adjacent.append(flatten(r, file))
rook_adjacent_to[square] = adjacent
solutions = solve(piece_moves_from, rook_adjacent_to)
Answered by Reti43 on May 14, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP