第19講 座標の工夫による魔方陣自動生成ソフトの高速化

第6話 コード解説その1
     if(s==n-1 && t==n-1){
        w=0;
        for(j=0;j<n;j++)w=w+x[j][j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
     if(s==n-1 && t==0){
        w=0;
        for(j=0;j<n;j++)w=w+x[j][n-1-j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
     if(s==0 && t==n-2){
        w=0;
        for(j=0;j<n;j++)w+=x[s][j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
     if(s==n-2 && t==0){
        w=0;
        for(j=0;j<n;j++)w+=x[j][t];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
     if(s>0 && s<n-1 && t==n-1){
        w=0;
        for(j=0;j<n;j++)w+=x[s][j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
     if(s==n-1 && t>0 && t<n-1){
        w=0;
        for(j=0;j<n;j++)w+=x[j][t];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
の解説
     if(s==n-1 && t==n-1){
        w=0;
        for(j=0;j<n;j++)w=w+x[j][j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
を先頭に持ってきた理由は、番号付け替えによって

10 11
12 13
14 15


4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24

一番最初に対象となるすべてのセルに数字が埋まるからです。
n=4のときすなわち4次魔方陣のとき、n-1は3ですから、
s==n-1 && t==n-1はs==
3 && t==3
となり、

のセルを示していることが分かります。


同様に、 n=5のときすなわち5次魔方陣のとき、n-1は4ですから、
s==n-1 && t==n-1はs==
4 && t==4
となり、

のセルを示していることが分かります。


ですから、対角線のセルに数字がすべて埋まっていますよね。
なので、
        w=0;
        for(j=0;j<n;j++)w=w+x[j][j];
        if(w!=n*(n*n+1)/2)goto tobi;
によって、対角線の合計がn*(n*n+1)/2になるかどうかを検査しているわけです。
n=4のときは、n*(n*n+1)/2=4×(4×4+1)/2=34
ですし、

n=5のときは、n*(n*n+1)/2=5×(5×5+1)/2=65
で、それぞれ4次魔方陣と5次魔方陣の行・列・行の合計です。

     if(s==n-1 && t==0){
        w=0;
        for(j=0;j<n;j++)w=w+x[j][n-1-j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
が2番目に来る理由はお分かりですね。

10 11
12 13
14 15


4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24

n=4のときすなわち4次魔方陣のとき、n-1は3ですから、
s==n-1 && t==0はs==
3 && t==0
となり、

のセルの場合になります。


同様に、 n=5のときすなわち5次魔方陣のとき、n-1は4ですから、
s==n-1 && t==0はs==4 && t==0
となり、

のセルの場合になり、

逆対角線のすべてのセルが埋まっていることになります。

次の
     if(s==0 && t==n-2){
        w=0;
        for(j=0;j<n;j++)w+=x[s][j];
        if(w!=n*(n*n+1)/2)goto tobi;
     }
はどういう意味でしょうか。

10 11
12 13
14 15


4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24

4次魔方陣では9のセル、5次魔方陣では11のセルに数字が埋まったときに、
1行目のすべてのセルに数字が埋まったことになります。
それぞれのセル(
のセル)はx[0][n-2]に対応しています。

n=4のときすなわち4次魔方陣のとき、n-2は2ですから、
s==0 && t==n-2はs==0 && t==2
となり、

のセルになりますし、

n=5のときすなわち5次魔方陣のとき、n-2は3ですから、
s==0 && t==n-2はs==0 && t==3
となり、

11

のセルに対応してますよね。
ですから、4次魔方陣の場合も5次魔方陣の場合も
1行目のセルが全部埋まったことになるので、
        w=0;
        for(j=0;j<n;j++)w+=x[s][j];
        if(w!=n*(n*n+1)/2)goto tobi;
によって、行合計がn*(n*n+1)/2になっているかどうかを確認しているわけす。

少し長くなりましたので、続きは次話で解説します。



第5話へ 第7話へ

a

eclipse c++ 入門講義第1部へ

魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ