Quick Overview

A coding problem that checks a partially filled 9x9 Sudoku board and completes it when possible. Solutions must detect givens that already break the row, column or box rules, recognize boards with no valid completion, and return a canonical completed grid, testing constraint checking and search.

Validate and Complete a Partially Filled 9x9 Sudoku Board

Company: Confluent

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

A 9 × 9 Sudoku board is partially filled with digits. Check whether the given digits are consistent with the rules of Sudoku and, if the board can be completed, return a completed board. ### Function Signature ```python def complete_sudoku(board: list[str]) -> list[str]: ``` `board[r][c]` is the cell in row `r` and column `c`, both 0-indexed: a digit `'1'` to `'9'`, or `'.'` for an empty cell. ### Rules - A completed board is valid when every row, every column and each of the nine 3 × 3 boxes contains each digit from 1 to 9 exactly once. The boxes are formed by grouping rows 0–2, 3–5 and 6–8 with columns 0–2, 3–5 and 6–8. - A completion keeps every given digit unchanged and fills every empty cell with a digit. - If the given digits already break the rules, meaning that some digit appears twice in one row, one column or one box, return `[]`. - If the given digits do not break the rules but no valid completion exists, return `[]`. - Otherwise return a valid completion as a list of 9 strings of 9 digits each. If more than one valid completion exists, return the one whose 81 digits, read row by row from top to bottom and left to right within each row, form the smallest string. Equivalently, at the first cell where two completions differ, prefer the one with the smaller digit. - A board with no empty cells is returned unchanged if it is valid, and `[]` otherwise. ### Constraints - `len(board) == 9`, and `len(board[r]) == 9` for every row `r`. - Every character is one of `'1'` to `'9'` or `'.'`. - Any number of cells, from 0 to 81, may be empty. ### Examples **Example 1** ```text Input: board = ["1.3456789", "456.89123", "789123456", "2345.7891", "56789.2.4", "89123456.", "3456789.2", "678912345", ".12345678"] Output: ["123456789", "456789123", "789123456", "234567891", "567891234", "891234567", "345678912", "678912345", "912345678"] ``` Rows 0, 1, 3, 5, 6 and 8 each miss exactly one digit, which fixes their empty cell. Row 4 misses 1 and 3, in columns 5 and 7; column 5 already holds a 3 in row 2, so row 4 gets 1 in column 5 and 3 in column 7. The completion is unique. **Example 2** ```text Input: board = ["3........", ".3.......", ".........", ".........", ".........", ".........", ".........", ".........", "........."] Output: [] ``` The two 3s are in different rows and different columns, but both lie in the top-left box. **Example 3** ```text Input: board = ["12345678.", ".........", ".........", ".........", "........9", ".........", ".........", ".........", "........."] Output: [] ``` No digit repeats in any row, column or box. However, the only digit missing from row 0 is 9, and column 8 already contains a 9 in row 4, so the cell in row 0, column 8 cannot be filled.

Overview: A coding problem that checks a partially filled 9x9 Sudoku board and completes it when possible. Solutions must detect givens that already break the row, column or box rules, recognize boards with no valid completion, and return a canonical completed grid, testing constraint checking and search.

Read the full Confluent Software Engineer interview experience this question came from

A 9 x 9 Sudoku board is partially filled with digits. Check whether the given digits are consistent with the rules of Sudoku and, if the board can be completed, return a completed board. Implement `complete_sudoku(board)`. `board` is a list of 9 strings. `board[r][c]` is the cell in row `r` and column `c`, both 0-indexed: a digit `'1'` to `'9'`, or `'.'` for an empty cell. Return a list of strings. ### Rules - A completed board is valid when every row, every column and each of the nine 3 x 3 boxes contains each digit from 1 to 9 exactly once. The boxes are formed by grouping rows 0-2, 3-5 and 6-8 with columns 0-2, 3-5 and 6-8. - A completion keeps every given digit unchanged and fills every empty cell with a digit. - If the given digits already break the rules, meaning that some digit appears twice in one row, one column or one box, return `[]`. - If the given digits do not break the rules but no valid completion exists, return `[]`. - Otherwise return a valid completion as a list of 9 strings of 9 digits each. If more than one valid completion exists, return the one whose 81 digits, read row by row from top to bottom and left to right within each row, form the smallest string. Equivalently, at the first cell where two completions differ, prefer the one with the smaller digit. - A board with no empty cells is returned unchanged if it is valid, and `[]` otherwise. ### Example 1 ```text Input: board = ['1.3456789', '456.89123', '789123456', '2345.7891', '56789.2.4', '89123456.', '3456789.2', '678912345', '.12345678'] Output: ['123456789', '456789123', '789123456', '234567891', '567891234', '891234567', '345678912', '678912345', '912345678'] ``` Rows 0, 1, 3, 5, 6 and 8 each miss exactly one digit, which fixes their empty cell. Row 4 misses 1 and 3, in columns 5 and 7; column 5 already holds a 3 in row 2, so row 4 gets 1 in column 5 and 3 in column 7. The completion is unique. ### Example 2 ```text Input: board = ['12345678.', '.........', '.........', '.........', '........9', '.........', '.........', '.........', '.........'] Output: [] ``` No digit repeats in any row, column or box. However, the only digit missing from row 0 is 9, and column 8 already contains a 9 in row 4, so the cell in row 0, column 8 cannot be filled. ### Constraints - `len(board) == 9`, and `len(board[r]) == 9` for every row `r`. - Every character is one of `'1'` to `'9'` or `'.'`. - Any number of cells, from 0 to 81, may be empty.

Constraints

  • len(board) == 9, and len(board[r]) == 9 for every row r.
  • Every character is one of '1' to '9' or '.'.
  • Any number of cells, from 0 to 81, may be empty.

Examples

Input: (['1.3456789', '456.89123', '789123456', '2345.7891', '56789.2.4', '89123456.', '3456789.2', '678912345', '.12345678'],)

Expected Output: ['123456789', '456789123', '789123456', '234567891', '567891234', '891234567', '345678912', '678912345', '912345678']

Explanation: Source Example 1: rows 0, 1, 3, 5, 6 and 8 miss one digit each; row 4 misses 1 and 3 and column 5 already holds 3, so (4,5)=1 and (4,7)=3; the completion is unique.

Input: (['3........', '.3.......', '.........', '.........', '.........', '.........', '.........', '.........', '.........'],)

Expected Output: []

Explanation: Source Example 2: the 3s at (0,0) and (1,1) differ in row and column but share the top-left box, so the givens break the rules.

Hints

  1. Look at the given digits on their own first: a digit repeated in any row, column or box decides the answer before any empty cell matters.
  2. Completions are compared at the first cell, in reading order, where they differ. Ask what that implies for the digit the answer must hold in the first empty cell, then in the next one.
  3. A partly filled board can be hopeless long before its last cell is reached. An empty cell with no allowed digit, or a row, column or box with a missing digit that fits none of its empty cells, means no completion exists.

Loading coding console...

Show the approach

Approach

Validation. Scan the givens with one 9-bit mask per row, column and box. If a digit is already present in the mask of its row, column or box, the givens break the rules and the answer is [] (this also covers a full board with a repeat).

Completability search. search() decides whether the current partial board has any valid completion and, if so, records one. For every empty cell it computes the candidate mask: digits absent from the cell's row, column and box. It fails at once if an empty cell has no candidate, or if a row, column or box is missing a digit that none of its empty cells can take. If some cell has a single candidate it places it. Otherwise, if a missing digit has exactly one possible cell in some unit, it places the digit there. Otherwise it branches over every candidate of the empty cell with the fewest candidates. Forced moves hold in every completion and branching is exhaustive, so search() succeeds exactly when a completion exists. Every placement is undone before returning, so the board is unchanged afterwards.

Smallest completion. If search() fails on the givens, return []. Otherwise keep its completion as a witness W and visit the empty cells in reading order (row by row, left to right). At cell i, try each candidate digit d < W[i] in increasing order: place d and call search(). The first d that succeeds is fixed and its completion becomes the new witness. If none succeeds, fix W[i]. Invariant: when cell i is visited, every fixed cell equals the corresponding cell of the smallest completion, and W is a completion that agrees with every fixed cell. So W[i] is always achievable, every smaller digit has been tested, and the digit fixed is the smallest one that still allows a completion. That is exactly the rule that the first differing cell takes the smaller digit. After the last cell, the board is the required completion.

Edge cases: a full valid board has no empty cells, so search() succeeds immediately and the board is returned unchanged. With consistent givens but a dead cell, or a digit that fits nowhere in some unit, the first search() fails and the answer is []. The all-empty board returns 123456789 / 456789123 / 789123456 / 214365897 / 365897214 / 897214365 / 531642978 / 642978531 / 978531642.

Time complexity:
O(E * 9 * T), where E <= 81 is the number of empty cells and T is the cost of one pruned completability search. T is exponential in E in the worst case, but the board is fixed at 9 x 9, so every input is bounded by a constant.
Space complexity:
O(E * 81): recursion depth is at most E, with an 81-entry candidate array per level.