第30講 数独(ナンバープレイス)問題解決ソフトVer.1の制作
(数独(ナンバープレイス)問題作成ソフトに挑戦する人は☆☆)
第16話 数独(ナンバープレイス)問題解決ソフトVer.1の完成
コード変更部分
                     ・
                     ・
                     ・
         void f(char g){
           if(s==2)return;
           char 
x,y;
           x=g%9;
           y=g/9;
           char h,i,j,k,k1,k2,ii,iii;
           if(a[y][x]>0){
             if(g+1<81){
               f(g+1);
             }
             else{
               k1=0;
               for(i=0;i<13;i++){
                 if(i%4==0){
                   k1++;
                   for(j=0;j<13;j++)dataGridView1[j,i+14]->Value=L"*";
                 }
                 if(i%4>0){
                   k2=0;
                   for(j=0;j<13;j++){
                     if(j%4==0){
                       dataGridView1[j,i+14]->Value=L"*";
                       k2++;
                     }
                     if(j%4>0){
                       dataGridView1[j,i+14]->Value=a[i-k1][j-k2];
                     }
                   }
                 }
               }
               s++;
               if(s==2)return;
             }
           }
           if(a[y][x]==0){
             ii=rand()%9;
             for(i=1;i<10;i++){
               iii=(i+ii)%9+1;
               h=1; 
               if(x>0){
                 for(j=0;j<x;j++){
                   if(a[y][j]==iii){
                     h=0;
                     break;
                   }
                 }
               }
               if(h==1){
                 if(x+1<8){
                   for(j=x+1;j<9;j++){
                     if(a[y][j]==iii){
                       h=0;
                       break;
                     }
                   }
                 }
               }
               if(h==1){
                 if(y>0){
                   for(j=0;j<y;j++){
                     if(a[j][x]==iii){
                       h=0;
                       break;
                     }
                   }
                 }
               }
               if(h==1){
                 if(y+1<8){
                   for(j=y+1;j<9;j++){
                     if(a[j][x]==iii){
                       h=0;
                       break;
                     }
                   }
                 }
               }
               if(h==1){
                 for(j=0;j<3;j++){
                   if(j!=ya){
                     for(k=0;k<3;k++){
                       if(k!=xa){
                         if(a[3*ys+j][3*xs+k]>0){
                           if(a[3*ys+j][3*xs+k]==iii){
                             h=0;
                             break; 
                           }
                         }
                       }
                     }
                     if(h==0)break;
                   }
                 }
               }
               if(h==1){
                 a[y][x]=iii;
                 if(g+1<81){
                   f(g+1);
                 }
                 else{
                   k1=0;
                   for(i=0;i<13;i++){
                     if(i%4==0){
                       k1++;
                       for(j=0;j<13;j++)dataGridView1[j,i+14]->Value=L"*";
                     }
                     if(i%4>0){
                       k2=0;
                       for(j=0;j<13;j++){
                         if(j%4==0){
                           dataGridView1[j,i+14]->Value=L"*";
                           k2++;
                         }
                         if(j%4>0){
                           dataGridView1[j,i+14]->Value=a[i-k1][j-k2];
                         }
                       }
                     }
                   }
                   s++;
                   if(s==2)return;
                 }
                 a[y][x]=0;
               }
             }
           }
         }
                     ・
                     ・
                     ・
解説
iをiii(=(ii+i)%9+1さらにiiはrand()%9で9未満のランダムな正の整数)に変更するだけで、

変更前にには1時間かけても解けなかった問題が、なんと0.004秒程度で解けてしまいました。
プログラムとは、本当に面白いものです。
ほんのちょっとした小改良で、3600÷0.004=9000000倍の速さになってしまいました。
実験を途中で打ち切ってしまいましたから、改良前は1時間と仮定してです。
実際には、1時間では解けないでしょうから、それ以上でしょう。
900万倍以上の速さになったのです。
ですが、今度は
の方の問題を解くのに52秒も要してしまいました。
22秒から52秒になってしまったのです。
もちろん、rand();を無駄打ちしたり、srand(0);によってシード値を変更すればもっと短い時間で出来るようになるでしょう。
シード値とは、srand(・);の括弧内の数値です。シード値を変えると、乱数系列自体が変わります。
後で数独(ナンバープレイス)問題作成ソフトの制作に挑戦しますが、シード値を変更しないと毎回同じ問題を作ってしまいます。
毎回異なる問題を作らせるためには、srand(static_cast<unsigned int>(time(0)));とすればよいのです。
static_cast<unsigned int>(time(0))は現在の時間を、整数に変更したものです。
実行ボタンを押すタイミングは毎回ずれますから、決して同じ問題を作ってしまうことはありません。
同じ問題を作ってしまう確率は1/1京(兆の1万倍)より遙かに小さいので、実質0です。
シード値を変更すれば、
が0.001秒以内で解けるようになる可能性はありますが、
すべての問題に対して、0.001秒以内で解けるようにするためには、そのような小手先の変更ではだめです。
どんな問題でも0.001秒以内で解けるソフトを作るのが目的です。
したがって、抜本的な改良が必要になってきます。
Verの変更が必要なわけです。
Ver.2では、問題全体構造解析を付け加え、そして問題全体構造解析に基づいた番号付け変更を行います。
Ver.1では、
| * | 0 | 1 | 2 | 3 | 4 | * | 5 | 6 | 
| 7 | 8 | * | * | 9 | * | 10 | 11 | 12 | 
| 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 
| 22 | 23 | 24 | 25 | 26 | * | 27 | 28 | 29 | 
| 30 | 31 | * | 32 | 33 | 34 | 35 | 36 | * | 
| 37 | 38 | 39 | 40 | * | * | 41 | * | 42 | 
| 43 | 44 | 45 | * | 46 | 47 | 48 | * | * | 
| * | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 
| * | 57 | 58 | * | 59 | 60 | 61 | 62 | 63 | 
の順にセルに値を入れていっています。これだと20秒以上かかってしまうわけですが、問題全体構造解析を行い、
入力順番を次にのように変更すると
| * | 48 | 21 | 1 | 22 | 7 | * | 23 | 24 | 
| 2 | 25 | * | * | 26 | * | 27 | 8 | 28 | 
| 29 | 59 | 49 | 30 | 50 | 31 | 63 | 51 | 52 | 
| 32 | 60 | 53 | 3 | 54 | * | 33 | 55 | 34 | 
| 9 | 61 | * | 0 | 10 | 11 | 35 | 56 | * | 
| 12 | 36 | 13 | 4 | * | * | 37 | * | 14 | 
| 5 | 15 | 16 | * | 17 | 6 | 38 | * | * | 
| * | 62 | 39 | 40 | 41 | 18 | 42 | 43 | 57 | 
| * | 58 | 19 | * | 44 | 20 | 45 | 46 | 47 | 
1秒もかからず解けるようになります。問題全体構造解析とは、次のものです。
| * | 6 | 5 | 3 | 5 | 4 | * | 5 | 5 | 
| 3 | 5 | * | * | 5 | * | 5 | 4 | 5 | 
| 5 | 7 | 6 | 5 | 6 | 5 | 8 | 6 | 6 | 
| 5 | 7 | 6 | 3 | 6 | * | 5 | 6 | 5 | 
| 4 | 7 | * | 1 | 4 | 4 | 5 | 6 | * | 
| 4 | 5 | 4 | 3 | * | * | 5 | * | 4 | 
| 3 | 4 | 4 | * | 4 | 3 | 5 | * | * | 
| * | 7 | 5 | 5 | 5 | 4 | 5 | 5 | 6 | 
| * | 6 | 4 | * | 5 | 4 | 5 | 5 | 5 | 
いったいこれは何を意味するのでしょうか。
第15話へ 第31講第1話へ

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual 
Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)