こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

数独のJavaプログラム

数独の解答を一発で出すプログラムを考えています。
自分が考えたプログラムは下記の通りです。

import java.util.Random;

public class NumberPlace {

public static void main(String[] args) {

int i, j, k, l, check=0, count=0, tmp;
int a[][] = new int [9][9];

Random rnd = new Random();
int ran;

for ( i=0; i<9; i++ )
for ( j=0; j<9; j++)
a[i][j] = 0;
count = 0;

for ( i=0; i<9; i++ ) {
for ( j=0; j<9; j++) {
ran = rnd.nextInt(9);
tmp = ran + 1;
check = 0;

for ( k=0; k<j; k++ )
if ( a[i][k] == tmp )
check = 1;

for ( k=0; k<i; k++ )
if ( a[k][j] == tmp )
check = 1;

for ( k=(i/3)*3; k<(i/3)*3+3; k++ )
for ( l=(j/3)*3; l<(j/3)*3+3; l++ )
if ( a[k][l] == tmp )
check = 1;

if ( check == 0 )
a[i][j] = tmp;

if ( check == 1 )
j--;

if ( count > 50000 )
break;
count++;
}

count = 0;
}

for ( i=0; i<9; i++) {
for ( j=0; j<9; j++ ) {
if ( a[i][j] < 10 ) {
System.out.print(" ");
}
System.out.print(a[i][j]);
}
System.out.print("\n");
}

}

}

これを実行すると、正しい数独の解が出来るまでに実行を20~30回。多い時は200回前後実行しないと出来ません。

実行結果(0は数独のルール上数字が入らない所)
9 3 6 5 4 1 7 8 2
1 7 4 2 9 6 5 3 0
5 2 8 7 3 0 0 0 0
2 1 5 3 7 8 4 6 9
8 6 3 4 1 9 2 7 5
4 9 7 6 5 2 1 0 0
7 5 1 8 6 4 9 2 3
3 8 2 9 0 0 0 0 0
6 4 9 1 2 5 8 0 0

これを一発で0がない状態にしたいのです。
因みにC言語だと下記のプログラムで一発で出るのですが。(前回質問したプログラム)

int main(void)
{
int i,j,k,l,chk=0,num=0,tmp,count=0;
int a[9][9]; 
srand((unsigned) time(NULL));
start:
count=0;
for(i = 0; i < 9; i++)
for(j = 0; j < 9; j++)
a[i][j]=0;
for(tmp=1;tmp<10;tmp++){
num=0;
while(num<9){
i = rand() % 9;
j = rand() % 9;
chk=0;
for(k=0;k<9;k++)
if(a[i][k]==tmp)chk=1;
for(k=0;k<9;k++)
if(a[k][j]==tmp)chk=1;
for(k=(i/3)*3;k<(i/3)*3+3;k++){
for(l=(j/3)*3;l<(j/3)*3+3;l++){
if(a[k][l]==tmp)chk=1;
}
}
if((chk==0)&&(a[i][j]==0)){
a[i][j]=tmp;
num++;
}
if(count%100==99){
count++;
for(i = 0; i < 9; i++)
for(j = 0; j < 9; j++)
if(a[i][j]==tmp)a[i][j]=0;
num=0;
}
if(count>10000) goto start;
count++;
}
}
for(i = 0; i < 9; i++){
for(j = 0; j < 9; j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}

このプログラムを実行すると一発で解答が出ます。
上のJavaプログラムを下のプログラムのようにするにはどうしたら良いでしょうか。

投稿日時 - 2011-02-08 00:14:57

QNo.6506137

すぐに回答ほしいです

質問者が選んだベストアンサー

簡単な方法は…。

Cのもともとの、問題作成関数あるよね?
これをcreate()と呼ぶことにする。


void create(){
for(){


if(){goto start;}
}
}

となってるよね。

これを、
GOTO文を消す方向で書き直すと、

void A(){
while(true){
if(create()){break;}//完成したら終了
}
}

boolean create(){
for(){


if(){return false;}//問題が未完成ならfalse
}
return true;//完成ならtrue
}

ローカル変数は適宜、"グローバルな"位置に移してね。
これでうまくいくんじゃないかな?

上記のように「関数の2重化」を用いないで、
1つの関数だけで、制御構造を工夫してなんとかするやりかたもあるけど、
ややこしいかも。

投稿日時 - 2011-02-09 03:33:42

お礼

回答ありがとうございます。
やってみたいと思います。

投稿日時 - 2011-02-09 11:22:47

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

http://okwave.jp/qa/q6505044.html
を参考にしてどうなったの?

投稿日時 - 2011-02-08 01:54:19

お礼

回答ありがとうございます。
前の質問で回答して下さった方々の方法もやってみましたが、上手くいきませんでした。
因みに、前の質問でchie65535さんのプログラムをJavaに変えようとしましたが、無限ループに入ってしまい、上手くいきませんでした。

質問したC言語のプログラムを自分なりにJavaプログラム直したら、下記のようになりました。

import java.util.Random;

public class NumberPlaceA {
public static void main(String[] args) {
int i, j, k, l, check = 0, num = 0, count = 0, tmp;
int a[][] = new int [9][9];
Random rnd = new Random();
int ran;
count=0;
for(i = 0; i < 9; i++)
for(j = 0; j < 9; j++)
a[i][j]=0;
for(tmp=1;tmp<10;tmp++){
num=0;
start:
while(num<9){
ran = rnd.nextInt(9);
i = ran;
j = ran;
check=0;
for(k=0;k<9;k++)
if(a[i][k]==tmp)check=1;
for(k=0;k<9;k++)
if(a[k][j]==tmp)check=1;
for(k=(i/3)*3;k<(i/3)*3+3;k++){
for(l=(j/3)*3;l<(j/3)*3+3;l++){
if(a[k][l]==tmp)check=1;
}
}
if((check==0)&&(a[i][j]==0)){
a[i][j]=tmp;
num++;
}
if(count%100==99){
count++;
for(i = 0; i < 9; i++)
for(j = 0; j < 9; j++)
if(a[i][j]==tmp)a[i][j]=0;
num=0;
}
if(count>10000) break start;
count++;
}
}
for ( i=0; i<9; i++) {
for ( j=0; j<9; j++ ) {
if ( a[i][j] < 10 ) {
System.out.print(" ");
}
System.out.print(a[i][j]);
}
System.out.print("\n");
}
}
}

これを実行すると、
3 0 0 0 0 0 0 0 0
0 9 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 7 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 2 0
0 0 0 0 0 0 0 0 0

となります。

投稿日時 - 2011-02-08 09:43:49

あなたにオススメの質問