📜  数独生成器程序

📅  最后修改于: 2022-05-13 01:57:21.391000             🧑  作者: Mango

数独生成器程序

背景:
以下是玩家的数独规则。

  1. 在所有 9 个 3×3 的子矩阵中,元素应该是 1-9,没有重复。
  2. 在所有行中应该有 1-9 之间的元素,没有重复。
  3. 在所有列中应该有 1-9 之间的元素,没有重复。

任务是生成一个有效的 9 x 9 数独网格,即玩家可以按照上述规则集填充网格。

一个简单的天真的解决方案可以是。

  1. 随机取任何数字 1-9。
  2. 检查放入单元格是否安全。(行、列和框)
  3. 如果安全,请将其放置并递增到下一个位置,然后转到步骤 1。
  4. 如果不安全,则不递增转到步骤 1。
  5. 矩阵完全填充后,删除 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