What six lines of Python can do
1 2 3 4 5 6 7 8
from itertools import permutations n = 8 cols = range(n) for vec in permutations(cols): if (n == len(set(vec[i]+i for i in cols)) == len(set(vec[i]-i for i in cols))): print vec
Solver for the eight queens puzzle:
Computes all 92 solutions for eight queens. By setting n to different values, other sized puzzles can be solved.
The output is presented in vector form (each number represents the column position of a queen on consecutive rows). The vector can be pretty printed with this function:
def board(vec): '''Translate column positions to an equivalent chess board. >>> board([0, 4, 7, 5, 2, 6, 1, 3]) Q------- ----Q--- -------Q -----Q-- --Q----- ------Q- -Q------ ---Q---- ''' for col in vec: s = ['-'] * len(vec) s[col] = 'Q' print ''.join(s) print
With the solution represented as a vector with one queen in each row, we don't have to check to see if two queens are on the same row. By using a permutation generator, we know that no value in the vector is repeated, so we don't have to check to see if two queens are on the same column. Since rook moves don't need to be checked, we only need to check bishop moves.
The technique for checking the diagonals is to add or subtract the column number from each entry, so any two entries on the same diagonal will have the same value (in other words, the sum or difference is unique for each diagnonal). Now all we have to do is make sure that the diagonals for each of the eight queens are distinct. So, we put them in a set (which eliminates duplicates) and check that the set length is eight (no duplicates were removed).
Any permutation with non-overlapping diagonals is a solution. So, we print it and continue checking other permutations.