Constraint puzzles (N-Queens, Sudoku)
In one line
Constraint puzzles fill a board one cell or row at a time, check the rules before each placement using fast lookup sets, and backtrack the moment a rule would be broken.
What it is
A constraint puzzle asks you to fill positions so that every rule holds. In N-Queens you place n queens on an n x n board so that no two share a row, column or diagonal. In Sudoku you fill a 9 x 9 grid so each row, column and 3 x 3 box contains 1 to 9 exactly once.
Backtracking solves both: place one piece, check that the rules still hold, recurse to the next position, and undo if no option works further down. The art is checking rules in O(1) with sets or arrays instead of rescanning the board.
Real solvers add two ideas on top: constraint propagation (after a placement, remove options that are now impossible elsewhere) and ordering heuristics (fill the most constrained cell first).
Why interviewers ask
These are classic hard backtracking questions. They test whether you can model the state cleanly, encode diagonals and boxes with simple arithmetic, keep several sets in sync when undoing, and reason about why the search is fast enough in practice despite a huge worst case.
How it works
- 1N-Queens: there is exactly one queen per row, so recurse row by row and choose a column for each.
- 2Keep three sets: used columns, used diagonals keyed by row - col, and used anti-diagonals keyed by row + col. Cells on the same diagonal share row - col; cells on the same anti-diagonal share row + col.
- 3A column c in row r is safe if c, r - c and r + c are all unused. Place, add to all three sets, recurse to r + 1, then remove from all three.
- 4Sudoku: keep a set for each row, column and box, with box index (r // 3) * 3 + c // 3. Fill empty cells one by one with digits that are in none of the three sets.
- 5For Sudoku you only need one solution, so return True as soon as the board is full and stop searching.
- 6Speed-up: choose the empty cell with the fewest legal digits next (minimum remaining values). This makes most real puzzles solve with very little backtracking.
Worked example · Solving 4-Queens by hand
- Row 0: try column 0. Row 1: col 0 shares the column, col 1 shares the diagonal (1 - 1 = 0 = 0 - 0), col 2 is safe: place (1, 2).
- Row 2: col 0 column used, col 1 anti-diagonal 3 is used by (1, 2), col 2 column used, col 3 diagonal -1 is used by (1, 2). Dead end: undo (1, 2).
- Row 1: try col 3. Row 2: col 1 is safe: place (2, 1). Row 3: cols 0, 1, 3 are used, col 2 shares diagonal 1 with (2, 1). Dead end: undo back to row 0.
- Row 0: try column 1. Row 1: col 3 is the only safe column. Row 2: col 0 is safe. Row 3: col 2 is safe.
- Board full: record [1, 3, 0, 2] (queen column per row). Continuing the search also finds the mirror [2, 0, 3, 1]. 4-Queens has exactly 2 solutions; 8-Queens has 92.
Picture it
Like filling in a seating plan where some guests cannot sit near each other. You seat people table by table, check the rules each time, and the moment someone has no acceptable seat you go back and move the last person you placed.
Reference code
def solve_n_queens(n):
solutions, queens = [], [] # queens[r] = column in row r
cols, diag, anti = set(), set(), set()
def place(row):
if row == n:
solutions.append(queens[:])
return
for c in range(n):
if c in cols or row - c in diag or row + c in anti:
continue # attacked: prune this branch
queens.append(c)
cols.add(c); diag.add(row - c); anti.add(row + c)
place(row + 1)
queens.pop()
cols.remove(c); diag.remove(row - c); anti.remove(row + c)
place(0)
return solutions
print(solve_n_queens(4)) # [[1, 3, 0, 2], [2, 0, 3, 1]]Three sets make each safety check O(1). Every placement adds to all three sets and every undo removes from all three, so the state is always consistent. Each solution lists the queen's column for rows 0 to n - 1.
Key patterns
Row-by-row placement
When: Exactly one piece per row (N-Queens)
How: Recurse on the row index; only the column is a choice, which removes row conflicts by construction.
Diagonal keys
When: Checking diagonals on a grid
How: Same diagonal means same row - col; same anti-diagonal means same row + col. Store them in sets or arrays of size 2n - 1.
Find one and stop
When: Sudoku, any single valid assignment
How: Make the recursive function return a boolean and return True up the stack as soon as the goal is reached.
Most constrained first
When: Many cells or variables to fill
How: Pick the cell with the fewest legal values next; a cell with zero values is an instant dead end.
Bitmask state
When: You need N-Queens counts fast
How: Represent columns and diagonals as integers and get all free positions with one bitwise expression.
Real-world use
Sudoku and puzzle apps
Puzzle apps solve and validate Sudoku with backtracking plus constraint propagation, and generate puzzles by removing digits while checking that the solution stays unique.
Constraint programming solvers
Google OR-Tools CP-SAT and MiniZinc solvers handle timetables, shift rosters and job-shop schedules with search plus propagation, the industrial version of the same idea.
Register allocation and map colouring
Compilers assign variables to a small number of CPU registers so that variables live at the same time get different registers, which is a graph colouring constraint problem; small instances are solved by backtracking, large ones heuristically.
Exact cover (Dancing Links)
Knuth's Algorithm X with Dancing Links solves exact cover problems such as Sudoku, pentomino tiling and N-Queens by backtracking on a sparse matrix with O(1) undo.
In a project
A hospital ward needs a weekly nurse rota: 20 nurses, 21 shifts, minimum staffing per shift, no nurse on two consecutive shifts, and a maximum of 5 shifts per nurse.
- Model each shift slot as a variable whose value is a nurse, and keep per-nurse counters and last-shift markers as sets for O(1) checks.
- Fill the most constrained slot first (fewest available nurses), as in the minimum-remaining-values heuristic for Sudoku.
- Before each assignment, check the consecutive-shift and maximum-shift rules; after it, update counters and undo them on backtrack.
- Stop at the first valid rota, then let a manager swap shifts; if the search grows too large, move the model to a constraint solver like OR-Tools.
Impact: A rota that took a manager hours each week is generated in seconds, always respects the legal rest rules, and makes understaffed shifts visible immediately when no solution exists.
Trade-offs
Use it when
- The puzzle has hard rules that can be checked on partial boards
- Boards are small (N-Queens up to about 12 to 14 for listing, standard 9 x 9 Sudoku)
- You need one valid solution or all solutions for a small instance
Avoid it when
- The problem is large and industrial: use a constraint or SAT solver
- An explicit construction exists (one N-Queens solution for any n >= 4 can be built directly in O(n))
- Soft goals dominate (minimise cost), where integer programming or local search fits better
Cost: N-Queens with row-by-row placement explores at most O(n!) placements, and real counts are far smaller because of diagonal pruning; extra space is O(n). Sudoku worst case is 9^(number of empty cells), but with good checks typical puzzles finish in milliseconds.
Common mistakes
- Checking safety by scanning the whole board on every placement, turning O(1) checks into O(n^2).
- Using row + col for both diagonals, or forgetting that row - col can be negative when sizing an array (offset it by n - 1).
- Updating three sets on place but undoing only one or two of them.
- For Sudoku, not returning the boolean, so the search continues and undoes the finished board.
- Computing the box index wrongly; the correct formula is (r // 3) * 3 + c // 3.
Interview questions
Quick revision
- N-Queens: one queen per row; choose a column per row.
- Diagonal key: r - c. Anti-diagonal key: r + c.
- 4-Queens has 2 solutions, 8-Queens has 92.
- Sudoku box index: (r // 3) * 3 + c // 3.
- Need one answer: return True to stop early.
- Fill the most constrained cell first.
- Undo every set you updated.
Check yourself
1. Two cells (r1, c1) and (r2, c2) are on the same anti-diagonal when:
2. How many solutions does the 8-Queens puzzle have?
3. Which 3 x 3 box index does cell (4, 7) belong to, using (r // 3) * 3 + c // 3?
4. Why recurse row by row in N-Queens?
Saved on this device. Create a free account to keep it on every device.
Practise this with Sam
A real mock interview, out loud, with an honest scorecard. Free to start.