Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

This Will Be Important Later

You may have already finished all the Sudoku puzzles without any problem-space reduction. I strongly suggest you consider following through with what I'm about to propose and the reason is because of Killer Sudoku Solver and Killer Sudoku Extreme Challenge. 100% of any effort you put forward on this exercise will benefit you when you solve the Killer Sudoku puzzles, which begin with all the same rules as Sudoku and then add a few details you can tackle later.

Initial Challenge - Lone Singles

My initial challenge is for you to implement the reduction technique covered in the previous pages. On the website Learn-Sudoku.com, this technique is referred to as Lone Singles. For any cell that has been reduced to a single candidate, that value may be removed from the candidate lists of all other cells in the same groups. With just this one reduction technique, you can achieve the following results on each of the CodinGame Sudoku puzzles...without any backtracking.


PuzzleResults
Sudoku Solver
✅ Test Case 1: Very Easy
❌ Test Case 2: Easy - Oh, so close!
❌ Test Case 3: Intermediate/Hard - Minimal reduction.
❌ Test Case 4: World's Hardest Sudoku - No reduction at all.

16x16 Sudoku
✅ Test Case 1: Test 1
✅ Test Case 2: Test 2

❌ Test Case 3: Test 3 - Minimal reduction.
❌ Test Case 4: Test 4 - Minimal reduction.
❌ Test Case 5: Test 5 - Minimal reduction.
❌ Test Case 6: Test 6 - Minimal reduction.

25x25 Sudoku
❌ Test Case 1: Test 1 - 77 more cells found.
❌ Test Case 2: Test 2 - Minimal reduction.
❌ Test Case 3: Test 3 - Minimal reduction.
❌ Test Case 4: Test 4 - Minimal reduction.
❌ Test Case 5: Test 5 - Minimal reduction.


Mini Sudoku Solver
✅ Test Case 1: Test 1
✅ Test Case 2: Test 2
✅ Test Case 3: Test 3
✅ Test Case 4: Test 4

Level 2 Challenge - Hidden Singles

Going back to Learn-Sudoku.com, let's add another fairly easy technique, Hidden Singles. A hidden single is a cell in a group that has one candidate that does not appear in the candidate list of any other cell in the group. Because this candidate only appears in a single cell in the group, it is known where the candidate belongs. Adding this one additional basic technique will improve your results.


PuzzleResults
Sudoku Solver
✅ Test Case 1: Very Easy
✅ Test Case 2: Easy
❌ Test Case 3: Intermediate/Hard - 12 more cells found.
❌ Test Case 4: World's Hardest Sudoku - No reduction at all.

16x16 Sudoku
✅ Test Case 1: Test 1
✅ Test Case 2: Test 2

❌ Test Case 3: Test 3 - 49 more cells found.
❌ Test Case 4: Test 4 - 14 more cells found.
❌ Test Case 5: Test 5 - 41 more cells found.
❌ Test Case 6: Test 6 - 56 more cells found.

25x25 Sudoku
✅ Test Case 1: Test 1
❌ Test Case 2: Test 2 - 56 more cells found.
❌ Test Case 3: Test 3 - 68 more cells found.
❌ Test Case 4: Test 4 - 58 more cells found.
❌ Test Case 5: Test 5 - 66 more cells found.


Mini Sudoku Solver
✅ Test Case 1: Test 1
✅ Test Case 2: Test 2
✅ Test Case 3: Test 3
✅ Test Case 4: Test 4


Ultimate Sudoku Logic Challenge

Learn-Sudoku.com has several more reduction strategies. Can you implement enough to solve every traditional Sudoku puzzle with logic alone? I will keep my own progress updated in a table at the end of this playground. If you take on this challenge, I do have one suggestion for your data structure. I have found it helpful if each cell has pointers to the groups to which it belongs. Conceptually, the object model has one small addition shown below.



Sudoku Data Structure

As the SudokuGroups are being filled with SudokuCells, it is easy enough to give each cell 3 pointers, one to each of the groups where it is a member. I have used a named tuple to hold these three pointers. In the constructor, the new groups attribute is initialized to None.

CellGroups = namedtuple('CellGroups', 'row col box')

class SudokuCell():

    def __init__(self, value: str, all_possible_values: str):
        self.value = value
        self.candidates = set(all_possible_values) if value == UNKNOWN else {value}
        self.groups = CellGroups(None, None, None)

As the groups are being built in the SudokuSolver constructor, give each cell a tuple of pointers to the groups to which it belongs.

        for row in range(size):
            for col in range(size):
                box = row // box_size * box_size + col // box_size
                cell = self.grid[(row, col)]

                rows[row].cells.append(cell)
                cols[col].cells.append(cell)
                boxes[box].cells.append(cell)

                cell.groups = CellGroups(rows[row], cols[col], boxes[box])

Solving Logic Puzzles Logically

Many Sudoku puzzles can be solved without making any guesses. Click here to see my progress toward solving as many logic puzzles as possible, strictly with logic, no guessing and no backtracking.

Open Source Your Knowledge: become a Contributor and help others learn. Create New Content