Files
PDP10Sudoku/README.md
2025-08-01 16:49:59 +02:00

147 lines
4.4 KiB
Markdown

# PDP-10 simple solver for Sudokus
## What is a sudoku?
[Sudoku](https://en.wikipedia.org/wiki/Sudoku) is a logic based number-placement
puzzle game originally from Japan. The word *sudoku* literally means
*digit-single*. The objecttive is to fill a 9x9 grid with numbers between 1 and
9, without having a number repeat in a row, column or a 3x3 subgrid. Normally,
there are a few numbers preset. In a regular sudoku, the pre-filled numbers make
sure, that exactly one solution for the puzzle exists.
The number of possible valid solutions to a sudoku is finite. In a classical
Sudoku, there are 6,670,903,752,021,072,936,960 possible valid grids. A number
that reduces to 5,472,730,538 essentially different solutions. The Sudokus you
will find in a modern day puzzle book, are always one of those roughly 5
billion, in order to guarantee a solution.
### Rules
A Sudoku is presented in a 9x9-grid:
```
||===|===|===||===|===|===||===|===|===||
|| | | 2 || 9 | | 3 || 8 | | ||
||---|---|---||---|---|---||---|---|---||
|| | | || 4 | 6 | 8 || | | ||
||---|---|---||---|---|---||---|---|---||
|| 4 | | || | | || | | 1 ||
||===|===|===||===|===|===||===|===|===||
|| 5 | 6 | || | | || | 4 | 9 ||
||---|---|---||---|---|---||---|---|---||
|| | 2 | || | 5 | || | 7 | ||
||---|---|---||---|---|---||---|---|---||
|| 7 | 8 | || | | || | 1 | 3 ||
||===|===|===||===|===|===||===|===|===||
|| 2 | | || | | || | | 7 ||
||---|---|---||---|---|---||---|---|---||
|| | | || 3 | 8 | 4 || | | ||
||---|---|---||---|---|---||---|---|---||
|| | | 6 || 2 | | 1 || 3 | | ||
||===|===|===||===|===|===||===|===|===||
```
The rules are the following:
- Every row must contain every number between 1 and 9 exactly once.
- Every vertical column must contain all the numbers between 1 and 9 exactly
once.
- Every 3x3 sub-grid must contain every number between 1 and 9 exactly once.
## Solving Sudokus programatically
### Backtracking (naïve approach)
Solving a Sudoku can be achieved in serveral ways. The most simple algorithm, is
a backtracking algorithm. With this a sudoku can be resolved basically by
brute-forcing it. In this case, we walk through each cell of the grid
recurseivly, and add a number. Then we check, if the grid is still valid. If it
is, we recursivly move on to the next column. If we find a number that doesn't
match, we return to the previous incarnation, and try another number. In order
to check, if our grid is still valid, we can use simple function:
```C
// Function to check, if it is save to place num at mat[row][col]
int isSafe(int[][] *mat, int row, int col, int num) {
// Check if num exists in the row
for (int x = 0; x <= 8; x++) {
if (*mat[row][x] == num) {
return 0;
}
}
// Check, if num exists in column
for (int x = 0; x < 8; x++) {
if (*mat[x][col]) {
return 0;
}
}
// Check if num exists in the 3x3 sub matrix
int startRow = row - (row % 3);
int startCol = col - (col % 3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++ {
if (*mat[i + startRow][j + startCol] == num) {
return 0;
}
}
}
return 1;
}
```
The only bit in this code, not straight forward, is the last part. By taking the
modulus of the current row and column, we can find the top left element in each
sub-grid, and adding the according number to it, we can then walk through.
The solving algorithm itself, is surprisingly simple:
```C
// Function to solve the sudoku problem by backtracking.
int solveSudokuRec(int[][] *mat, int row, int col) {
int n = sizeof(*mat);
// base case: Reached the nth column of the last row. We're done.
if (row == n - 1 && col == n) {
return 1;
}
// if last column of a row, go to next row
if (col == n) {
row++;
col=0;
}
// if cell is already occupied, move on
if (*mat[row][col] != 0) {
return solveSudokuRec(mat, row, col + 1);
}
for (int num = 1; num <= n; num++) {
// if it is safe to place num at current position, do so.
if (isSafe(mat, row, col, num)) {
*mat[row][col] = num;
if (solveSudokuRec(mat, row, col + 1)) {
return 1;
}
*mat[row][col] = 0;
}
}
return 0;
}
```
And that's it.
## Using the PDP-10 to solve the Sudoku
The PDP-10 should be able to solve the sudoku using backtracking. The above
algorithm will be implemented directly in PDP-10 assembly, using the MIDAS
assembler, of the ITS operating system.