I have written following code for solving the n-Queens problem where we have to find all possible legal (non-attacking) placements of n
queens in an n*n
chessboard. The code uses the standard backtracking solution.
Here the method n_queens
uses the helper method solve_n_queens
which uses recursion. The outer method just initializes global lists result
& col_placement
and calls the helper method.
def n_queens(n):
def solve_n_queens(row):
if row == n: # all queens are legally placed
result.append(list(col_placement))
return
for col in range(n):
# check if new queen is either 1) in same column or 2) same diagonal with any previously placed queen
if all(abs(col-c) not in (0, row-r)
for r, c in enumerate(col_placement[:row])):
col_placement[row] = col
solve_n_queens(row+1)
result, col_placement = [], [0] * n # result is empty initially; [0] * n means no queen is placed
solve_n_queens(0)
return result
This gives erroneous output for n_queens(4)
[[3, 1, 2, 1], [3, 1, 2, 1]]
However it is not an algorithmic bug because just altering the 4th line result.append(col_placement)
to result.append(list(col_placement))
mysteriously gives the correct output
[[1, 3, 0, 2], [2, 0, 3, 1]]
What I don't grok is when col_placement
is already a list
, why do we need to call the list
method?