You’re one of those people who prefer writing numbers from 1 to 9 into quadratic boxes and you know how to use C# and .Net? If both applies to you, then stop reading here. If only one statement is true, continue.
Sudoku is actually quite logical and pretty easy to solve, especially with a high-end cpu in the background. I’m quite sure you all know the rules (not the same number in row, column and region). That’s it, quite simple. And all C# functionality you need for this is respectively one function to check the correctness of your inputs, two stacks to juggle with your numbers and some for loops to cycle through the possible values. That’s all, and here you go. At one function to test the region:
[code lang="c#"]
public static bool TestRegion(int index, int value)
{
if (value > 9)
return false;
int start_row = ((index / 9) / 3) * 3;
int start_col = ((index % 9) / 3) * 3;
for (int col = start_col; col <= start_col + 2; col++) {
for (int row = start_row; row <= start_row + 2; row++) {
int i = row*9 + col;
if (grid[i] != 0)
{
if (value == grid[i] && i != index)
return false;
}
}
}
return true;
}
[/code]
I will skip the ones for the rows and the columns, they are quite similar.
And now our ‘main’ function, with the declaration and definition of the most important variables.
[code lang="c#"]
static Stack doneempties = new Stack();
static Stack beginempties = new Stack();
static int[] grid = new int[81];
index = (int)begin_empties.Pop();
while (!(succeed)) {
bool right_number = false;
int value = grid[index]+1;
while ((!(right_number)) ^ (value == 10)) {
right_number = TestRow(index, value) & TestCol(index, value) & TestRegion(index, value);
if (!(right_number))
value++;
counter++;
}
if (value == 10) {
grid[index] = 0;
int tmp = index;
begin_empties.Push((int)index);
if (done_empties.Count != 0)
index = (int)done_empties.Pop();
else
{
Console.WriteLine("\nNo more solutions.\n");
break;
}
} else {
grid[index] = value;
done_empties.Push((int)index);
if (begin_empties.Count != 0)
index = (int)begin_empties.Pop();
else
succeed = true;
if (succeed)
{
for (int i = 0; i <= 8; i++)
{
for (int u = 0; u <= 8; u++)
Console.Write(grid[i*9+u].ToString() + " ");
Console.Write("\n");
}
done_empties.Clear();
int rem = grid[(int)arr[0]];
for (int i = arr.Count-1; i >= 0; i--)
{
begin_empties.Push((int)arr[i]);
grid[(int)arr[i]] = 0;
}
grid[(int)arr[0]] = rem;
index = (int)begin_empties.Pop();
succeed = false;
}
}
}
[/code]
Once again, now in words: I pop an item from the source-stack, which holds all my indexes I have to work through. I try to set a value and check if it’s logically correct. If it is I will push it to the destination-stack, holding the indexes we already worked through. Then I’ll do this step again (pop an item, set a value, check for correctness). But if the value is not valid, I’ll push it back to the source-stack and pop an item from the destination-stack.
When my source-stack is empty, I found my solution. To make sure there’s no other solution, I will shuffle back all my values to the source-stack, except the first one, and run through the whole procedure again.
Sudoku (source code, binaries and example file included) [4KB]