Update
This commit is contained in:
parent
a2a9b750ab
commit
ec03c1b60c
22 changed files with 1804 additions and 1686 deletions
108
sudoku.md
108
sudoku.md
|
@ -74,6 +74,114 @@ For a unique solution sudoku we have to check there still exists exactly one sol
|
|||
|
||||
The matter of generating sudokus is further complicated by taking into account the difficulty rating of the puzzle.
|
||||
|
||||
## Code
|
||||
|
||||
Here is a [C](c.md) code that solves sudoku with [brute force](brute_force.md) (note that for too many empty squares it won't be usable as it might run for years):
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
|
||||
char sudoku[9 * 9] = // 0s for empty squares
|
||||
{
|
||||
9, 3, 1, 0, 5, 7, 2, 6, 0,
|
||||
6, 5, 0, 9, 1, 8, 3, 4, 7,
|
||||
4, 7, 8, 6, 3, 2, 1, 9, 5,
|
||||
|
||||
7, 1, 5, 2, 6, 0, 4, 8, 3,
|
||||
3, 0, 6, 5, 8, 1, 7, 2, 9,
|
||||
2, 8, 9, 7, 0, 3, 6, 5, 1,
|
||||
|
||||
5, 6, 7, 3, 9, 0, 8, 1, 2,
|
||||
8, 2, 0, 1, 7, 5, 9, 3, 6,
|
||||
1, 9, 3, 8, 2, 6, 5, 0, 4
|
||||
};
|
||||
|
||||
void print(void)
|
||||
{
|
||||
puts("-----------------");
|
||||
|
||||
for (int i = 0; i < 9 * 9; ++i)
|
||||
{
|
||||
putchar('0' + sudoku[i]);
|
||||
putchar(i % 9 != 8 ? ' ' : '\n');
|
||||
}
|
||||
}
|
||||
|
||||
int isValid(void) // checks if whole sudoku is valid
|
||||
{
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
unsigned int m1 = 0, m2 = 0, m3 = 0; // bit masks of each group
|
||||
|
||||
char *s1 = sudoku + i, // column
|
||||
*s2 = sudoku + i * 9, // row
|
||||
*s3 = sudoku + (i / 3) * (3 * 3 * 3) + (i % 3) * 3; // square
|
||||
|
||||
for (int j = 0; j < 9; ++j)
|
||||
{
|
||||
m1 |= (1 << (*s1));
|
||||
m2 |= (1 << (*s2));
|
||||
m3 |= (1 << (*s3));
|
||||
|
||||
s1 += 9;
|
||||
s2 += 1;
|
||||
s3 += (j % 3 != 2) ? 1 : 7;
|
||||
}
|
||||
|
||||
if ((m1 != m2) || (m1 != m3) || (m1 != 0x03fe)) // all must be 1111111110
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int printCounter = 0;
|
||||
|
||||
int solve(void) // find first empty square and brute forces all values on it
|
||||
{
|
||||
char *square = sudoku;
|
||||
|
||||
printCounter++;
|
||||
|
||||
if (printCounter % 512 == 0) // just to limit printing speed
|
||||
print();
|
||||
|
||||
for (int j = 0; j < 9 * 9; ++j, ++square) // find first empty square
|
||||
if (!(*square)) // empty square?
|
||||
{
|
||||
while (1) // try all possible values in the square
|
||||
{
|
||||
*square = ((*square) + 1) % 10;
|
||||
|
||||
if (!(*square)) // overflow to 0 => we tried all values now
|
||||
break;
|
||||
|
||||
if (solve()) // recursively solve the next empty square
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0; // no value led to solution => can't be solved
|
||||
}
|
||||
|
||||
// no empty square found, the sudoku is filled
|
||||
return isValid();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Here we could do some initial attempts at reasoning and filling in
|
||||
digits by "logic" before getting to brute force -- with too many empty
|
||||
squares brute force will take forever. However this is left as an
|
||||
exercise :-) */
|
||||
|
||||
int success = solve();
|
||||
print();
|
||||
puts(success ? "solved" : "couldn't solve it");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
- [sudo](sudo.md)
|
Loading…
Add table
Add a link
Reference in a new issue