数独生成器程序
背景:
以下是玩家的数独规则。
- 在所有 9 个 3×3 的子矩阵中,元素应该是 1-9,没有重复。
- 在所有行中应该有 1-9 之间的元素,没有重复。
- 在所有列中应该有 1-9 之间的元素,没有重复。
任务是生成一个有效的 9 x 9 数独网格,即玩家可以按照上述规则集填充网格。
一个简单的天真的解决方案可以是。
- 随机取任何数字 1-9。
- 检查放入单元格是否安全。(行、列和框)
- 如果安全,请将其放置并递增到下一个位置,然后转到步骤 1。
- 如果不安全,则不递增转到步骤 1。
- 矩阵完全填充后,删除 k 号。元素随机完成游戏。
改进的解决方案:如果我们了解这个游戏中的模式,我们可以改进解决方案。我们可以观察到,所有对角线存在的 3 x 3 矩阵最初都独立于其他 3 x 3 相邻矩阵,因为其他矩阵是空的。
3 8 5 0 0 0 0 0 0
9 2 1 0 0 0 0 0 0
6 4 7 0 0 0 0 0 0
0 0 0 1 2 3 0 0 0
0 0 0 7 8 4 0 0 0
0 0 0 6 9 5 0 0 0
0 0 0 0 0 0 8 7 3
0 0 0 0 0 0 9 6 2
0 0 0 0 0 0 1 4 5
(我们可以观察到在上面的矩阵中,对角矩阵最初是独立于其他空矩阵的)。因此,如果我们先填写它们,那么我们只需要进行框检查,因此不需要列/行检查。
其次,当我们填充其余的非对角元素时,我们不必使用随机生成器,但我们可以通过检查 1 到 9 递归填充。
Following is the improved logic for the problem.
1. Fill all the diagonal 3x3 matrices.
2. Fill recursively rest of the non-diagonal matrices.
For every cell to be filled, we try all numbers until
we find a safe number to be placed.
3. Once matrix is fully filled, remove K elements
randomly to complete game.
Java
/* Java program for Sudoku generator */
import java.lang.*;
public class Sudoku
{
int[] mat[];
int N; // number of columns/rows.
int SRN; // square root of N
int K; // No. Of missing digits
// Constructor
Sudoku(int N, int K)
{
this.N = N;
this.K = K;
// Compute square root of N
Double SRNd = Math.sqrt(N);
SRN = SRNd.intValue();
mat = new int[N][N];
}
// Sudoku Generator
public void fillValues()
{
// Fill the diagonal of SRN x SRN matrices
fillDiagonal();
// Fill remaining blocks
fillRemaining(0, SRN);
// Remove Randomly K digits to make game
removeKDigits();
}
// Fill the diagonal SRN number of SRN x SRN matrices
void fillDiagonal()
{
for (int i = 0; ii==j
fillBox(i, i);
}
// Returns false if given 3 x 3 block contains num.
boolean unUsedInBox(int rowStart, int colStart, int num)
{
for (int i = 0; i=N && i=N && j>=N)
return true;
if (i < SRN)
{
if (j < SRN)
j = SRN;
}
else if (i < N-SRN)
{
if (j==(int)(i/SRN)*SRN)
j = j + SRN;
}
else
{
if (j == N-SRN)
{
i = i + 1;
j = 0;
if (i>=N)
return true;
}
}
for (int num = 1; num<=N; num++)
{
if (CheckIfSafe(i, j, num))
{
mat[i][j] = num;
if (fillRemaining(i, j+1))
return true;
mat[i][j] = 0;
}
}
return false;
}
// Remove the K no. of digits to
// complete game
public void removeKDigits()
{
int count = K;
while (count != 0)
{
int cellId = randomGenerator(N*N)-1;
// System.out.println(cellId);
// extract coordinates i and j
int i = (cellId/N);
int j = cellId%9;
if (j != 0)
j = j - 1;
// System.out.println(i+" "+j);
if (mat[i][j] != 0)
{
count--;
mat[i][j] = 0;
}
}
}
// Print sudoku
public void printSudoku()
{
for (int i = 0; i
C#
/* C# program for Sudoku generator */
using System;
public class Sudoku
{
int[,] mat;
int N; // number of columns/rows.
int SRN; // square root of N
int K; // No. Of missing digits
// Constructor
public Sudoku(int N, int K)
{
this.N = N;
this.K = K;
// Compute square root of N
double SRNd = Math.Sqrt(N);
SRN = (int)SRNd;
mat = new int[N,N];
}
// Sudoku Generator
public void fillValues()
{
// Fill the diagonal of SRN x SRN matrices
fillDiagonal();
// Fill remaining blocks
fillRemaining(0, SRN);
// Remove Randomly K digits to make game
removeKDigits();
}
// Fill the diagonal SRN number of SRN x SRN matrices
void fillDiagonal()
{
for (int i = 0; ii==j
fillBox(i, i);
}
// Returns false if given 3 x 3 block contains num.
bool unUsedInBox(int rowStart, int colStart, int num)
{
for (int i = 0; i=N && i=N && j>=N)
return true;
if (i < SRN)
{
if (j < SRN)
j = SRN;
}
else if (i < N-SRN)
{
if (j==(int)(i/SRN)*SRN)
j = j + SRN;
}
else
{
if (j == N-SRN)
{
i = i + 1;
j = 0;
if (i>=N)
return true;
}
}
for (int num = 1; num<=N; num++)
{
if (CheckIfSafe(i, j, num))
{
mat[i,j] = num;
if (fillRemaining(i, j+1))
return true;
mat[i,j] = 0;
}
}
return false;
}
// Remove the K no. of digits to
// complete game
public void removeKDigits()
{
int count = K;
while (count != 0)
{
int cellId = randomGenerator(N*N)-1;
// System.out.println(cellId);
// extract coordinates i and j
int i = (cellId/N);
int j = cellId%9;
if (j != 0)
j = j - 1;
// System.out.println(i+" "+j);
if (mat[i,j] != 0)
{
count--;
mat[i,j] = 0;
}
}
}
// Print sudoku
public void printSudoku()
{
for (int i = 0; i
输出:[ 0表示未填充]
2 3 0 4 1 5 0 6 8
0 8 0 2 3 6 5 1 9
1 6 0 9 8 7 2 3 4
3 1 7 0 9 4 0 2 5
4 5 8 1 2 0 6 9 7
9 2 6 0 5 8 3 0 1
0 0 0 5 0 0 1 0 2
0 0 0 8 4 2 9 0 3
5 9 2 3 7 1 4 8 6