第31講 数独(ナンバープレイス)問題解決ソフトVer.2の制作
(数独(ナンバープレイス)問題作成ソフトに挑戦する人は☆☆)


第9話 
問題全体構造解析に基づく入力順を構築するコード例2
  private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
                   ・
                   ・
                   ・         
           char k1=0,k2;
           
cn=0;  //動作不良の原因のひとつがこれを落としたことです。
                   ・
                   ・
                   ・
          }
  private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
                   ・
                   ・
                   ・
           s=0;
           zentaikouzoukaiseki();
           for(i=0;i<15;i++)dataGridView1->Rows->Add();
          
nyuryokujyunkoutiku();
           
//f(0);   //問題全体構造解析がうまくいっているか確認するためいったん外しておく
           DateTime^ ow=DateTime::Now; //終了時間
           TimeSpan sa=ow->Subtract(*hj); //経過時間の計算
           dataGridView1[30,25]->Value=L"解答作成時間";
           dataGridView1[30,26]->Value=sa.TotalSeconds.ToString();
          
/*    //問題全体構造解析がうまくいっているか確認するためいったん外しておく
           if(s==2)dataGridView1[30,27]->Value=L"解答が複数存在する";
           if(s==2)dataGridView1[30,14]->Value=L"不適切な問題です。";
           if(s==0)dataGridView1[30,27]->Value=L"解答が存在しない";
           if(s==0)dataGridView1[30,14]->Value=L"不適切な問題です。";
           */       

       
 }
                   ・
                   ・
                   ・
        void nyuryokujyunkoutiku(char g){
          char i,j,k,h,
jh,ih;
          char min=100;
          k=0;
          for(i=0;i<9;i++){
            for(j=0;j<9;j++){
              if(a[i][j]==0){
                h=1;
                if(g>0){
                  for(k=0;k<g;k++){
                    
if(j==zx[k] && i==zy[k]){  //この辺の記述にも問題がありました。以降赤が訂正箇所。
                      h=0;
                      break;
                    }
                  }
                }
                if(h==1){
                  if(b[i][j]<min){
                    min=b[i][j];
                    ih=i;
                    jh=j;
                  }
                }
              }
            } 
          }
          
zx[g]=jh;
          zy[g]=ih;

          if(g+1<cn){
            nyuryokujyunkoutiku(g+1);
          }
          else{
            for(i=0;i<4;i++)for(j=0;j<13;j++)dataGridView1[j,4*i+28]->Value=L"*";
            for(i=0;i<4;i++)for(j=0;j<13;j++)dataGridView1[4*i,j+28]->Value=L"*";
            for(i=0;i<cn;i++){
            if(a[zy[i]][zx[i]]==0){
              if(zx[i]<3)xx=zx[i];
              if(zx[i]>2 && zx[i]<6)xx=zx[i]+1;
              if(zx[i]>5 && zx[i]<9)xx=zx[i]+2;
              if(zy[i]<3)yy=zy[i];
              if(zy[i]>2 && zy[i]<6)yy=zy[i]+1;
              if(zy[i]>5 && zy[i]<9)yy=zy[i]+2;
              dataGridView1[xx+1,yy+29]->Value=i;
            }
             for(i=0;i<9;i++){
              for(j=0;j<9;j++){
                if(a[i][j]>0){
                  if(j<3)xx=j;
                  if(j>2 && j<6)xx=j+1;
                  if(j>5 && j<9)xx=j+2;
                  if(i<3)yy=i;
                  if(i>2 && i<6)yy=i+1;
                  if(i>5 && i<9)yy=i+2;
                  dataGridView1[xx+1,yy+29]->Value=L"/";
                }
              }
            }

          }
        }
      }
                   ・
                   ・
                   ・

こちらは難解です。難解な割には、実行速度は変わりません。しかし、将来のバージョンのために必要です。
このVer.2は、最初だけ問題構造解析とそれに基づく入力順の構築をしますが、
実は、リスト構造とそれに基づく入力順はセルに数字を入れる度に変わっていきます。
したがって、初回だけでなく毎回構造分析と入力順構築が必要です。
しかし、毎回全体構造解析をしていたのでは時間に無駄ですし、
実は入力順は、今回のように全体を構築する必要はありません。
f(g)のg番目だけの入力順が決まっていればよいのです。
数字を入れたことによって影響を受ける部分だけの部分構造解析
c++ 
とその回だけの入力順構築が出来れば、問題を解く速度は著しく改善されます。
今回の難解なコードはその回だけの入力順構築に使うことが出来ます。

尚、コード例1の解説は第11話で、コード例2の解説は第12話と第13話で行います。
では第10話は何でしょうか。
そうです。
Ver.2の完成コードを載せることが第10話の任務です。
皆さん、コード例を見る前に数独問題解決ソフトVer.2を完成させましょう。

第8話へ 第10話へ


戻る

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