第19講 数独(ナンプレ)解答自動生成アプリ
第4話 行と列の重複を許さないソフト
実行画面
1 7 5 2 8 6 9 4 3
6 9 8 5 1 2 4 3 7
3 1 4 8 7 9 6 2 5
4 2 1 7 6 3 5 8 9
7 3 6 4 2 5 1 9 8
9 4 2 6 3 7 8 5 1
5 6 9 3 4 8 7 1 2
8 5 7 1 9 4 2 6 3
1 8 3 2 5 6 9 7 4
2 7 5 9 8 1 3 4 6
6 9 8 5 1 2 4 3 7
3 1 4 8 7 9 6 2 5
4 2 1 7 6 3 5 8 9
7 3 6 4 2 5 1 9 8
9 4 2 6 3 7 8 5 1
5 6 9 3 4 8 7 1 2
8 5 7 1 9 4 2 6 3
2 7 5 9 8 1 3 4 6
1 8 3 2 5 6 9 7 4
生成された数独(ナンプレ)は10個です。
数独(ナンプレ)生成にかかった時間は0.000000秒です。
を実現するソフト例
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void f(int g); //数独(ナンプレ)を作り出す社員
void hy(); //出来た数独(ナンプレ)をコンソールに表示させる社員
void zy(); //座標を作成する社員
int cn,n;
int m[10][10]; //少し大きめに配列要素数を取っておく
int y[100],x[100];
int main(){
clock_t hj,ow;
srand(1);
n=9;
hj=clock();
zy();
f(0);
ow=clock();
printf("生成された数独(ナンプレ)は%d個です。\n",cn);
printf("数独(ナンプレ)生成にかかった時間は%f秒です。\n",(double)(ow - hj) / CLOCKS_PER_SEC);
}
void zy(){ //座標を作成する社員
int i;
for(i=0;i<n*n;i++){
y[i]=i/n;
x[i]=i%n;
}
}
void f(int g){ //数独(ナンプレ)を作り出す社員
int i,j,ih;
ih=rand()%n;
for(i=0;i<n;i++){
for(j=0;j<x[g];j++){
if(((ih+i)%n)+1==m[y[g]][j])goto tobi;
}
for(j=0;j<y[g];j++){
if(((ih+i)%n)+1==m[j][x[g]])goto tobi;
}
m[y[g]][x[g]]=((ih+i)%n)+1;
if(g+1<n*n){
f(g+1);
if(cn==10)return;
}
else{
hy();
cn++;
if(cn==10)return;
}
tobi:;
}
}
void hy(){ //出来た数独(ナンプレ)をコンソールに表示させる社員
int i,j;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf("%d ",m[i][j]);
}
printf("\n");
}
printf("\n");
}
行と列の重複を許さないソフト
最後はブロックの条件も付け加えて、
数独(ナンプレ)解答自動生成の一応の完成です。
一応としたのは、まだ境界線を入れていないからです。
ブロックの条件が1番難しいですね。
詳しくは、第19講第8話で説明しますが、
ここでも簡単に説明しましょう。
ブロック内の重複検査はどのようにしたら出来るのでしょうか。
課題は、座標(4,8)から座標(3,6)をいかに作り出すかです。
ブロックの途中の座標から、
ブロックの先頭座標をいかに作り出すかです。
これが出来れば、2次元for文によって重複検査が出来ます。
4から3を作り出すことも、
8から6を作り出すことも、
同じ方法で出来ます。
それは、
i/3とj/3が小数部分を切り捨てた値をとること、
すなわち、それぞれが3で割ったときの商をとることを利用する、
という方法です。
答を、ずばり30行下に書きましょう。
答
座標(4,8)から座標(3,6)を作り出す方法
3*(4/3)=3
3*(8/3)=6
一般的には、
(3*(i/3),3*j(j/3))です。
2次元for文は・・・
for(j=3*(y[g]/3);j・・y[g];j++){
for(k=3*(x[g]/3);k・x[g];k++){
・・・
}
}
という形になります。
j・・y[g]とk・x[g]で省略した・には1つに対して1つの記号が入ります。
縦座標と横座標は働きが同じはずなのに、
どうして、両者が違っているか考えて下さい。
さて、
2 5 3 1 4 7 9 6 8
6 9 8 5 1 2 4 3 7
3 1 4 8 7 9 6 2 5
4 2 5 7 6 3 8 9 1
7 3 6 4 2 5 1 8 9
9 4 1 6 3 8 5 7 2
5 6 2 9 8 1 7 4 3
1 8 7 3 9 6 2 5 4
8 7 3 2 5 4 9 1 6
2 5 9 1 4 7 3 6 8
6 9 8 5 1 2 4 3 7
3 1 4 8 7 9 6 2 5
4 2 5 7 6 3 8 9 1
7 3 6 4 2 5 1 8 9
9 4 1 6 3 8 5 7 2
5 6 2 9 8 1 7 4 3
2 8 7 1 9 4 3 5 6
8 7 9 3 5 6 2 1 4
1 5 3 2 4 7 9 6 8
生成された数独(ナンプレ)は10個です。
数独(ナンプレ)生成にかかった時間は0.000000秒です。
を実現させましょう。
第3話へ 第5話へ
初心者のための excel 2016 マクロ VBA 入門講義 基礎から応用まで
vc++ c言語 c++ 入門 初心者 基礎から応用まで
eclipse c++ 入門
魔方陣 数独(ナンプレ)で学ぶ VBA 入門
数独(ナンプレ)のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
本サイトトップへ