2011-08-06 16 views
5

私の最後の質問はこちらSudoku - Region testing私は3x3地域をチェックする方法を尋ねました。誰かが私に満足のいく回答を与えることができました(ただし、彼らはtable_tクラスが何であるかについて言及していなかったので、望んでいた。)Java Sudoku Generator(もっとも簡単な解決策)

私はプロジェクトを完了し、スドクジェネレータを作成することができたが、それは人工的だと感じた。そして、私はパズルを生成するために非常に力強いアプローチをとることによって、何とか複雑なことをやったように感じる。

私の目標は、9- 3x3の領域を持つ9x9グリッドを作成することです。各行/ col/regionは1〜9の数字を1回だけ使用する必要があります。

私がこれを解決しようとした方法は、一度に3行ずつランダムに数字を配置するために2次元配列を使用することでした。いったん3行が行なわれると、3行と3領域と3行目までの各垂直colをチェックします。それが繰り返されるにつれ、配列がいっぱいになるまでは同じことが実行されますが、ランドでいっぱいで、各行/列/領域を何度もチェックしているため、非常に効率が悪いと感じました。

2次元配列以外の任意のタイプのデータ構造でこれを行う方法はありますか?各3x3領域を確認する簡単な方法はありますか?計算の観点からは、コードのサイズを劇的に膨らませることなく、より効率的に行う方法はあまりありません。

答えて

7

私は少し前にスドクゲームを作り、Donald Knuthのダンスリンクアルゴリズムを使ってパズルを作りました。私はあなたが1次元配列をモデル化することができますほとんど同じように、1次元配列を使用することができると思うの学習では、これらのサイトは非常に役に立ったとアルゴリズム

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

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

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

+0

こんにちはTassinari、 あなたが持っているパズルジェネレータのスニークピークを与えることができますか?私はSUDokuのパズルgebneratorのための私のアルゴリズムを作成するために苦労していた:( アドバンテージありがとう –

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

} 
+0

ちょうどこれを考えて...配列が初期化されるとき、それはゼロのいっぱいになります。 0 ... 9の代わりに1〜10のスードク値を使用する方が良いです。生成が完了したら、それぞれの値を減らすことができます。 – user646539

+0

ちょっと考えました...私は明らかにスドクについて何も知りません:)明らかに0はスドクパズルの有効な値ではありません!誰かわかったね?私は上記のコードをクリーンアップし、すべての明白な間違いを修正した後に動作するように見えました:)あなたはただの制約を正しく書く必要があります。 – user646539

+0

これは実際にはうまく機能しているので、ここにいくつかのコードがあります。それは動作しますが、列と行のみをテストします。あなたは自分自身で地域テストを理解する必要があります:)このテストのために2次元配列に変換することにした場合は、toString()メソッドをチェックしてください。これを追加すると、すべての有効なスドクグリッドが生成されます。元の回答を編集して新しいコードを追加します。 – user646539

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

    } 
} 
+1

このコードを試してみてください。このコードは数独質問を生成します。ユーザーはパズルを解き、各要素を手動で入力する必要があります。答えが必要な結果と比較され、答えが正しいかどうかが表示されます。 –

関連する問題