Java数独生成器(最简单的解决方案)

时间:2011-08-06 00:17:47

标签: java generator sudoku solver

我在这里看到的最后一个问题:Sudoku - Region testing我问过如何检查3x3区域,有人能够给我一个满意的答案(虽然它涉及很多修补工作,让它按我想要的方式工作,因为他们没有提到类table_t是什么。)

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

基本上我的目标是创建一个9x9网格,其中包含9-3x3区域。每行/列/区域必须仅使用数字1-9一次。

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

除了2D阵列之外,还有一种“更简单”的方法可以用于任何类型的数据构造吗?是否有更简单的方法来检查每个3x3区域可能与检查vert或horizo​​ntal更好一致?从计算的角度来看,我没有太多方法可以更有效地实现它,而不会显着扩大代码的大小。

4 个答案:

答案 0 :(得分:7)

前段时间我建立了一个数独游戏,并使用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/

答案 1 :(得分: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;*/
        }

    }
}

答案 2 :(得分:0)

我认为你可以使用一维数组,就像一维数组可以为二叉树建模一样。例如,要查看数字下方的值,请将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);
    }

}

答案 3 :(得分:0)

试试这段代码:

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();
    }
}
}