我在这里看到的最后一个问题:Sudoku - Region testing我问过如何检查3x3区域,有人能够给我一个满意的答案(虽然它涉及很多修补工作,让它按我想要的方式工作,因为他们没有提到类table_t是什么。)
我完成了项目,并且能够创建一个数独生成器,但感觉就像它的设计。而且我觉得我通过采用非常强力的方法来制作谜题,以某种方式使事情变得过于复杂。
基本上我的目标是创建一个9x9网格,其中包含9-3x3区域。每行/列/区域必须仅使用数字1-9一次。
我解决这个问题的方法是使用二维数组随机放置数字,一次放3行。一旦完成3行,它将检查3行,3个区域和每个垂直col直到第3个位置。因为它迭代通过它会做同样的事情,直到数组被填充,但由于我正在填充rand,并且多次检查每个行/列/区域,它感觉非常低效。
除了2D阵列之外,还有一种“更简单”的方法可以用于任何类型的数据构造吗?是否有更简单的方法来检查每个3x3区域可能与检查vert或horizontal更好一致?从计算的角度来看,我没有太多方法可以更有效地实现它,而不会显着扩大代码的大小。
答案 0 :(得分:7)
前段时间我建立了一个数独游戏,并使用Donald Knuth的跳舞链接算法来生成谜题。我发现这些网站在学习和实现算法方面非常有用
http://en.wikipedia.org/wiki/Dancing_Links
答案 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&®ions[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();
}
}
}