N Queens¶
Problem¶
Place n queens on an n x n chessboard such that no two queens threaten each other (no shared row, column, or diagonal). Return all distinct solutions.
Approach¶
Backtracking row by row. Track occupied columns, positive diagonals (r + c), and negative diagonals (r - c) with sets. Only valid placements are explored.
When to Use¶
Constraint placement — "place N items with mutual exclusion constraints", "non-attacking queens", "conflict-free assignment". Row-by-row backtracking with column/diagonal conflict sets. See also: CSP solver.
Complexity¶
| Time | O(n!) (with pruning) |
| Space | O(n) |
Implementation¶
n_queens ¶
N-Queens — place n queens on n x n board with no attacks.
Problem
Place n queens on an n x n chessboard such that no two queens threaten each other (no shared row, column, or diagonal). Return all distinct solutions.
Approach
Backtracking row by row. Track occupied columns, positive diagonals (r + c), and negative diagonals (r - c) with sets. Only valid placements are explored.
When to use
Constraint placement — "place N items with mutual exclusion constraints", "non-attacking queens", "conflict-free assignment". Row-by-row backtracking with column/diagonal conflict sets. See also: CSP solver.
Complexity
Time: O(n!) (with pruning) Space: O(n)
solve_n_queens ¶
Return all solutions as lists of strings ('.' and 'Q').
len(solve_n_queens(4)) 2 solve_n_queens(1) [['Q']]
Source code in src/algo/backtracking/n_queens.py
"""Tests for N-Queens."""
from algo.backtracking.n_queens import solve_n_queens
class TestNQueens:
def test_one_queen(self) -> None:
assert solve_n_queens(1) == [["Q"]]
def test_four_queens(self) -> None:
result = solve_n_queens(4)
assert len(result) == 2
def test_eight_queens(self) -> None:
result = solve_n_queens(8)
assert len(result) == 92
def test_no_solution_for_two(self) -> None:
assert solve_n_queens(2) == []
def test_no_solution_for_three(self) -> None:
assert solve_n_queens(3) == []
def test_board_validity(self) -> None:
"""Check that no two queens attack each other in any 4-queens solution."""
for board in solve_n_queens(4):
queens = [(r, row.index("Q")) for r, row in enumerate(board)]
# No shared column
cols = [c for _, c in queens]
assert len(cols) == len(set(cols))
# No shared diagonal
for i in range(len(queens)):
for j in range(i + 1, len(queens)):
r1, c1 = queens[i]
r2, c2 = queens[j]
assert abs(r1 - r2) != abs(c1 - c2)
Implement it yourself
Run: just challenge backtracking n_queens
Then implement the functions to make all tests pass.
Use just study backtracking for watch mode.
Reveal Solution
n_queens ¶
N-Queens — place n queens on n x n board with no attacks.
Problem
Place n queens on an n x n chessboard such that no two queens threaten each other (no shared row, column, or diagonal). Return all distinct solutions.
Approach
Backtracking row by row. Track occupied columns, positive diagonals (r + c), and negative diagonals (r - c) with sets. Only valid placements are explored.
When to use
Constraint placement — "place N items with mutual exclusion constraints", "non-attacking queens", "conflict-free assignment". Row-by-row backtracking with column/diagonal conflict sets. See also: CSP solver.
Complexity
Time: O(n!) (with pruning) Space: O(n)
solve_n_queens ¶
Return all solutions as lists of strings ('.' and 'Q').
len(solve_n_queens(4)) 2 solve_n_queens(1) [['Q']]