From 6b4946216054d9fb9cd93104334287324b899228 Mon Sep 17 00:00:00 2001 From: Jali Date: Fri, 1 Aug 2025 16:49:59 +0200 Subject: [PATCH] initial commit --- README.md | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f614acd --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ +# 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.