マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第10章 関数の再帰的使用によって魔方陣を自動生成する

第6話 仮屋崎さんの天才的方法解説の解説その1=第1の要点



void 2次座標生成() {//y横座標とx縦座標生成

    int i, j, c;

    for (i = 0; i < n; i++) {

        for (j = 0; j < n; j++) {

            a[i][j] = -1;

        }

    }

    for (i = 0; i < n; i++) {

        a[i][i] = i;

    }

    c = n - 1;

    for (i = 0; i < n; i++) {

        if (a[i][n - 1 - i] == -1) {

            c++;

            a[i][n - 1 - i] = c;

        }

    }

    for (i = 0; i < n; i++) {

        for (j = 0; j < n; j++) {

            if (a[i][j] == -1) {

                c++;

                a[i][j] = c;

            }

        }

    }

    for (i = 0; i < n; i++) {

        for (j = 0; j < n; j++) {

            x[a[i][j]] = j;

            y[a[i][j]] = i;

        }

    }

}
さて、次話を元に戻しましょう。

偶数次では対角線と逆対角線が中央で交差するのに対して、

奇数次では中央で交差するのに、

なぜ一括して扱えるのか、という問題に戻ります。


話の味噌は

    for (i = 0; i < n; i++) {

        for (j = 0; j < n; j++) {

            a[i][j] = -1;

        }

    }

にあります。

実はこの6行の役割はただ一点にあります。

偶数次・・・中央で交差しない

奇数次・・・中央で交差する

に対応するという一点です。

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            a[i][j] = -1;
        }
    }
    for (i = 0; i < n; i++) {
        a[i][i] = i;
    }
    c = n - 1;
    for (i = 0; i < n; i++) {
        if (a[i][n - 1 - i] == -1) {
            c++;
            a[i][n - 1 - i] = c;
        }
    }

  2が7に上書きされない理由は何ですか。

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            a[i][j] = -1;
        }
    }
によって

となります。

そして、

    for (i = 0; i < n; i++) {
        a[i][i] = i;
    }
によって

となります。

    c = n - 1;
    for (i = 0; i < n; i++) {
        if (a[i][n - 1 - i] == -1) {
            c++;
            a[i][n - 1 - i] = c;
        }
    }
によって

という局面を迎えます。

    if (a[i][n - 1 - i] == -1) {
            c++;
            a[i][n - 1 - i] = c;
        }
赤に注目です。-1ときだけc++;を実行して代入せよとなっています。

ところが、中央には2が入っているので

    if (a[i][n - 1 - i] == -1) {
            c++;
            a[i][n - 1 - i] = c;
        }
は実行されません。

というわけで2が7に上書きされずに、番号づけは最後までうまくいくわけです。


以上が仮屋崎さんのコードを理解するために必要なことの第1の要点です。






第10章第5話へ 第10章7話へ

本講義トップへ