TransWikia.com

Place three Knights, three Bishops and three Rooks on this board snippet

Puzzling Asked by Tweakimp on May 14, 2021

The board

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).

3 Answers

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP