Код:
using Microsoft.SolverFoundation.Solvers;
using System;
namespace Sudoku
{
class Program
{
private static CspTerm[] GetSlice(CspTerm[][] sudoku, int Ra, int Rb, int Ca, int Cb)
{
CspTerm[] slice = new CspTerm[9];
int i = 0;
for (int row = Ra; row < Rb + 1; row++)
for (int col = Ca; col < Cb + 1; col++)
{
{
slice[i++] = sudoku[row][col];
}
}
return slice;
}
static void Main(string[] args)
{
Console.Title = "Программа для решения судоку.";
Console.ForegroundColor = ConsoleColor.Green;
Console.BackgroundColor = ConsoleColor.Black;
Console.SetWindowSize(Console.LargestWindowWidth - 3, Console.LargestWindowHeight - 2);
Console.Write("************************************************************************************************");
Console.Write("\nУсловие программы: " +
"Судоку размера n называется квадрат со стороной n2, разделенный на n2" +
"\nсредних квадратов со стороной n, каждый из которых разделен на n2 маленьких квадратов." +
"\nВ каждом маленьком квадрате записано число от 1 до n2." +
"\nСудоку называется правильным, если в каждом столбце," +
"\nкаждой строке и каждом среднем квадрате встречаются все числа от 1 до n2." +
"\nНедавно Вася нарисовал Судоку размера n." +
"\nВаша задача – помочь ему определить правильный ли он.");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("\n************************************************************************************************");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("Введите ширину судоку: ");
int N = Convert.ToInt32(Console.ReadLine());
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("Введите высоту судоку: ");
int M = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("");
if (N == M)
{
int[,] B = new int[N, M];
for (int row = 0; row < B.GetLength(0); row++)
{
for (int col = 0; col < B.GetLength(1); col++)
{
if (B[row, col] == 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
}
{
Console.Write($"Введите [{row + 1} - строку {col + 1} - столбец] - ");
B[row, col] = byte.Parse(Console.ReadLine());
}
}
}
Console.WriteLine("\nИсходные данные нашего судоку:");
for (int row = 0; row < M; row++)
{
for (int col = 0; col < N; col++)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(B[row, col] + "\t");
}
Console.WriteLine();
}
ConstraintSystem S = ConstraintSystem.CreateSolver();
CspDomain Z = S.CreateIntegerInterval(1, 9);
CspTerm[][] sudoku = S.CreateVariableArray(Z, "cell", 9, 9);
for (int row = 0; row < N; row++)
{
for (int col = 0; col < M; col++)
{
if (B[row, col] > 0)
{
S.AddConstraints(S.Equal(B[row, col], sudoku[row][col]));
}
}
S.AddConstraints(S.Unequal(GetSlice(sudoku, row, row, 0, 8)));
}
for (int col = 0; col < 9; col++)
{
S.AddConstraints(S.Unequal(GetSlice(sudoku, 0, 8, col, col)));
}
for (int a = 0; a < 3; a++)
{
for (int b = 0; b < 3; b++)
{
S.AddConstraints(S.Unequal(GetSlice(sudoku, a * 3, a * 3 + 2, b * 3, b * 3 + 2)));
}
}
Console.WriteLine("\nРешение судоку:");
ConstraintSolverSolution soln = S.Solve();
object[] h = new object[9];
for (int row = 0; row < N; row++)
{
if ((row % 3) == 0)
for (int col = 0; col < M; col++)
{
soln.TryGetValue(sudoku[row][col], out h[col]);
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{h[0]}\t{h[1]}\t{h[2]}\t{h[3]}\t{h[4]}\t{h[5]}\t{h[6]}\t{h[7]}\t{h[8]}");
}
}
else if (N != M)
{
Console.WriteLine($"Судоку не может быть размером {N} на {M} то есть прямоугольной формы.");
}
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("\nПрограмма завершена, нажмите любую клавишу . . .");
Console.ReadKey();
}
}
}
}