rendered paste bodyusing System;
using System.IO;
namespace SudokuBruteForceSolver {
internal class Program {
private static byte[,] puzzle = new byte[9,9];
private static int callCount = 0;
private static int solutionCount = 0;
private static string outputFilename;
private static void Main (string[] args) {
Console.Clear();
string filename;
if (args.Length > 0) filename = args[0];
else {
Console.Write("Please enter input file/path: ");
filename = Console.ReadLine();
}
StreamReader inputFile = File.OpenText(filename);
for (byte i = 0; i < 9; ++i) {
string line = inputFile.ReadLine();
if (line.Length != 9) throw new FormatException();
for (byte j = 0; j < 9; ++j)
if (Char.IsDigit(line[j])) puzzle[i, j] = (byte)Convert.ToInt32(line[j].ToString());
else puzzle[i, j] = 0;
}
inputFile.Close();
inputFile.Dispose();
Console.Write("Please enter output file/path: ");
outputFilename = Console.ReadLine();
File.Create(outputFilename).Close();
Execute();
Console.Write("Press any key to continue... ");
Console.ReadKey(true);
}
private static bool validDigit (byte a, byte b, byte digit) {
byte a0 = (byte)(a - a%3), b0 = (byte)(b - b%3);
for (byte c = 0; c < 9; ++c)
if (puzzle[a, c] == digit || puzzle[c, b] == digit ||
puzzle[a0 + c/3, b0 + c%3] == digit) return false;
return true;
}
// this is my old function that only found one solution
private static bool solved () {
Console.SetCursorPosition(0, 1);
Console.WriteLine("Number of function calls: " + ++callCount);
for (byte a = 0; a < 9; ++a) {
for (byte b = 0; b < 9; ++b) {
if (puzzle[a, b] == 0) Console.Write(' ');
else Console.Write(puzzle[a, b]);
}
Console.Write('\n');
}
for (byte a = 0; a < 9; ++a) {
for (byte b = 0; b < 9; ++b) {
if (puzzle[a, b] == 0) {
for (byte digit = 1; digit <= 9; ++digit) {
if (validDigit(a, b, digit)) {
puzzle[a, b] = digit;
if (solved()) return true;
}
}
puzzle[a, b] = 0;
return false;
}
}
}
return true;
}
// redundant post-calculation check function, checks for summing to 45
private static bool IsValidSolution() {
for (byte a = 0; a < 9; ++a) {
int count1 = 0x1FF, count2 = 0x1FF, count3 = 0x1FF;
for (byte b = 0; b < 9; ++b) {
count1 ^= 1 << (puzzle[a, b] - 1);
count2 ^= 1 << (puzzle[b, a] - 1);
count3 ^= 1 << (puzzle[3*(a/3) + (b/3), 3*(a%3) + (b%3)] - 1);
}
if ((count1 | count2 | count3) != 0) return false;
}
return true;
}
// output results
private static void FoundSolution () {
StreamWriter outputFile = File.AppendText(outputFilename);
Console.Write("solutions: " + ++solutionCount + "; calls: " + callCount + "; sudoku: ");
for (byte a = 0; a < 9; ++a) {
for (byte b = 0; b < 9; ++b) {
if (puzzle[a, b] == 0) {
Console.Write(' ');
outputFile.Write(' ');
}
else {
Console.Write(puzzle[a, b]);
outputFile.Write(puzzle[a, b].ToString());
}
}
//Console.Write('\n');
}
Console.WriteLine("; valid solution: " + IsValidSolution() + "; END.");
outputFile.WriteLine("; END.");
outputFile.WriteLine();
outputFile.Close();
outputFile.Dispose();
}
// recursive solution finder function
private static bool Execute () {
callCount++;
for (byte a = 0; a < 9; ++a) for (byte b = 0; b < 9; ++b) {
if (puzzle[a, b] == 0) {
for (byte digit = 1; digit <= 9; ++digit) {
if (validDigit(a, b, digit)) {
puzzle[a, b] = digit;
if (Execute()) FoundSolution();
}
}
puzzle[a, b] = 0;
return false;
}
}
return true;
}
}
}