C言語で数独の問題をつくる

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
すけ

C言語で数独の問題をつくる

#1

投稿記事 by すけ » 17年前

はじめまして!
C言語初心者です。
今、数独の問題をつくるプログラムをC言語で作っています。
数独については(http://ja.wikipedia.org/wiki/%E6%95%B0%E7%8B%AC)で御覧下さい。

問題を作るには、まず解けなくてはいけないと思い、解答するプログラムをつくりました。
それで、問題作成にとりかかっているのですが、上手くできません。

考えている方法は、
1、行・列・3*3ボックスで重複しないように、ランダムに81マスを全部埋める。
2、そこから、適当なマスを空(0)にする。
3、その問題が、解答プログラムで解けたら、問題作成終了
という感じで作ろうと思っています。

そして今、1番で悩んでいます。
バックトラックという方法を見つけたのですが、それをどのように実装したらいいのかわかりません。

どなたか教えていただけないでしょうか。
初心者なので、易しく教えてください!
お願いします!

やそ

Re:C言語で数独の問題をつくる

#2

投稿記事 by やそ » 17年前

問題を解くプログラムは出来たのですね。

まずご自分ではどのように組んで、どの辺りで詰まっているのでしょうか?

すけ

Re:C言語で数独の問題をつくる

#3

投稿記事 by すけ » 17年前

お返事ありがとうございます!

問題を解くとこまではできてます。

問題作成の部分は、下の関数で作っています。
見にくくてもうしわけないのですが...
説明は下に書いておきます。
void Rand_prob (void)
{
	int rand_num = 0;
	int det_count = 0;

	for(;;){
		i = rand() %9;
		j = rand() %9;

		if(Cell_[j].det == 0){
			rand_num = rand() %9 + 1;
			if(poss_Row[rand_num-1] == 0 && poss_Line[j][rand_num-1] == 0 && poss_Box[Cell_[j].Box_num][rand_num-1] == 0){
				Cell_[j].det = rand_num;
				det_count++;
				poss_Row[rand_num-1] = 1;
				poss_Line[j][rand_num-1] = 1;
				poss_Box[Cell_[j].Box_num][rand_num-1] = 1;
			}
		}
	if(det_count == 32) break;
	}
}


Cell_[行][列]は、各マスの構造体で、detとBox_numというメンバをもっています。
detには最初、0が入っていて、ランダムに決めた数字を入れていきます。
Box_numにはそのマスのボックス番号が入っています。
ここで言うボックス番号とは、3*3のボックスを左上から順に、
0 1 2
3 4 5
6 7 8
という風にしました。

あと、poss_Row[行][数字]とposs_Line[列][数字]とposs_Box[ボックス番号][数字]は各行・列・ボックス
に[数字]が入っているかどうかを入れていきます。
最初は全て0が入っていて、その数字が行・列・ボックスに入ったら、1に変えます。

これで、32マスが埋まったら止まるのですが、解が存在しない問題が出来てしまいます。
そこで、81マス全てを埋めてから、数マスずつ空にしていく方法に変えようと思ったのですが、
どうやったら、81マス全てを埋められるのか、わからなくて質問しました。

わかりにくい説明でもうしわけありません。

すけ

Re:C言語で数独の問題をつくる

#4

投稿記事 by すけ » 17年前

問題作成プログラムを検索で見つけたのですが、コードを理解できません。

実行すると、問題(全て埋まった状態)が無限に出続けます。

これを1回で止めるにはどうしたら良いですか?

できればコードの意味も説明していただけると嬉しいです。

宜しくお願いします。

<pre>
#include <stdio.h>

int a[81],c[10],j,k;


o()
{
for(j=80;~j;j--)for(k=80;k>j;k--)if((j/9==k/9||j%9==k%9||(j/27==k/27&&j%9/3==k%9/3))&&a[j]==a[k]&&a[j])return 0;return 1;

}

s(n)
{
int i=80;if(a[n])s(n+1);else if(n>80){for(;~i;i--)printf("%d%c",a,i%9?32:10);puts("\n");}else{for(i=1;i<=9;i++)(a[n]=i,o()?s(n+1):0,a[n]=0);}
}

int main(i)
{
i=80;
o();
s(0);
}
</pre>

閉鎖

“C言語何でも質問掲示板” へ戻る