【问题标题】:Java Sudoku Generator(easiest solution)Java数独生成器(最简单的解决方案)
【发布时间】:2011-08-06 00:17:47
【问题描述】:

在我在这里看到的最后一个问题中:Sudoku - Region testing 我问了如何检查 3x3 区域,有人能够给我一个令人满意的答案(尽管它需要大量的修补才能让它按我想要的方式工作,因为他们没有提到 table_t 是什么类。)

我完成了这个项目并且能够创建一个数独生成器,但感觉像是做作的。而且我觉得我通过一种非常暴力的方法来生成谜题,以某种方式使事情变得过于复杂。

基本上我的目标是创建一个具有 9-3x3 区域的 9x9 网格。每行/列/区域只能使用数字 1-9 一次。

我解决这个问题的方法是使用二维数组随机放置数字,一次 3 行。一旦 3 行完成,它将检查 3 行、3 个区域和每个垂直列直到第 3 个位置。当它遍历它时,它会做同样的事情,直到数组被填充,但由于我用 rand 填充,并且多次检查每一行/列/区域,感觉非常低效。

除了二维数组之外,是否有一种“更简单”的方法可以使用任何类型的数据构造来执行此操作?有没有一种更简单的方法来检查每个 3x3 区域,这可能与更好地检查垂直或水平一致?从计算的角度来看,我看不出有太多方法可以在不显着增加代码大小的情况下更有效地完成计算。

【问题讨论】:

    标签: java generator sudoku solver


    【解决方案1】:

    我不久前建立了一个数独游戏,并使用 Donald Knuth 的舞蹈链接算法来生成谜题。我发现这些网站对学习和实现算法很有帮助

    http://en.wikipedia.org/wiki/Dancing_Links

    http://cgi.cse.unsw.edu.au/~xche635/dlx_sodoku/

    http://garethrees.org/2007/06/10/zendoku-generation/

    【讨论】:

    • 嗨,Tassinari,你能先看看你拥有的拼图生成器吗?我一直在努力为 SUdoku 拼图 gebnerator 创建我的算法 :( 提前感谢
    • 第二个链接不可访问。请在其他地方上传内容
    【解决方案2】:
    import java.util.Random;
    import java.util.Scanner;
    
    public class sudoku {
    
        /**
         * @antony
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int p = 1;
            Random r = new Random();
            int i1=r.nextInt(8);
            int firstval = i1;
            while (p == 1) {
                int x = firstval, v = 1;
                int a[][] = new int[9][9];
                int b[][] = new int[9][9];
                for (int i = 0; i < 9; i++) {
                    for (int j = 0; j < 9; j++) {
                        if ((x + j + v) <= 9)
                            a[i][j] = j + x + v;
                        else
                            a[i][j] = j + x + v - 9;
                        if (a[i][j] == 10)
                            a[i][j] = 1;
                        // System.out.print(a[i][j]+" ");
                    }
                    x += 3;
                    if (x >= 9)
                        x = x - 9;
                    // System.out.println();
                    if (i == 2) {
                        v = 2;
                        x = firstval;
                    }
                    if (i == 5) {
                        v = 3;
                        x = firstval;
                    }
    
                }
                int eorh;
                Scanner in = new Scanner(System.in);
                System.out
                        .println("hey lets play a game of sudoku:take down the question and replace the 0's with your digits and complete the game by re entering your answer");
                System.out.println("enter your option 1.hard  2.easy");
                eorh = in.nextInt();
                switch (eorh) {
                case 1:
                    b[0][0] = a[0][0];
                    b[8][8] = a[8][8];
                    b[0][3] = a[0][3];
                    b[0][4] = a[0][4];
                    b[1][2] = a[1][2];
                    b[1][3] = a[1][3];
                    b[1][6] = a[1][6];
                    b[1][7] = a[1][7];
                    b[2][0] = a[2][0];
                    b[2][4] = a[2][4];
                    b[2][8] = a[2][8];
                    b[3][2] = a[3][2];
                    b[3][8] = a[3][8];
                    b[4][2] = a[4][2];
                    b[4][3] = a[4][3];
                    b[4][5] = a[4][5];
                    b[4][6] = a[4][6];
                    b[5][0] = a[5][0];
                    b[5][6] = a[5][6];
                    b[6][0] = a[6][0];
                    b[6][4] = a[6][4];
                    b[6][8] = a[6][8];
                    b[7][1] = a[7][1];
                    b[7][2] = a[7][2];
                    b[7][5] = a[7][5];
                    b[7][6] = a[7][6];
                    b[8][4] = a[8][4];
                    b[8][5] = a[8][5];
                    b[0][0] = a[0][0];
                    b[8][8] = a[8][8];
    
                    break;
                case 2:
                    b[0][3] = a[0][3];
                    b[0][4] = a[0][4];
                    b[1][2] = a[1][2];
                    b[1][3] = a[1][3];
                    b[1][6] = a[1][6];
                    b[1][7] = a[1][7];
                    b[1][8] = a[1][8];
                    b[2][0] = a[2][0];
                    b[2][4] = a[2][4];
                    b[2][8] = a[2][8];
                    b[3][2] = a[3][2];
                    b[3][5] = a[3][5];
                    b[3][8] = a[3][8];
                    b[4][0] = a[4][0];
                    b[4][2] = a[4][2];
                    b[4][3] = a[4][3];
                    b[4][4] = a[4][4];
                    b[4][5] = a[4][5];
                    b[4][6] = a[4][6];
                    b[5][0] = a[5][0];
                    b[5][1] = a[5][1];
                    b[5][4] = a[5][4];
                    b[5][6] = a[5][6];
                    b[6][0] = a[6][0];
                    b[6][4] = a[6][4];
                    b[6][6] = a[6][6];
                    b[6][8] = a[6][8];
                    b[7][0] = a[7][0];
                    b[7][1] = a[7][1];
                    b[7][2] = a[7][2];
                    b[7][5] = a[7][5];
                    b[7][6] = a[7][6];
                    b[8][2] = a[8][2];
                    b[8][4] = a[8][4];
                    b[8][5] = a[8][5];
                    break;
                default:
                    System.out.println("entered option is incorrect");
                    break;
                }
    
                for (int y = 0; y < 9; y++) {
                    for (int z = 0; z < 9; z++) {
                        System.out.print(b[y][z] + " ");
                    }
                    System.out.println("");
                }
                System.out.println("enter your answer");
                int c[][] = new int[9][9];
                for (int y = 0; y < 9; y++) {
                    for (int z = 0; z < 9; z++) {
                        c[y][z] = in.nextInt();
                    }
                }
                for (int y = 0; y < 9; y++) {
                    for (int z = 0; z < 9; z++)
                        System.out.print(c[y][z] + " ");
                    System.out.println();
                }
                int q = 0;
                for (int y = 0; y < 9; y++) {
                    for (int z = 0; z < 9; z++)
                        if (a[y][z] == c[y][z])
                            continue;
                        else {
                            q++;
                            break;
                        }
                }
                if (q == 0)
                    System.out
                            .println("the answer you have entered is correct well done");
                else
                    System.out.println("oh  wrong answer better luck next time");
                System.out
                        .println("do you want to play a different game of sudoku(1/0)");
                p = in.nextInt();
                firstval=r.nextInt(8);
                /*if (firstval > 8)
                    firstval -= 9;*/
            }
    
        }
    }
    

    【讨论】:

    • 试试这个代码。这个代码生成一个数独问题。用户必须解决难题并手动输入每个元素,答案将与所需结果进行比较,并显示您的答案是否正确.
    【解决方案3】:

    我认为您可以使用一维数组,就像一维数组可以模拟二叉树一样。例如,要查看数字下方的值,请将 9 添加到索引中。

    我只是编造了这个,但是这样的东西可以吗?

    private boolean makePuzzle(int [] puzzle,  int i)
    {
         for (int x = 0; x< 10 ; x++)
         {
               if (//x satisfies all three conditions for the current square i)
               {
                    puzzle[i]=x;
                    if (i==80) return true //terminal condition, x fits in the last square
                    else
                        if makePuzzle(puzzle, i++);//find the next x
                             return true; 
               }// even though x fit in this square, an x couldn't be 
                 // found for some future square, try again with a new x
         }
         return false; //no value for x fit in the current square
     } 
    
     public static void main(String[] args ) 
     {
      int[] puzzle = new int[80];
      makePuzzle(puzzle,0);
      // print out puzzle here
     }       
    

    编辑:自从我在 Java 中使用数组以来已经有一段时间了,如果我搞砸了任何语法,对不起。请考虑它的伪代码:)

    这是我评论中描述的代码。

    public class Sudoku
    {
        public int[] puzzle = new int[81];
        private void makePuzzle(int[] puzzle, int i)
        {
            for (int x = 1; x< 10 ; x++)
            {
                puzzle[i]=x;
                if(checkConstraints(puzzle))
                {
                    if (i==80)//terminal condition
                    {
                        System.out.println(this);//print out the completed puzzle
                            puzzle[i]=0;
                        return;
                    }
                    else
                        makePuzzle(puzzle,i+1);//find a number for the next square                          
                }
                puzzle[i]=0;//this try didn't work, delete the evidence 
            }       
        }
        private boolean checkConstraints(int[] puzzle)
        {
            int test;
         //test that rows have unique values    
          for (int column=0; column<9; column++)
            {
                for (int row=0; row<9; row++)
                {
                    test=puzzle[row+column*9];
                    for (int j=0;j<9;j++)
                    {
                        if(test!=0&&  row!=j&&test==puzzle[j+column*9])
                            return false;
                    }
                }
            }
            //test that columns have unique values
            for  (int column=0; column<9; column++) 
            {
                 for(int row=0; row<9; row++)
                {
                    test=puzzle[column+row*9];
                    for (int j=0;j<9;j++)
                    {
                        if(test!=0&&row!=j&&test==puzzle[column+j*9])
                            return false;
                    }
                }
            }
            //implement region test here
            int[][] regions = new int[9][9];
            int[] regionIndex ={0,3,6,27,30,33,54,57,60};
            for (int region=0; region<9;region++) //for each region
            {
    
                int j =0;
                for (int k=regionIndex[region];k<regionIndex[region]+27; k=(k%3==2?k+7:k+1))
                    {
                        regions[region][j]=puzzle[k];
                        j++;
                    }
            }
            for (int i=0;i<9;i++)//region counter
            {
                for (int j=0;j<9;j++)
                {
                    for (int k=0;k<9;k++)
                    {
                        if (regions[i][j]!=0&&j!=k&&regions[i][j]==regions[i][k])
                        return false;
                    }
    
                }
            }
        return true;
    
        }
        public String toString()
        {
            String string= "";
            for (int i=0; i <9;i++)
            {
                for  (int j = 0; j<9;j++)
                {
                    string = string+puzzle[i*9+j];
                }
                string =string +"\n";
            }
            return string;
        }
        public static void main(String[] args)
        {
            Sudoku sudoku=new Sudoku();
            sudoku.makePuzzle(sudoku.puzzle, 0);
        }
    
    }
    

    【讨论】:

    • 刚刚想到这个......当数组初始化时,它会充满零,这会搞砸了。也许最好使用 1...10 作为可能的数独值,而不是 0...9。完成生成后,您可以减少每个值。
    • 刚刚想到别的东西...我显然对数独一无所知 :) 显然 0 在数独游戏中不是有效值!谁知道?不过我清理了上面的代码,在我修复了所有明显的错误之后它似乎工作了:) 你只需要正确地编写约束。
    • 好的,实际上已经成功了,所以这里有一些代码。它可以工作,但它只测试列和行。您必须自己弄清楚区域测试:) 如果您决定将其转换为 2d 数组以进行此测试,请查看 toString() 方法。添加后,这将生成所有有效的数独网格。我将编辑原始答案以包含新代码。
    【解决方案4】:

    试试这个代码:

    package com;
    public class Suduku{
        public static void main(String[] args ){
            int k=0;
            int fillCount =1;
            int subGrid=1;
            int N=3;
            int[][] a=new int[N*N][N*N];
        for (int i=0;i<N*N;i++){
            if(k==N){
                k=1;
                subGrid++;
                fillCount=subGrid;
            }else{
                k++;
                if(i!=0)
                fillCount=fillCount+N;
            }
            for(int j=0;j<N*N;j++){
                if(fillCount==N*N){
                    a[i][j]=fillCount;
                    fillCount=1;
                    System.out.print("  "+a[i][j]);
                }else{
                    a[i][j]=fillCount++;
                    System.out.print("  "+a[i][j]);
                }
            }
            System.out.println();
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-08
      • 2011-10-18
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2010-09-05
      相关资源
      最近更新 更多