#pragma warning(disable: 4996)

 

#include<iostream>

 

#include<stdlib.h> /*callocrand,srandを使うのに必要*/

 

#include<ctime>

 

#include<process.h>

 

#include<conio.h> //while (!_kbhit()); を使うためのお呪い。

 

#include <math.h>

 

#include <cmath>

 

#include<process.h>

 

#include <iomanip>

 

#include <stdio.h>

 

#include <stdlib.h>

 

#include <vector>

 

using namespace std;

 

const size_t th = 120;

 

void 問題生成関数(size_t g, size_t a);

 

void 問題生成検証関数(size_t g, size_t a);

 

void 非対称配列関数(size_t a);

 

void 左右対称配列関数(size_t a);

 

void 上下対称配列関数(size_t a);

 

void 点対称配列関数(size_t a);

 

void 左右上下対称配列関数(size_t a);//対称対称かつ点対称配列でもある。

 

void ハート型配列関数(size_t a);

 

void 局所解析関数(size_t s, size_t t, size_t a);

 

void 代入関数(size_t a);

 

char 継続 = 1;

 

size_t* どのスレッドが発見したか示す変数 = (size_t*)calloc(th, sizeof(size_t));

 

unsigned シード値 = (unsigned)time(NULL);

 

void 変身の術関数(void* a);

 

void 初期化0(size_t a);

 

void 初期化1(size_t a);

 

void 初期化2(size_t a);

 

void 入力順決定関数(size_t g, size_t a);

 

size_t 検証関数(size_t a);

 

size_t 全体リスト構造解析関数(size_t a);

 

void 解答作成関数(size_t a);

 

void 色塗り関数(size_t a);

 

void 0収集関数(size_t a);

 

void ライン排除関数(size_t a);

 

void 相補確定関数(size_t a);

 

void リスト法関数(size_t a);

 

void ライン行排除関数(size_t a);

 

void ライン列排除関数(size_t a);

 

void ラインブロック排除関数(size_t a);

 

void 相補確定とそれによる行排除関数(size_t a);

 

void 相補確定とそれによる列排除関数(size_t a);

 

void 相補確定とそれによるブロック排除関数(size_t a);

 

void 三対三確定および排除行関数(size_t a);

 

void 三対三確定および排除列関数(size_t a);

 

void 三対三確定および排除ブロック関数(size_t a);

 

void 三対三確定および排除関数(size_t a);

 

void 四対四確定および排除行関数(size_t a);

 

void 四対四確定および排除列関数(size_t a);

 

void 四対四確定および排除ブロック関数(size_t a);

 

void 四対四確定および排除関数(size_t a);

 

void 五対五確定および排除行関数(size_t a);

 

void 五対五確定および排除列関数(size_t a);

 

void 五対五確定および排除ブロック関数(size_t a);

 

void 五対五確定および排除関数(size_t a);

 

void 六対六確定および排除行関数(size_t a);

 

void 六対六確定および排除列関数(size_t a);

 

void 六対六確定および排除ブロック関数(size_t a);

 

void 六対六確定および排除関数(size_t a);

 

void 七対七確定および排除行関数(size_t a);

 

void 七対七確定および排除列関数(size_t a);

 

void 七対七確定および排除ブロック関数(size_t a);

 

void 七対七確定および排除関数(size_t a);

 

void 八対八確定および排除行関数(size_t a);

 

void 八対八確定および排除列関数(size_t a);

 

void 八対八確定および排除ブロック関数(size_t a);

 

void 八対八確定および排除関数(size_t a);

 

void #排除関数(size_t a);

 

const size_t RN = 5;

 

const size_t N = RN * RN;

 

const size_t N2 = N * N;

 

void 表示関数3(size_t a);

 

void 表示関数4(size_t a);

 

void 問題表示関数(size_t a);

 

void 解答表示関数(size_t a);

 

void 解答表示関数1(size_t a, size_t M[N][N]);

 

size_t m[th][N][N];//問題

 

size_t mx[th][N][N];//座標(N,N)候補リスト数

 

size_t wb[th][N][N][N];

 

//スレッドNにおける座標(N,N)の色塗り 色は入力文字に対応9×9数独なら1から9

 

size_t rlst[th][N][N][N];

 

//スレッドNにおける座標(N,N)の候補数字リスト

 

vector<int> 行値0番号集合[25];//行の空欄番号の集合

 

vector<int> 列値0番号集合[25];//列の空欄番号の集合

 

vector<int> ブロック値0番号集合[25];//ブロックの空欄番号の集合

 

size_t y[th][N2], x[th][N2];//各スレッドにおいて入力順決定関数を使うときの座標

 

size_t yy[th][N2], xx[th][N2];

 

//9×9を例にとると01,・・・,80各セル番号を等間隔に飛ぶ座標

 

//スタート地点も飛ぶ間隔も疑似乱数によってスレッド毎にランダムに与えられる。

 

size_t cm[th][N][N];//問題

 

size_t ヒント数, 空欄数[th], cn[th];//各スレッドで解答が発見されると1になる。

 

size_t S;//左右対称型などのタイプを示す変数

 

clock_t hj1[th], ow1[th];

 

//各スレッドの数独を解き始める時間と解き終わったときの時間

 

clock_t 初期配置数 = 0;

 

int  main() {

 

    size_t ii[th];

 

    ヒント数 = 325;

 

    clock_t hj, ow;//数独

 

    cout << "数独のタイプ:" << N << "×" << N << endl;

 

    cout << "ヒント数 = " << ヒント数 << endl;

 

    cout << "空欄数 = " << N * N - ヒント数 << endl;

 

    cout << "スレッド数 = " << th << endl;

 

    hj = clock();

 

    シード値 = (unsigned)time(NULL);

 

    継続 = 1;

 

    for (size_t i = 1; i < th; i += 1) {

 

        ii[i] = i;

 

        _beginthread(変身の術関数, 0, &ii[i]); //新しいスレッドを起動して、そのスレッド上で関数問題生成関数を働かせなさいの命令

 

    }

 

    srand(シード値);

 

    while (1) {

 

        初期化0(0);

 

        size_t 選択変数 = 4;

 

        点対称配列関数(0);

 

        /*size_t 選択変数;

 

        if (ヒント数 == 20)選択変数 = rand() % 5; else 選択変数 = rand() % 6;

 

        if (選択変数 == 0) 左右対称配列関数(0);

 

        if (選択変数 == 1) 上下対称配列関数(0);

 

        if (選択変数 == 2) 点対称配列関数(0);

 

        if (選択変数 == 3) 左右上下対称配列関数(0);

 

        if (選択変数 == 4) 非対称配列関数(0);

 

        if (選択変数 == 5) ハート型配列関数(0);*/

 

        if (継続 == 0)break;

 

        cn[0] = 0;

 

        問題生成関数(0, 0);

 

        if (継続 == 0)break;

 

        色塗り関数(0);

 

        if (継続 == 0)break;

 

        0収集関数(0);

 

        解答作成関数(0);

 

        if (cn[0] == 1) {

 

            ow1[0] = clock();

 

            どのスレッドが発見したか示す変数[0] = 1;

 

            継続 = 0;

 

            goto tobi0;

 

        }

 

    }

 

tobi0:;

 

    while (継続);

 

    size_t ik;

 

    for (size_t i = 0; i < th; i++)if (どのスレッドが発見したか示す変数[i] == 1) { ik = i; break; }

 

    //数独を見つけたスレッドを特定した。

 

    size_t M[N][N];//解答

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            M[i][j] = m[ik][i][j];

 

        }

 

    }

 

    問題表示関数(ik); 解答表示関数(ik);

 

    FILE* fp;

 

    /*ファイル(save.csv)に書き込む*/

 

    if ((fp = fopen("a-2026-09-05-325-025.csv", "w")) != NULL) {

 

        for (size_t i = 0; i < N; i++) {

 

            for (size_t j = 0; j < N; j++) {

 

                fprintf(fp, "%d,\n", cm[ik][i][j]);//問題

 

            }

 

        }

 

        for (size_t i = 0; i < N; i++) {

 

            for (size_t j = 0; j < N; j++) {

 

                /*カンマで区切ることでCSVファイルとする*/

 

                fprintf(fp, "%d,\n", m[ik][i][j]);//解答

 

            }

 

        }

 

    }

 

    /*忘れずに閉じる*/

 

    fclose(fp);

 

    ow = clock();

 

    cout << "数独解法時間は" << (double)(ow1[ik] - hj1[ik]) / CLOCKS_PER_SEC << "秒です。" << endl;

 

    cout << "数独生成時間は" << (double)(ow - hj) / CLOCKS_PER_SEC << "秒です。" << endl;

 

    cout << "プロジェクト終了" << endl;

 

    while (!_kbhit()); //待機させるための命令

 

    return 0;

 

}

 

void 変身の術関数(void* aa) {

 

    size_t a = *(size_t*)aa;

 

    srand(シード値 + 104729 * (a + 1));

 

    while (1) {

 

        初期化0(a);

 

        size_t 選択変数 = 4;

 

        点対称配列関数(a);

 

        /*size_t 選択変数;

 

        if (ヒント数 == 20)選択変数 = rand() % 5; else 選択変数 = rand() % 6;

 

        if (選択変数 == 0) 左右対称配列関数(a);

 

        if (選択変数 == 1) 上下対称配列関数(a);

 

        if (選択変数 == 2) 点対称配列関数(a);

 

        if (選択変数 == 3) 左右上下対称配列関数(a);

 

        if (選択変数 == 4) 非対称配列関数(a);

 

        if (選択変数 == 5) ハート型配列関数(a);*/

 

        cn[a] = 0;

 

        問題生成関数(0, a);

 

        if (継続 == 0)return;

 

        色塗り関数(a);

 

        if (継続 == 0)return;

 

        空欄数[a] = N2 - ヒント数;

 

        hj1[a] = clock();

 

        0収集関数(0);

 

        解答作成関数(a);

 

        if (cn[a] == 1) {

 

            ow1[a] = clock();

 

            どのスレッドが発見したか示す変数[a] = 1;

 

            継続 = 0;

 

            return;

 

        }

 

    }

 

}

 

void 表示関数3(size_t a) {

 

    for (int i = 0; i < N + 1; i++) {

 

        if (i % RN == 0) {

 

            cout << " ";

 

            for (int j = 0; j < N + 3; j++) {

 

                cout << "- ";

 

            }

 

            cout << " ";

 

            cout << endl;

 

        }

 

        if (i == N)break;

 

        for (int j = 0; j < N + 1; j++) {

 

            if (j % RN == 0) {

 

                cout << "| ";

 

            }

 

            if (j < N) {

 

                if (cm[a][i][j] == 0)cout << "* "; else cout << cm[a][i][j] << " ";

 

                //問題

 

            }

 

        }

 

        cout << endl;

 

    }

 

    for (int i = 0; i < N + 1; i++) {

 

        if (i % RN == 0) {

 

            cout << " ";

 

            for (int j = 0; j < N + 3; j++) {

 

                cout << "- ";

 

            }

 

            cout << " ";

 

            cout << endl;

 

        }

 

        if (i == N)break;

 

        for (int j = 0; j < N + 1; j++) {

 

            if (j % RN == 0) {

 

                cout << "| ";

 

            }

 

            if (j < N) {

 

                if (m[a][i][j] == 0)cout << "* "; else cout << m[a][i][j] << " ";//問題

 

            }

 

        }

 

        cout << endl;

 

    }

 

}

 

void 表示関数4(size_t a) {

 

    for (int i = 0; i < N + 1; i++) {

 

        if (i % RN == 0) {

 

            cout << " ";

 

            for (int j = 0; j < N + 27; j++) {

 

                cout << "- ";

 

            }

 

            cout << " ";

 

            cout << endl;

 

        }

 

        if (i == N)break;

 

        for (int j = 0; j < N + 1; j++) {

 

            if (j % RN == 0) {

 

                cout << "|";

 

            }

 

            if (j < N) {

 

                if (m[a][i][j] == 0) {

 

                    cout << " ** ";//問題

 

                }

 

                if (m[a][i][j] > 0 && m[a][i][j] < 10) {

 

                    cout << "  " << m[a][i][j] << " ";//問題

 

                }

 

                if (m[a][i][j] >= 10) {

 

                    cout << " " << m[a][i][j] << " ";//問題

 

                }

 

            }

 

        }

 

        cout << endl;

 

    }

 

    //for (int i = 0; i < N + 1; i++) {

 

    //    if (i % RN == 0) {

 

    //        cout << " ";

 

    //        for (int j = 0; j < N + 27; j++) {

 

    //            cout << "- ";

 

    //        }

 

    //        cout << " ";

 

    //        cout << endl;

 

    //    }

 

    //    if (i == N)break;

 

    //    for (int j = 0; j < N + 1; j++) {

 

    //        if (j % RN == 0) {

 

    //            cout << "|";

 

    //        }

 

    //        if (j < N) {

 

    //            if (cm[a][i][j] == 0) {

 

    //                cout << " ** ";//解答

 

    //            }

 

    //            if (cm[a][i][j] > 0 && cm[a][i][j] < 10) {

 

    //                cout << "  " << cm[a][i][j] << " ";//解答

 

    //            }

 

    //            if (cm[a][i][j] >= 10) {

 

    //                cout << " " << cm[a][i][j] << " ";//解答

 

    //            }

 

    //        }

 

    //    }

 

    //    cout << endl;

 

    //}

 

}

 

void 解答表示関数(size_t a) {

 

 

    for (int i = 0; i < N + 1; i++) {

 

        if (i % RN == 0) {

 

            cout << " ";

 

            for (int j = 0; j < N + 27; j++) {

 

                cout << "- ";

 

            }

 

            cout << " ";

 

            cout << endl;

 

        }

 

        if (i == N)break;

 

        for (int j = 0; j < N + 1; j++) {

 

            if (j % RN == 0) {

 

                cout << "|";

 

            }

 

            if (j < N) {

 

                if (m[a][i][j] == 0) {

 

                    cout << " ** ";//解答

 

                }

 

                if (m[a][i][j] > 0 && m[a][i][j] < 10) {

 

                    cout << "  " << m[a][i][j] << " ";//解答

 

                }

 

                if (m[a][i][j] >= 10) {

 

                    cout << " " << m[a][i][j] << " ";//解答

 

                }

 

            }

 

        }

 

        cout << endl;

 

    }

 

 

}

 

void 解答表示関数1(size_t a, size_t M[N][N]) {

 

 

    for (int i = 0; i < N + 1; i++) {

 

        if (i % RN == 0) {

 

            cout << " ";

 

            for (int j = 0; j < N + 27; j++) {

 

                cout << "- ";

 

            }

 

            cout << " ";

 

            cout << endl;

 

        }

 

        if (i == N)break;

 

        for (int j = 0; j < N + 1; j++) {

 

            if (j % RN == 0) {

 

                cout << "|";

 

            }

 

            if (j < N) {

 

                if (M[i][j] == 0) {

 

                    cout << " ** ";//解答

 

                }

 

                if (M[i][j] > 0 && M[i][j] < 10) {

 

                    cout << "  " << M[i][j] << " ";//解答

 

                }

 

                if (M[i][j] >= 10) {

 

                    cout << " " << M[i][j] << " ";//解答

 

                }

 

            }

 

        }

 

        cout << endl;

 

    }

 

 

}

 

void 問題表示関数(size_t a) {

 

    for (int i = 0; i < N + 1; i++) {

 

        if (i % RN == 0) {

 

            cout << " ";

 

            for (int j = 0; j < N + 27; j++) {

 

                cout << "- ";

 

            }

 

            cout << " ";

 

            cout << endl;

 

        }

 

        if (i == N)break;

 

        for (int j = 0; j < N + 1; j++) {

 

            if (j % RN == 0) {

 

                cout << "|";

 

            }

 

            if (j < N) {

 

                if (cm[a][i][j] == 0) {

 

                    cout << " ** ";//問題

 

                }

 

                if (cm[a][i][j] > 0 && cm[a][i][j] < 10) {

 

                    cout << "  " << cm[a][i][j] << " ";//問題

 

                }

 

                if (cm[a][i][j] >= 10) {

 

                    cout << " " << cm[a][i][j] << " ";//問題

 

                }

 

            }

 

        }

 

        cout << endl;

 

    }

 

}

 

void 解答作成関数(size_t a) {

 

    size_t i, k空欄数;

 

    /*if (全体リスト構造解析関数(a) == 1) {

 

        cn[a] = 2;

 

        return;

 

    }*/

 

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

 

        k空欄数 = 空欄数[a];

 

        ライン排除関数(a);

 

        if (cn[a] > 0) return;

 

        if (空欄数[a] == 0) {

 

            cn[a] = 1;

 

            return;

 

        }

 

        相補確定関数(a);

 

        0収集関数(a);

 

        三対三確定および排除関数(a);

 

        四対四確定および排除関数(a);

 

        五対五確定および排除関数(a);

 

        六対六確定および排除関数(a);

 

        if (ヒント数 < 213)七対七確定および排除関数(a);

 

        if (ヒント数 < 211)八対八確定および排除関数(a);

 

        #排除関数(a);

 

        if (空欄数[a] == 0) {

 

            cn[a] = 1;

 

            return;

 

        }

 

        リスト法関数(a);

 

        if (cn[a] > 0)return;

 

        if (空欄数[a] == 0) {

 

            cn[a] = 1;

 

            return;

 

        }

 

        if (k空欄数 == 空欄数[a]) {

 

            cn[a] = 0;

 

            return;

 

        }

 

    }

 

}

 

size_t 全体リスト構造解析関数(size_t a) {

 

    size_t i, j;

 

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

 

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

 

            if (m[a][i][j] == 0) {

 

                局所解析関数(i, j, a);

 

                if (mx[a][i][j] == 0) {

 

                    return(1);

 

                }

 

            }

 

        }

 

    }

 

    return(0);

 

}

 

void ライン行排除関数(size_t a) {

 

    size_t i, j, k, w, jk, kk, s, t;

 

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

 

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

 

            w = 0;

 

            for (k = 0; k < N; k++) {

 

                if (m[a][j][k] == 0) {

 

                    if (wb[a][j][k][i] == 0) {

 

                        jk = j;

 

                        kk = k;

 

                        w = w + 1;

 

                    }

 

                }

 

            }

 

            if (w == 1) {

 

                if (空欄数[a] == 0) {

 

                    cn[a] = 2;

 

                    return;

 

                }

 

                m[a][jk][kk] = i + 1;

 

                空欄数[a] = 空欄数[a] - 1;

 

                if (空欄数[a] == 0) return;

 

                for (k = 0; k < N; k++) {

 

                    if (m[a][jk][k] == 0) {

 

                        wb[a][jk][k][m[a][jk][kk] - 1] = 1;

 

                    }

 

                    if (m[a][k][kk] == 0) {

 

                        wb[a][k][kk][m[a][jk][kk] - 1] = 1;

 

                    }

 

                    s = RN * (jk / RN) + (k / RN);

 

                    t = RN * (kk / RN) + (k % RN);

 

                    if (m[a][s][t] == 0) {

 

                        wb[a][s][t][m[a][jk][kk] - 1] = 1;

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (m[a][jk][k] == 0)局所解析関数(jk, k, a);

 

                    if (m[a][k][kk] == 0) 局所解析関数(k, kk, a);

 

                    s = RN * (jk / RN) + (k / RN);

 

                    t = RN * (kk / RN) + (k % RN);

 

                    if (m[a][s][t] == 0)局所解析関数(s, t, a);

 

                }

 

            }

 

        }

 

    }

 

}

 

void ライン列排除関数(size_t a) {

 

    size_t i, j, k, w, jk, kk, s, t;

 

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

 

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

 

            w = 0;

 

            for (k = 0; k < N; k++) {

 

                if (m[a][k][j] == 0) {

 

                    if (wb[a][k][j][i] == 0) {

 

                        jk = j;

 

                        kk = k;

 

                        w = w + 1;

 

                    }

 

                }

 

            }

 

            if (w == 1) {

 

                if (空欄数[a] == 0) {

 

                    cn[a] = 2;

 

                    return;

 

                }

 

                m[a][kk][jk] = i + 1;

 

                空欄数[a] = 空欄数[a] - 1;

 

                if (空欄数[a] == 0) return;

 

                for (k = 0; k < N; k++) {

 

                    if (m[a][kk][k] == 0) {

 

                        wb[a][kk][k][m[a][kk][jk] - 1] = 1;

 

                    }

 

                    if (m[a][k][jk] == 0) {

 

                        wb[a][k][jk][m[a][kk][jk] - 1] = 1;

 

                    }

 

                    s = RN * (kk / RN) + (k / RN);

 

                    t = RN * (jk / RN) + (k % RN);

 

                    if (m[a][s][t] == 0) {

 

                        wb[a][s][t][m[a][kk][jk] - 1] = 1;

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (m[a][kk][k] == 0)局所解析関数(kk, k, a);

 

                    if (m[a][k][jk] == 0)局所解析関数(k, jk, a);

 

                    s = RN * (kk / RN) + (k / RN);//ブロック部分を動く y座標

 

                    t = RN * (jk / RN) + (k % RN);//ブロック部分を動く x座標

 

                    if (m[a][s][t] == 0)局所解析関数(s, t, a);

 

                }

 

            }

 

        }

 

    }

 

}

 

void ラインブロック排除関数(size_t a) {

 

    size_t i, j, k, w, sk, tk, s, t, s1, t1;

 

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

 

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

 

            w = 0;

 

            for (k = 0; k < N; k++) {

 

                s = RN * (j / RN) + (k / RN);

 

                t = RN * (j % RN) + (k % RN);

 

                if (m[a][s][t] == 0) {

 

                    if (wb[a][s][t][i] == 0) {

 

                        sk = s;

 

                        tk = t;

 

                        w = w + 1;

 

                    }

 

                }

 

            }

 

            if (w == 1) {

 

                if (空欄数[a] == 0) {

 

                    cn[a] = 2;

 

                    return;

 

                }

 

                m[a][sk][tk] = i + 1;

 

                空欄数[a] = 空欄数[a] - 1;

 

                if (空欄数[a] == 0) return;

 

                for (k = 0; k < N; k++) {

 

                    if (m[a][sk][k] == 0) {

 

                        wb[a][sk][k][m[a][sk][tk] - 1] = 1;

 

                    }

 

                    if (m[a][k][tk] == 0) {

 

                        wb[a][k][tk][m[a][sk][tk] - 1] = 1;

 

                    }

 

                    s1 = RN * (sk / RN) + (k / RN);

 

                    t1 = RN * (tk / RN) + (k % RN);

 

                    if (m[a][s1][t1] == 0) {

 

                        wb[a][s1][t1][m[a][sk][tk] - 1] = 1;

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (m[a][sk][k] == 0)局所解析関数(sk, k, a);

 

                    if (m[a][k][tk] == 0)局所解析関数(k, tk, a);

 

                    s1 = RN * (sk / RN) + (k / RN);

 

                    t1 = RN * (tk / RN) + (k % RN);

 

                    if (m[a][s1][t1] == 0)局所解析関数(s1, t1, a);

 

                }

 

            }

 

        }

 

    }

 

}

 

void ライン排除関数(size_t a) {

 

    ライン行排除関数(a);

 

    if (空欄数[a] == 0) {

 

        cn[a] = 1;

 

        return;

 

    }

 

    ライン列排除関数(a);

 

    if (空欄数[a] == 0) {

 

        cn[a] = 1;

 

        return;

 

    }

 

    ラインブロック排除関数(a);

 

}

 

void 相補確定とそれによる行排除関数(size_t a) {

 

    size_t i, j, k, w, onoff[N];

 

    size_t ckotae[N], l;

 

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

 

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

 

            for (k = j + 1; k < N; k++) {

 

                if (mx[a][i][j] == 2 && mx[a][i][k] == 2) {

 

                    for (l = 0; l < N; l++) {

 

                        onoff[l] = 0;

 

                    }

 

                    for (l = 0; l < 2; l++) {

 

                        onoff[rlst[a][i][j][l] - 1] = 1;

 

                        onoff[rlst[a][i][k][l] - 1] = 1;

 

                    }

 

                    w = 0;

 

                    for (l = 0; l < N; l++) {

 

                        if (onoff[l] == 1) {

 

                            ckotae[w] = l;

 

                            w = w + 1;

 

                        }

 

                    }

 

                    if (w == 2) {

 

                        for (l = 0; l < N; l++) {

 

                            if (l != j && l != k) {

 

                                if (m[a][i][l] == 0) {

 

                                    wb[a][i][l][ckotae[0]] = 1;

 

                                    wb[a][i][l][ckotae[1]] = 1;

 

                                }

 

                            }

 

                        }

 

                        for (l = 0; l < N; l++) {

 

                            if (l != j && l != k) {

 

                                if (m[a][i][l] == 0) {

 

                                    局所解析関数(i, l, a);

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 相補確定とそれによる列排除関数(size_t a) {

 

    size_t i, j, k, w, onoff[N];

 

    size_t ckotae[N], l;

 

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

 

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

 

            for (k = j + 1; k < N; k++) {

 

                if (mx[a][j][i] == 2 && mx[a][k][i] == 2) {

 

                    for (l = 0; l < N; l++) {

 

                        onoff[l] = 0;

 

                    }

 

                    for (l = 0; l < 2; l++) {

 

                        onoff[rlst[a][j][i][l] - 1] = 1;

 

                        onoff[rlst[a][k][i][l] - 1] = 1;

 

                    }

 

                    w = 0;

 

                    for (l = 0; l < N; l++) {

 

                        if (onoff[l] == 1) {

 

                            ckotae[w] = l;

 

                            w = w + 1;

 

                        }

 

                    }

 

                    if (w == 2) {

 

                        for (l = 0; l < N; l++) {

 

                            if (l != j && l != k) {

 

                                if (m[a][l][i] == 0) {

 

                                    wb[a][l][i][ckotae[0]] = 1;

 

                                    wb[a][l][i][ckotae[1]] = 1;

 

                                }

 

                            }

 

                        }

 

                        for (l = 0; l < N; l++) {

 

                            if (l != j && l != k) {

 

                                if (m[a][l][i] == 0) {

 

                                    局所解析関数(l, i, a);

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 相補確定とそれによるブロック排除関数(size_t a) {

 

    size_t i, j, k, w, onoff[N], s1, s2, t1, t2, s3, t3, s4, t4;;

 

    size_t ckotae[N], l;

 

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

 

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

 

            s1 = RN * (i / RN) + (j / RN);

 

            t1 = RN * (i % RN) + (j % RN);

 

            for (k = j + 1; k < N; k++) {

 

                s2 = RN * (i / RN) + (k / RN);

 

                t2 = RN * (i % RN) + (k % RN);

 

                if (mx[a][s1][t1] == 2 && mx[a][s2][t2] == 2) {

 

                    for (l = 0; l < N; l++) {

 

                        onoff[l] = 0;

 

                    }

 

                    for (l = 0; l < 2; l++) {

 

                        onoff[rlst[a][s1][t1][l] - 1] = 1;

 

                        onoff[rlst[a][s2][t2][l] - 1] = 1;

 

                    }

 

                    w = 0;

 

                    for (l = 0; l < N; l++) {

 

                        if (onoff[l] == 1) {

 

                            ckotae[w] = l;

 

                            w = w + 1;

 

                        }

 

                    }

 

                    if (w == 2) {

 

                        for (l = 0; l < N; l++) {

 

                            if (l != j && l != k) {

 

                                s3 = RN * (i / RN) + (l / RN);

 

                                t3 = RN * (i % RN) + (l % RN);

 

                                if (m[a][s3][t3] == 0) {

 

                                    wb[a][s3][t3][ckotae[0]] = 1;

 

                                    wb[a][s3][t3][ckotae[1]] = 1;

 

                                }

 

                            }

 

                        }

 

                        for (l = 0; l < N; l++) {

 

                            if (l != j && l != k) {

 

                                s4 = RN * (i / RN) + (l / RN);

 

                                t4 = RN * (i % RN) + (l % RN);

 

                                if (m[a][s4][t4] == 0) {

 

                                    局所解析関数(s4, t4, a);

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 相補確定関数(size_t a) {

 

    相補確定とそれによる行排除関数(a);

 

    相補確定とそれによる列排除関数(a);

 

    相補確定とそれによるブロック排除関数(a);

 

}

void 三対三確定および排除行関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = 行値0番号集合[i].size();

 

        if (n >= 3) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t x = 0; x < n; x++) {

 

                if (m[a][i][x] == 0 && mx[a][i][x] < 4) {

 

                    size_t max_x = mx[a][i][x];

 

                    for (size_t j = 0; j < max_x; j++) {

 

                        if (b[rlst[a][i][x][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][i][x][j]);

 

                            b[rlst[a][i][x][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (size_t y = 0; y < n; y++) {

 

                        if (m[a][i][y] == 0 && mx[a][i][y] < 4) {

 

                            size_t max_y = mx[a][i][y];

 

                            for (size_t j = 0; j < max_y; j++) {

 

                                if (b[rlst[a][i][y][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][i][y][j]);

 

                                    b[rlst[a][i][y][j] - 1] = 1;

 

                                }

                            }

 

                            for (size_t z = 0; z < n; z++) {

 

                                if (m[a][i][z] == 0 && mx[a][i][z] < 4) {

 

                                    size_t max_z = mx[a][i][z];

 

                                    for (size_t j = 0; j < max_z; j++) {

 

                                        if (b[rlst[a][i][z][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][i][z][j]);

 

                                            b[rlst[a][i][z][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

                                if (和集合.size() == 3) {

 

                                    for (size_t j = 0; j < N; j++) {

 

                                        if (j != x && j != y && j != z) {

 

                                            if (m[a][i][j] == 0) {

 

                                                wb[a][i][j][和集合[0] - 1] = 1;

 

                                                wb[a][i][j][和集合[1] - 1] = 1;

 

                                                wb[a][i][j][和集合[2] - 1] = 1;

 

                                            }

 

                                        }

 

                                    }

 

                                    for (size_t j = 0; j < N; j++) {

 

                                        if (j != x && j != y && j != z) {

 

                                            if (m[a][i][j] == 0) {

 

                                                局所解析関数(i, j, a);

 

                                            }

 

                                        }

 

                                    }

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 三対三確定および排除列関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = 列値0番号集合[i].size();

 

        if (n >= 3) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t x = 0; x < n; x++) {

 

                if (m[a][x][i] == 0 && mx[a][x][i] < 4) {

 

                    size_t max_x = mx[a][x][i];

 

                    for (size_t j = 0; j < max_x; j++) {

 

                        if (b[rlst[a][x][i][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][x][i][j]);

 

                            b[rlst[a][x][i][j] - 1] = 1;

 

                        }

 

                    }

                    for (size_t y = 0; y < n; y++) {

 

                        if (m[a][y][i] == 0 && mx[a][y][i] < 4) {

 

                            size_t max_y = mx[a][y][i];

 

                            for (size_t j = 0; j < max_y; j++) {

 

                                if (b[rlst[a][y][i][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][y][i][j]);

 

                                    b[rlst[a][y][i][j] - 1] = 1;

 

                                }

 

                            }

                            for (size_t z = 0; z < n; z++) {

 

                                if (m[a][z][i] == 0 && mx[a][z][i] < 4) {

 

                                    size_t max_z = mx[a][z][i];

 

                                    for (size_t j = 0; j < max_z; j++) {

 

                                        if (b[rlst[a][z][i][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][z][i][j]);

 

                                            b[rlst[a][z][i][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

                                if (和集合.size() == 3) {

 

                                    for (size_t j = 0; j < N; j++) {

 

                                        if (j != x && j != y && j != z) {

 

                                            if (m[a][j][i] == 0) {

 

                                                wb[a][j][i][和集合[0] - 1] = 1;

 

                                                wb[a][j][i][和集合[1] - 1] = 1;

 

                                                wb[a][j][i][和集合[2] - 1] = 1;

 

                                            }

 

                                        }

 

                                    }

 

                                    for (size_t j = 0; j < N; j++) {

 

                                        if (j != x && j != y && j != z) {

 

                                            if (m[a][j][i] == 0) {

 

                                                局所解析関数(j, i, a);

 

                                            }

 

                                        }

 

                                    }

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 三対三確定および排除ブロック関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {//ブロック番号

 

        size_t n = ブロック値0番号集合[i].size();

 

        if (n >= 3) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t x = 0; x < n; x++) {//ブロック内セル番号

 

                if (m[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] == 0 && mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] < 4) {

 

                    size_t max_x = mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)];

 

                    for (size_t j = 0; j < max_x; j++) {

 

                        if (b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j]);

 

                            b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (size_t y = 0; y < n; y++) {

 

                        if (m[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] == 0 && mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] < 4) {

 

                            size_t max_y = mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)];

 

                            for (size_t j = 0; j < max_y; j++) {

 

                                if (b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j]);

 

                                    b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] = 1;

 

                                }

 

                            }

 

                            for (size_t z = 0; z < n; z++) {

 

                                if (m[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] == 0 && mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] < 4) {

 

                                    size_t max_z = mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)];

 

                                    for (size_t j = 0; j < max_z; j++) {

 

                                        if (b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j]);

 

                                            b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] = 1;

 

                                        }

                                    }

 

                                }

 

                                if (和集合.size() == 3) {

 

                                    for (size_t j = 0; j < N; j++) {

 

                                        if (j != x && j != y && j != z) {

 

                                            if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

 

                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[0] - 1] = 1;

 

                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[1] - 1] = 1;

 

                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[2] - 1] = 1;

 

                                            }

                                        }

 

                                    }

                                    for (size_t j = 0; j < N; j++) {

 

                                        if (j != x && j != y && j != z) {

 

                                            if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

 

                                                局所解析関数(RN * (i / RN) + (j / RN), RN * (i % RN) + (j % RN), a);

 

                                            }

                                        }

 

                                    }

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 三対三確定および排除関数(size_t a) {

 

    三対三確定および排除行関数(a);

 

    三対三確定および排除列関数(a);

 

    三対三確定および排除ブロック関数(a);

 

}

 

void 四対四確定および排除行関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = 行値0番号集合[i].size();

 

        if (n >= 4) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t w = 0; w < n; w++) {

 

                if (m[a][i][w] == 0 && mx[a][i][w] < 5) {

 

                    size_t max_w = mx[a][i][w];

 

                    for (size_t j = 0; j < max_w; j++) {

 

                        if (b[rlst[a][i][w][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][i][w][j]);

 

                            b[rlst[a][i][w][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (size_t x = 0; x < n; x++) {

 

                        if (m[a][i][x] == 0 && mx[a][i][x] < 5) {

 

                            size_t max_x = mx[a][i][x];

 

                            for (size_t j = 0; j < max_x; j++) {

 

                                if (b[rlst[a][i][x][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][i][x][j]);

 

                                    b[rlst[a][i][x][j] - 1] = 1;

 

                                }

 

                            }

 

                            for (size_t y = 0; y < n; y++) {

 

                                if (m[a][i][y] == 0 && mx[a][i][y] < 5) {

 

                                    size_t max_y = mx[a][i][y];

 

                                    for (size_t j = 0; j < max_y; j++) {

 

                                        if (b[rlst[a][i][y][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][i][y][j]);

 

                                            b[rlst[a][i][y][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

 

                                for (size_t z = 0; z < n; z++) {

 

                                    if (m[a][i][z] == 0 && mx[a][i][z] < 5) {

 

                                        size_t max_z = mx[a][i][z];

 

                                        for (size_t j = 0; j < max_z; j++) {

 

                                            if (b[rlst[a][i][z][j] - 1] == 0) {

 

                                                和集合.push_back(rlst[a][i][z][j]);

 

                                                b[rlst[a][i][z][j] - 1] = 1;

 

                                            }

 

                                        }

 

 

                                    }

                                    if (和集合.size() == 4) {

 

                                        for (size_t j = 0; j < N; j++) {

 

                                            if (j != w && j != x && j != y && j != z) {

 

                                                if (m[a][i][j] == 0) {

 

                                                    wb[a][i][j][和集合[0] - 1] = 1;

 

                                                    wb[a][i][j][和集合[1] - 1] = 1;

 

                                                    wb[a][i][j][和集合[2] - 1] = 1;

 

                                                    wb[a][i][j][和集合[3] - 1] = 1;

 

                                                }

 

                                            }

 

 

                                        }

 

                                        for (size_t j = 0; j < N; j++) {

 

                                            if (j != w && j != x && j != y && j != z) {

 

                                                if (m[a][i][j] == 0) {

 

                                                    局所解析関数(i, j, a);

 

                                                }

 

                                            }

 

                                        }

 

                                    }

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 四対四確定および排除列関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = 列値0番号集合[i].size();

 

        if (n >= 4) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t w = 0; w < n; w++) {

 

                if (m[a][w][i] == 0 && mx[a][w][i] < 5) {

 

                    size_t max_w = mx[a][w][i];

 

                    for (size_t j = 0; j < max_w; j++) {

 

                        if (b[rlst[a][w][i][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][w][i][j]);

 

                            b[rlst[a][w][i][j] - 1] = 1;

 

                        }

 

                    }

                    for (size_t x = 0; x < n; x++) {

 

                        if (m[a][x][i] == 0 && mx[a][x][i] < 5) {

 

                            size_t max_x = mx[a][x][i];

 

                            for (size_t j = 0; j < max_x; j++) {

 

                                if (b[rlst[a][x][i][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][x][i][j]);

 

                                    b[rlst[a][x][i][j] - 1] = 1;

 

                                }

 

                            }

 

                            for (size_t y = 0; y < n; y++) {

 

                                if (m[a][y][i] == 0 && mx[a][y][i] < 5) {

 

                                    size_t max_y = mx[a][y][i];

 

                                    for (size_t j = 0; j < max_y; j++) {

 

                                        if (b[rlst[a][y][i][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][y][i][j]);

 

                                            b[rlst[a][y][i][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

 

                                for (size_t z = 0; z < n; z++) {

 

                                    if (m[a][z][i] == 0 && mx[a][z][i] < 5) {

 

                                        size_t max_z = mx[a][z][i];

 

                                        for (size_t j = 0; j < max_z; j++) {

 

                                            if (b[rlst[a][z][i][j] - 1] == 0) {

 

                                                和集合.push_back(rlst[a][z][i][j]);

 

                                                b[rlst[a][z][i][j] - 1] = 1;

 

                                            }

 

                                        }

 

                                    }

 

                                    if (和集合.size() == 4) {

 

                                        for (size_t j = 0; j < N; j++) {

 

                                            if (j != w && j != x && j != y && j != z) {

 

                                                if (m[a][j][i] == 0) {

 

                                                    wb[a][j][i][和集合[0] - 1] = 1;

 

                                                    wb[a][j][i][和集合[1] - 1] = 1;

 

                                                    wb[a][j][i][和集合[2] - 1] = 1;

 

                                                    wb[a][j][i][和集合[3] - 1] = 1;

 

                                                }

 

                                            }

 

                                        }

 

                                        for (size_t j = 0; j < N; j++) {

 

                                            if (j != w && j != x && j != y && j != z) {

 

                                                if (m[a][j][i] == 0) {

 

                                                    局所解析関数(j, i, a);

 

                                                }

 

                                            }

 

                                        }

 

                                    }

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 四対四確定および排除ブロック関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = ブロック値0番号集合[i].size();

 

        if (n >= 4) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t w = 0; w < n; w++) {

 

                if (m[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] == 0 && mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] < 5) {

 

                    size_t max_w = mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)];

 

                    for (size_t j = 0; j < max_w; j++) {

 

                        if (b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j]);

 

                            b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (size_t x = 0; x < n; x++) {

 

                        if (m[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] == 0 && mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] < 5) {

 

                            size_t max_x = mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)];

 

                            for (size_t j = 0; j < max_x; j++) {

 

                                if (b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j]);

 

                                    b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] = 1;

 

                                }

 

                            }

 

                            for (size_t y = 0; y < n; y++) {

 

                                if (m[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] == 0 && mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] < 5) {

 

                                    size_t max_y = mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)];

 

                                    for (size_t j = 0; j < max_y; j++) {

 

                                        if (b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j]);

 

                                            b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

 

                                for (size_t z = 0; z < n; z++) {

 

                                    if (m[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] == 0 && mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] < 5) {

 

                                        size_t max_z = mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)];

 

                                        for (size_t j = 0; j < max_z; j++) {

                                           

                                            if (b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] == 0) {

 

                                                和集合.push_back(rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j]);

 

                                                b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] = 1;

 

                                            }

 

                                        }

 

                                    }

 

                                    if (和集合.size() == 4) {

 

                                        for (size_t j = 0; j < N; j++) {

 

                                            if (j != w && j != x && j != y && j != z) {

 

                                                if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

 

                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[0] - 1] = 1;

 

                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[1] - 1] = 1;

 

                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[2] - 1] = 1;

 

                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[3] - 1] = 1;

 

                                                }

 

                                            }

 

                                        }

                                        for (size_t j = 0; j < N; j++) {

 

                                            if (j != w && j != x && j != y && j != z) {

 

                                                if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

 

                                                    局所解析関数(RN * (i / RN) + (j / RN), RN * (i % RN) + (j % RN), a);

 

                                                }

 

                                            }

 

                                        }

 

                                    }

 

                                }

 

                            }

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 四対四確定および排除関数(size_t a) {

 

    四対四確定および排除行関数(a);

 

    四対四確定および排除列関数(a);

 

    四対四確定および排除ブロック関数(a);

 

}

 

void 五対五確定および排除行関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = 行値0番号集合[i].size();

 

        if (n >= 5) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t v = 0; v < n; v++) {

 

                if (m[a][i][v] == 0 && mx[a][i][v] < 6) {

 

                    size_t max_v = mx[a][i][v];

 

                    for (size_t j = 0; j < max_v; j++) {

 

                        if (b[rlst[a][i][v][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][i][v][j]);

 

                            b[rlst[a][i][v][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (size_t w = 0; w < n; w++) {

 

                        if (m[a][i][w] == 0 && mx[a][i][w] < 6) {

 

                            size_t maw_w = mx[a][i][w];

 

                            for (size_t j = 0; j < maw_w; j++) {

 

                                if (b[rlst[a][i][w][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][i][w][j]);

 

                                    b[rlst[a][i][w][j] - 1] = 1;

 

                                }

 

                            }

 

                            for (size_t x = 0; x < n; x++) {

 

                                if (m[a][i][x] == 0 && mx[a][i][x] < 6) {

 

                                    size_t max_x = mx[a][i][x];

 

                                    for (size_t j = 0; j < max_x; j++) {

 

                                        if (b[rlst[a][i][x][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][i][x][j]);

 

                                            b[rlst[a][i][x][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

 

                                for (size_t y = 0; y < n; y++) {

 

                                    if (m[a][i][y] == 0 && mx[a][i][y] < 6) {

 

                                        size_t max_y = mx[a][i][y];

 

                                        for (size_t j = 0; j < max_y; j++) {

 

                                            if (b[rlst[a][i][y][j] - 1] == 0) {

 

                                                和集合.push_back(rlst[a][i][y][j]);

 

                                                b[rlst[a][i][y][j] - 1] = 1;

 

                                            }

 

                                        }

 

                                    }

 

                                    for (size_t z = 0; z < n; z++) {

 

                                        if (m[a][i][z] == 0 && mx[a][i][z] < 6) {

 

                                            size_t max_z = mx[a][i][z];

 

                                            for (size_t j = 0; j < max_z; j++) {

 

                                                if (b[rlst[a][i][z][j] - 1] == 0) {

 

                                                    和集合.push_back(rlst[a][i][z][j]);

 

                                                    b[rlst[a][i][z][j] - 1] = 1;

 

                                                }

 

                                            }

 

                                        }

 

                                        if (和集合.size() == 5) {

                                            for (size_t j = 0; j < N; j++) {

                                                if (j != v && j != w && j != x && j != y && j != z) {

                                                    if (m[a][i][j] == 0) {

                                                        wb[a][i][j][和集合[0] - 1] = 1;

                                                        wb[a][i][j][和集合[1] - 1] = 1;

                                                        wb[a][i][j][和集合[2] - 1] = 1;

                                                        wb[a][i][j][和集合[3] - 1] = 1;

                                                        wb[a][i][j][和集合[4] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t j = 0; j < N; j++) {

                                                if (j != v && j != w && j != x && j != y && j != z) {

                                                    if (m[a][i][j] == 0) {

                                                        局所解析関数(i, j, a);

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 五対五確定および排除列関数(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        size_t n = 行値0番号集合[i].size();

 

        if (n >= 5) {

 

            vector<int> 和集合;

 

            size_t b[N] = { 0 };//値の重複を防ぐための配列

 

            for (size_t v = 0; v < n; v++) {

 

                if (m[a][v][i] == 0 && mx[a][v][i] < 6) {

 

                    size_t max_v = mx[a][v][i];

 

                    for (size_t j = 0; j < max_v; j++) {

 

                        if (b[rlst[a][v][i][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][v][i][j]);

 

                            b[rlst[a][v][i][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (size_t w = 0; w < n; w++) {

 

                        if (m[a][w][i] == 0 && mx[a][w][i] < 6) {

 

                            size_t maw_w = mx[a][w][i];

 

                            for (size_t j = 0; j < maw_w; j++) {

 

                                if (b[rlst[a][w][i][j] - 1] == 0) {

 

                                    和集合.push_back(rlst[a][w][i][j]);

 

                                    b[rlst[a][w][i][j] - 1] = 1;

 

                                }

 

                            }

 

                            for (size_t x = 0; x < n; x++) {

 

                                if (m[a][x][i] == 0 && mx[a][x][i] < 6) {

 

                                    size_t max_x = mx[a][x][i];

 

                                    for (size_t j = 0; j < max_x; j++) {

 

                                        if (b[rlst[a][x][i][j] - 1] == 0) {

 

                                            和集合.push_back(rlst[a][x][i][j]);

 

                                            b[rlst[a][x][i][j] - 1] = 1;

 

                                        }

 

                                    }

 

                                }

                                for (size_t y = 0; y < n; y++) {

 

                                    if (m[a][y][i] == 0 && mx[a][y][i] < 6) {

 

                                        size_t max_y = mx[a][y][i];

 

                                        for (size_t j = 0; j < max_y; j++) {

 

                                            if (b[rlst[a][y][i][j] - 1] == 0) {

 

                                                和集合.push_back(rlst[a][y][i][j]);

 

                                                b[rlst[a][y][i][j] - 1] = 1;

 

                                            }

                                        }

                                    }

                                    for (size_t z = 0; z < n; z++) {

 

                                        if (m[a][z][i] == 0 && mx[a][z][i] < 6) {

 

                                            size_t max_z = mx[a][z][i];

 

                                            for (size_t j = 0; j < max_z; j++) {

 

                                                if (b[rlst[a][z][i][j] - 1] == 0) {

 

                                                    和集合.push_back(rlst[a][z][i][j]);

 

                                                    b[rlst[a][z][i][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        if (和集合.size() == 5) {

                                            for (size_t j = 0; j < N; j++) {

                                                if (j != v && j != w && j != x && j != y && j != z) {

                                                    if (m[a][j][i] == 0) {

                                                        wb[a][j][i][和集合[0] - 1] = 1;

                                                        wb[a][j][i][和集合[1] - 1] = 1;

                                                        wb[a][j][i][和集合[2] - 1] = 1;

                                                        wb[a][j][i][和集合[3] - 1] = 1;

                                                        wb[a][j][i][和集合[4] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t j = 0; j < N; j++) {

                                                if (j != v && j != w && j != x && j != y && j != z) {

                                                    if (m[a][j][i] == 0) {

                                                        局所解析関数(j, i, a);

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 五対五確定および排除ブロック関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 5) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t v = 0; v < n; v++) {

 

                if (m[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] == 0 && mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] < 6) {

 

                    size_t max_v = mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)];

 

                    for (size_t j = 0; j < max_v; j++) {

 

                        if (b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] == 0) {

 

                            和集合.push_back(rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j]);

 

                            b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] = 1;

 

                        }

                    }

                    for (size_t w = 0; w < n; w++) {

 

                        if (m[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] == 0 && mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] < 6) {

                           

                            size_t maw_w = mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)];

                           

                            for (size_t j = 0; j < maw_w; j++) {

                               

                                if (b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j]);

                                   

                                    b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] = 1;

                                }

                            }

                            for (size_t x = 0; x < n; x++) {

                               

                                if (m[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] == 0 && mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] < 6) {

                                   

                                    size_t max_x = mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)];

                                   

                                    for (size_t j = 0; j < max_x; j++) {

                                       

                                        if (b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j]);

                                           

                                            b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t y = 0; y < n; y++) {

                                   

                                    if (m[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] == 0 && mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] < 6) {

                                       

                                        size_t max_y = mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)];

                                       

                                        for (size_t j = 0; j < max_y; j++) {

                                           

                                            if (b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] == 0) {

                                               

                                                和集合.push_back(rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j]);

                                               

                                                b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t z = 0; z < n; z++) {

                                       

                                        if (m[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] == 0 && mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] < 6) {

                                           

                                            size_t max_z = mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)];

                                           

                                            for (size_t j = 0; j < max_z; j++) {

                                               

                                                if (b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j]);

                                                   

                                                    b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        if (和集合.size() == 5) {

                                            for (size_t j = 0; j < N; j++) {

                                                if (j != v && j != w && j != x && j != y && j != z) {

                                                    if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                        wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[0] - 1] = 1;

                                                        wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[1] - 1] = 1;

                                                        wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[2] - 1] = 1;

                                                        wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[3] - 1] = 1;

                                                        wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[4] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t j = 0; j < N; j++) {

                                                if (j != v && j != w && j != x && j != y && j != z) {

                                                    if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                        局所解析関数(RN * (i / RN) + (j / RN), RN * (i % RN) + (j % RN), a);

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 五対五確定および排除関数(size_t a) {

 

    五対五確定および排除行関数(a);

 

    五対五確定および排除列関数(a);

 

    五対五確定および排除ブロック関数(a);

 

}

 

void 六対六確定および排除行関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 6) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t u = 0; u < n; u++) {

               

                if (m[a][i][u] == 0 && mx[a][i][u] < 7) {

                   

                    size_t max_u = mx[a][i][u];

                   

                    for (size_t j = 0; j < max_u; j++) {

                       

                        if (b[rlst[a][i][u][j] - 1] == 0) {

                           

                            和集合.push_back(rlst[a][i][u][j]);

                           

                            b[rlst[a][i][u][j] - 1] = 1;

                        }

                    }

                    for (size_t v = 0; v < n; v++) {

                       

                        if (m[a][i][v] == 0 && mx[a][i][v] < 7) {

                           

                            size_t mav_v = mx[a][i][v];

                           

                            for (size_t j = 0; j < mav_v; j++) {

                               

                                if (b[rlst[a][i][v][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][i][v][j]);

                                   

                                    b[rlst[a][i][v][j] - 1] = 1;

                               

                                }

                            }

                           

                            for (size_t w = 0; w < n; w++) {

                               

                                if (m[a][i][w] == 0 && mx[a][i][w] < 7) {

                                   

                                    size_t maw_w = mx[a][i][w];

                                   

                                    for (size_t j = 0; j < maw_w; j++) {

                                       

                                        if (b[rlst[a][i][w][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][i][w][j]);

                                           

                                            b[rlst[a][i][w][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t x = 0; x < n; x++) {

                                   

                                    if (m[a][i][x] == 0 && mx[a][i][x] < 7) {

                                       

                                        size_t max_x = mx[a][i][x];

                                       

                                        for (size_t j = 0; j < max_x; j++) {

                                           

                                            if (b[rlst[a][i][x][j] - 1] == 0) {

                                               

                                                和集合.push_back(rlst[a][i][x][j]);

                                               

                                                b[rlst[a][i][x][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t y = 0; y < n; y++) {

                                       

                                        if (m[a][i][y] == 0 && mx[a][i][y] < 7) {

                                           

                                            size_t max_y = mx[a][i][y];

                                           

                                            for (size_t j = 0; j < max_y; j++) {

                                               

                                                if (b[rlst[a][i][y][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][i][y][j]);

                                                   

                                                    b[rlst[a][i][y][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t z = 0; z < n; z++) {

                                           

                                            if (m[a][i][z] == 0 && mx[a][i][z] < 7) {

                                               

                                                size_t max_z = mx[a][i][z];

                                               

                                                for (size_t j = 0; j < max_z; j++) {

                                                   

                                                    if (b[rlst[a][i][z][j] - 1] == 0) {

                                                       

                                                        和集合.push_back(rlst[a][i][z][j]);

                                                       

                                                        b[rlst[a][i][z][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            if (和集合.size() == 6) {

                                                for (size_t j = 0; j < N; j++) {

                                                    if (j != u && j != v && j != w && j != x && j != y && j != z) {

                                                        if (m[a][i][j] == 0) {

                                                            wb[a][i][j][和集合[0] - 1] = 1;

                                                            wb[a][i][j][和集合[1] - 1] = 1;

                                                            wb[a][i][j][和集合[2] - 1] = 1;

                                                            wb[a][i][j][和集合[3] - 1] = 1;

                                                            wb[a][i][j][和集合[4] - 1] = 1;

                                                            wb[a][i][j][和集合[5] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                for (size_t j = 0; j < N; j++) {

                                                    if (j != u && j != v && j != w && j != x && j != y && j != z) {

                                                        if (m[a][i][j] == 0) {

                                                            局所解析関数(i, j, a);

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 六対六確定および排除列関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 6) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t u = 0; u < n; u++) {

               

                if (m[a][u][i] == 0 && mx[a][u][i] < 7) {

                   

                    size_t max_u = mx[a][u][i];

                   

                    for (size_t j = 0; j < max_u; j++) {

                       

                        if (b[rlst[a][u][i][j] - 1] == 0) {

                           

                            和集合.push_back(rlst[a][u][i][j]);

                           

                            b[rlst[a][u][i][j] - 1] = 1;

                        }

                    }

                    for (size_t v = 0; v < n; v++) {

                       

                        if (m[a][v][i] == 0 && mx[a][v][i] < 7) {

                           

                            size_t mav_v = mx[a][v][i];

                           

                            for (size_t j = 0; j < mav_v; j++) {

                               

                                if (b[rlst[a][v][i][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][v][i][j]);

                                   

                                    b[rlst[a][v][i][j] - 1] = 1;

                                }

                            }

                            for (size_t w = 0; w < n; w++) {

                                if (m[a][w][i] == 0 && mx[a][w][i] < 7) {

                                    size_t maw_w = mx[a][w][i];

                                    for (size_t j = 0; j < maw_w; j++) {

                                        if (b[rlst[a][w][i][j] - 1] == 0) {

                                            和集合.push_back(rlst[a][w][i][j]);

                                            b[rlst[a][w][i][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t x = 0; x < n; x++) {

                                   

                                    if (m[a][x][i] == 0 && mx[a][x][i] < 7) {

                                       

                                        size_t max_x = mx[a][x][i];

                                       

                                        for (size_t j = 0; j < max_x; j++) {

                                           

                                            if (b[rlst[a][x][i][j] - 1] == 0) {

                                               

                                                和集合.push_back(rlst[a][x][i][j]);

                                               

                                                b[rlst[a][x][i][j] - 1] = 1;

                                            }

                                        }

                                    }

                                   

                                    for (size_t y = 0; y < n; y++) {

                                       

                                        if (m[a][y][i] == 0 && mx[a][y][i] < 7) {

                                           

                                            size_t max_y = mx[a][y][i];

                                           

                                            for (size_t j = 0; j < max_y; j++) {

                                               

                                                if (b[rlst[a][y][i][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][y][i][j]);

                                                   

                                                    b[rlst[a][y][i][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t z = 0; z < n; z++) {

                                           

                                            if (m[a][z][i] == 0 && mx[a][z][i] < 7) {

                                               

                                                size_t max_z = mx[a][z][i];

                                               

                                                for (size_t j = 0; j < max_z; j++) {

                                                   

                                                    if (b[rlst[a][z][i][j] - 1] == 0) {

                                                       

                                                        和集合.push_back(rlst[a][z][i][j]);

                                                       

                                                        b[rlst[a][z][i][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            if (和集合.size() == 6) {                                               

                                                for (size_t j = 0; j < N; j++) {

                                                    if (j != u && j != v && j != w && j != x && j != y && j != z) {

                                                        if (m[a][j][i] == 0) {

                                                            wb[a][j][i][和集合[0] - 1] = 1;

                                                            wb[a][j][i][和集合[1] - 1] = 1;

                                                            wb[a][j][i][和集合[2] - 1] = 1;

                                                            wb[a][j][i][和集合[3] - 1] = 1;

                                                            wb[a][j][i][和集合[4] - 1] = 1;

                                                            wb[a][j][i][和集合[5] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                for (size_t j = 0; j < N; j++) {

                                                    if (j != u && j != v && j != w && j != x && j != y && j != z) {

                                                        if (m[a][j][i] == 0) {

                                                            局所解析関数(i, j, a);

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 六対六確定および排除ブロック関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 6) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t u = 0; u < n; u++) {

               

                if (m[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)] == 0 && mx[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)] < 7) {

                   

                    size_t max_u = mx[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)];

                   

                    for (size_t j = 0; j < max_u; j++) {

                       

                        if (b[rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j] - 1] == 0) {

                           

                            和集合.push_back(rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j]);

                           

                            b[rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j] - 1] = 1;

                        }

                    }

                    for (size_t v = 0; v < n; v++) {

                       

                        if (m[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] == 0 && mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] < 7) {

                           

                            size_t mav_v = mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)];

                           

                            for (size_t j = 0; j < mav_v; j++) {

                               

                                if (b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j]);

                                   

                                    b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] = 1;

                                }

                            }

                            for (size_t w = 0; w < n; w++) {

                               

                                if (m[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] == 0 && mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] < 7) {

                                   

                                    size_t maw_w = mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)];

                                   

                                    for (size_t j = 0; j < maw_w; j++) {

                                       

                                        if (b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j]);

                                           

                                            b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t x = 0; x < n; x++) {

                                   

                                    if (m[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] == 0 && mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] < 7) {

                                       

                                        size_t max_x = mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)];

                                       

                                        for (size_t j = 0; j < max_x; j++) {

                                           

                                            if (b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] == 0) {

                                               

                                                和集合.push_back(rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j]);

                                               

                                                b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t y = 0; y < n; y++) {

                                       

                                        if (m[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] == 0 && mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] < 7) {

                                           

                                            size_t max_y = mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)];

                                           

                                            for (size_t j = 0; j < max_y; j++) {

                                               

                                                if (b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j]);

                                                   

                                                    b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t z = 0; z < n; z++) {

                                           

                                            if (m[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] == 0 && mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] < 7) {

                                               

                                                size_t max_z = mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)];

                                               

                                                for (size_t j = 0; j < max_z; j++) {

                                                   

                                                    if (b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] == 0) {

                                                       

                                                        和集合.push_back(rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j]);

                                                       

                                                        b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            if (和集合.size() == 6) {

                                                for (size_t j = 0; j < N; j++) {

                                                    if (j != u && j != v && j != w && j != x && j != y && j != z) {

                                                        if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                            wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[0] - 1] = 1;

                                                            wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[1] - 1] = 1;

                                                            wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[2] - 1] = 1;

                                                            wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[3] - 1] = 1;

                                                            wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[4] - 1] = 1;

                                                            wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[5] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                for (size_t j = 0; j < N; j++) {

                                                    if (j != u && j != v && j != w && j != x && j != y && j != z) {

                                                        if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                            局所解析関数(RN * (i / RN) + (j / RN), RN * (i % RN) + (j % RN), a);

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 六対六確定および排除関数(size_t a) {

 

    六対六確定および排除行関数(a);

 

    六対六確定および排除列関数(a);

 

    六対六確定および排除ブロック関数(a);

 

}

 

void 七対七確定および排除行関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 7) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t t = 0; t < n; t++) {

               

                if (m[a][i][t] == 0 && mx[a][i][t] < 8) {

                   

                    size_t max_t = mx[a][i][t];

                   

                    for (size_t j = 0; j < max_t; j++) {

                       

                        if (b[rlst[a][i][t][j] - 1] == 0) {

                           

                            和集合.push_back(rlst[a][i][t][j]);

                           

                            b[rlst[a][i][t][j] - 1] = 1;

                        }

                    }

                    for (size_t u = 0; u < n; u++) {

                       

                        if (m[a][i][u] == 0 && mx[a][i][u] < 8) {

                           

                            size_t mau_u = mx[a][i][u];

                           

                            for (size_t j = 0; j < mau_u; j++) {

                               

                                if (b[rlst[a][i][u][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][i][u][j]);

                                  

                                    b[rlst[a][i][u][j] - 1] = 1;

                                }

                            }

                            for (size_t v = 0; v < n; v++) {

                               

                                if (m[a][i][v] == 0 && mx[a][i][v] < 8) {

                                   

                                    size_t mav_v = mx[a][i][v];

                                   

                                    for (size_t j = 0; j < mav_v; j++) {

                                       

                                        if (b[rlst[a][i][v][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][i][v][j]);

                                           

                                            b[rlst[a][i][v][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t w = 0; w < n; w++) {

                                   

                                    if (m[a][i][w] == 0 && mx[a][i][w] < 8) {

                                       

                                        size_t maw_w = mx[a][i][w];

                                       

                                        for (size_t j = 0; j < maw_w; j++) {

                                           

                                            if (b[rlst[a][i][w][j] - 1] == 0) {

                                               

                                                和集合.push_back(rlst[a][i][w][j]);

                                               

                                                b[rlst[a][i][w][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t x = 0; x < n; x++) {

                                       

                                        if (m[a][i][x] == 0 && mx[a][i][x] < 8) {

                                           

                                            size_t max_x = mx[a][i][x];

                                           

                                            for (size_t j = 0; j < max_x; j++) {

                                               

                                                if (b[rlst[a][i][x][j] - 1] == 0) {

                                                  

                                                    和集合.push_back(rlst[a][i][x][j]);

                                                 

                                                    b[rlst[a][i][x][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t y = 0; y < n; y++) {

                                           

                                            if (m[a][i][y] == 0 && mx[a][i][y] < 8) {

                                               

                                                size_t max_y = mx[a][i][y];

                                               

                                                for (size_t j = 0; j < max_y; j++) {

                                                   

                                                    if (b[rlst[a][i][y][j] - 1] == 0) {

                                                      

                                                        和集合.push_back(rlst[a][i][y][j]);

                                                   

                                                        b[rlst[a][i][y][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t z = 0; z < n; z++) {

                                               

                                                if (m[a][i][z] == 0 && mx[a][i][z] < 8) {

                                                  

                                                    size_t max_z = mx[a][i][z];

                                                   

                                                    for (size_t j = 0; j < max_z; j++) {

                                                       

                                                        if (b[rlst[a][i][z][j] - 1] == 0) {

                                                          

                                                            和集合.push_back(rlst[a][i][z][j]);

                                                         

                                                            b[rlst[a][i][z][j] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                if (和集合.size() == 7) {

                                                    for (size_t j = 0; j < N; j++) {

                                                        if (j != t && j != u && j != v && j != w && j != x && j != y && j != z) {

                                                            if (m[a][i][j] == 0) {

                                                                wb[a][i][j][和集合[0] - 1] = 1;

                                                                wb[a][i][j][和集合[1] - 1] = 1;

                                                                wb[a][i][j][和集合[2] - 1] = 1;

                                                                wb[a][i][j][和集合[3] - 1] = 1;

                                                                wb[a][i][j][和集合[4] - 1] = 1;

                                                                wb[a][i][j][和集合[5] - 1] = 1;

                                                                wb[a][i][j][和集合[6] - 1] = 1;

                                                            }

                                                        }

                                                    }

                                                    for (size_t j = 0; j < N; j++) {

                                                        if (j != t && j != u && j != v && j != w && j != x && j != y && j != z) {

                                                            if (m[a][i][j] == 0) {

                                                                局所解析関数(i, j, a);

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 七対七確定および排除列関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 7) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t t = 0; t < n; t++) {

               

                if (m[a][t][i] == 0 && mx[a][t][i] < 8) {

                   

                    size_t max_t = mx[a][t][i];

                   

                    for (size_t j = 0; j < max_t; j++) {

                       

                        if (b[rlst[a][t][i][j] - 1] == 0) {

                           

                            和集合.push_back(rlst[a][t][i][j]);

                           

                            b[rlst[a][t][i][j] - 1] = 1;

                        }

                    }

                    for (size_t u = 0; u < n; u++) {

                       

                        if (m[a][u][i] == 0 && mx[a][u][i] < 8) {

                           

                            size_t mau_u = mx[a][u][i];

                           

                            for (size_t j = 0; j < mau_u; j++) {

                               

                                if (b[rlst[a][u][i][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][u][i][j]);

                                   

                                    b[rlst[a][u][i][j] - 1] = 1;

                                }

                            }

                            for (size_t v = 0; v < n; v++) {

                               

                                if (m[a][v][i] == 0 && mx[a][v][i] < 8) {

                                   

                                    size_t mav_v = mx[a][v][i];

                                   

                                    for (size_t j = 0; j < mav_v; j++) {

                                       

                                        if (b[rlst[a][v][i][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][v][i][j]);

                                           

                                            b[rlst[a][v][i][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t w = 0; w < n; w++) {

                                   

                                    if (m[a][w][i] == 0 && mx[a][w][i] < 8) {

                                       

                                        size_t maw_w = mx[a][w][i];

                                       

                                        for (size_t j = 0; j < maw_w; j++) {

                                           

                                            if (b[rlst[a][w][i][j] - 1] == 0) {

                                             

                                                和集合.push_back(rlst[a][w][i][j]);

                                            

                                                b[rlst[a][w][i][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t x = 0; x < n; x++) {

                                       

                                        if (m[a][x][i] == 0 && mx[a][x][i] < 8) {

                                        

                                            size_t max_x = mx[a][x][i];

                                        

                                            for (size_t j = 0; j < max_x; j++) {

                                         

                                                if (b[rlst[a][x][i][j] - 1] == 0) {                                          

                                          

                                                    和集合.push_back(rlst[a][x][i][j]);

 

                                                    b[rlst[a][x][i][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t y = 0; y < n; y++) {

                                           

                                            if (m[a][y][i] == 0 && mx[a][y][i] < 8) {

                                               

                                                size_t max_y = mx[a][y][i];

                                               

                                                for (size_t j = 0; j < max_y; j++) {

                                                  

                                                    if (b[rlst[a][y][i][j] - 1] == 0) {

                                                    

                                                        和集合.push_back(rlst[a][y][i][j]);

                                                     

                                                        b[rlst[a][y][i][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t z = 0; z < n; z++) {

                                               

                                                if (m[a][z][i] == 0 && mx[a][z][i] < 8) {

                                                   

                                                    size_t max_z = mx[a][z][i];

                                                   

                                                    for (size_t j = 0; j < max_z; j++) {

                                                       

                                                        if (b[rlst[a][z][i][j] - 1] == 0) {

                                                        

                                                            和集合.push_back(rlst[a][z][i][j]);

                                                         

                                                            b[rlst[a][z][i][j] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                if (和集合.size() == 7) {

                                                    for (size_t j = 0; j < N; j++) {

                                                        if (j != t && j != u && j != v && j != w && j != x && j != y && j != z) {

                                                            if (m[a][j][i] == 0) {

                                                                wb[a][j][i][和集合[0] - 1] = 1;

                                                                wb[a][j][i][和集合[1] - 1] = 1;

                                                                wb[a][j][i][和集合[2] - 1] = 1;

                                                                wb[a][j][i][和集合[3] - 1] = 1;

                                                                wb[a][j][i][和集合[4] - 1] = 1;

                                                                wb[a][j][i][和集合[5] - 1] = 1;

                                                                wb[a][j][i][和集合[6] - 1] = 1;

                                                            }

                                                        }

                                                    }

                                                    for (size_t j = 0; j < N; j++) {

                                                        if (j != t && j != u && j != v && j != w && j != x && j != y && j != z) {

                                                            if (m[a][j][i] == 0) {

                                                                局所解析関数(j, i, a);

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 七対七確定および排除ブロック関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 7) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t t = 0; t < n; t++) {

               

                if (m[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)] == 0 && mx[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)] < 8) {

                   

                    size_t max_t = mx[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)];

                   

                    for (size_t j = 0; j < max_t; j++) {

                       

                        if (b[rlst[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)][j] - 1] == 0) {

                        

                            和集合.push_back(rlst[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)][j]);

                         

                            b[rlst[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)][j] - 1] = 1;

                        }

                    }

                    for (size_t u = 0; u < n; u++) {

                       

                        if (m[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)] == 0 && mx[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)] < 8) {

                           

                            size_t mau_u = mx[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)];

                           

                            for (size_t j = 0; j < mau_u; j++) {

                               

                                if (b[rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j] - 1] == 0) {

                                 

                                    和集合.push_back(rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j]);

                                

                                    b[rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j] - 1] = 1;

                                }

                            }

                            for (size_t v = 0; v < n; v++) {

                               

                                if (m[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] == 0 && mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] < 8) {

                                   

                                    size_t mav_v = mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)];

                                   

                                    for (size_t j = 0; j < mav_v; j++) {

                                       

                                        if (b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] == 0) {

                                          

                                            和集合.push_back(rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j]);

                                           

                                            b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t w = 0; w < n; w++) {

                                   

                                    if (m[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] == 0 && mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] < 8) {

                                       

                                        size_t maw_w = mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)];

                                       

                                        for (size_t j = 0; j < maw_w; j++) {

                                           

                                            if (b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] == 0) {

                                               

                                                和集合.push_back(rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j]);

                                               

                                                b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t x = 0; x < n; x++) {

                                       

                                        if (m[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] == 0 && mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] < 8) {

                                           

                                            size_t max_x = mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)];

                                           

                                            for (size_t j = 0; j < max_x; j++) {

                                               

                                                if (b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j]);

                                                   

                                                    b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t y = 0; y < n; y++) {

                                           

                                            if (m[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] == 0 && mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] < 8) {

                                               

                                                size_t max_y = mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)];

                                               

                                                for (size_t j = 0; j < max_y; j++) {

                                                   

                                                    if (b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] == 0) {

                                                     

                                                     

                                                        和集合.push_back(rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j]);

                                                        b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t z = 0; z < n; z++) {

                                               

                                                if (m[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] == 0 && mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] < 8) {

                                                   

                                                    size_t max_z = mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)];

                                                   

                                                    for (size_t j = 0; j < max_z; j++) {

                                                       

                                                        if (b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] == 0) {

                                                        

                                                            和集合.push_back(rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j]);

                                                        

                                                            b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                if (和集合.size() == 7) {

                                                    for (size_t j = 0; j < N; j++) {

                                                        if (j != t && j != u && j != v && j != w && j != x && j != y && j != z) {

                                                            if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[0] - 1] = 1;

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[1] - 1] = 1;

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[2] - 1] = 1;

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[3] - 1] = 1;

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[4] - 1] = 1;

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[5] - 1] = 1;

                                                                wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[6] - 1] = 1;

                                                            }

                                                        }

                                                    }

                                                    for (size_t j = 0; j < N; j++) {

                                                        if (j != t && j != u && j != v && j != w && j != x && j != y && j != z) {

                                                            if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                                局所解析関数(RN * (i / RN) + (j / RN), RN * (i % RN) + (j % RN), a);

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 七対七確定および排除関数(size_t a) {

 

    七対七確定および排除行関数(a);

 

    七対七確定および排除列関数(a);

 

    七対七確定および排除ブロック関数(a);

 

}

 

void 八対八確定および排除行関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 8) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t t = 0; t < n; t++) {

               

                if (m[a][i][t] == 0 && mx[a][i][t] < 9) {

                   

                    size_t max_t = mx[a][i][t];

                   

                    for (size_t j = 0; j < max_t; j++) {

                       

                        if (b[rlst[a][i][t][j] - 1] == 0) {

                         

                            和集合.push_back(rlst[a][i][t][j]);

                         

                            b[rlst[a][i][t][j] - 1] = 1;

                        }

                    }

                    for (size_t u = 0; u < n; u++) {

                       

                        if (m[a][i][u] == 0 && mx[a][i][u] < 9) {

                           

                            size_t mau_u = mx[a][i][u];

                           

                            for (size_t j = 0; j < mau_u; j++) {

                               

                                if (b[rlst[a][i][u][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][i][u][j]);

                                   

                                    b[rlst[a][i][u][j] - 1] = 1;

                                }

                            }

                            for (size_t v = 0; v < n; v++) {

                               

                                if (m[a][i][v] == 0 && mx[a][i][v] < 9) {

                                   

                                    size_t mav_v = mx[a][i][v];

                                   

                                    for (size_t j = 0; j < mav_v; j++) {

                                       

                                        if (b[rlst[a][i][v][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][i][v][j]);

                                          

                                            b[rlst[a][i][v][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t w = 0; w < n; w++) {

                                   

                                    if (m[a][i][w] == 0 && mx[a][i][w] < 9) {

                                       

                                        size_t maw_w = mx[a][i][w];

                                       

                                        for (size_t j = 0; j < maw_w; j++) {

                                           

                                            if (b[rlst[a][i][w][j] - 1] == 0) {

                                              

                                                和集合.push_back(rlst[a][i][w][j]);

                                              

                                                b[rlst[a][i][w][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t x = 0; x < n; x++) {

                                       

                                        if (m[a][i][x] == 0 && mx[a][i][x] < 9) {

                                           

                                            size_t max_x = mx[a][i][x];

                                           

                                            for (size_t j = 0; j < max_x; j++) {

                                               

                                                if (b[rlst[a][i][x][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][i][x][j]);

                                                   

                                                    b[rlst[a][i][x][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t y = 0; y < n; y++) {

                                           

                                            if (m[a][i][y] == 0 && mx[a][i][y] < 9) {

                                               

                                                size_t max_y = mx[a][i][y];

                                               

                                                for (size_t j = 0; j < max_y; j++) {

                                                  

                                                    if (b[rlst[a][i][y][j] - 1] == 0) {

                                                       

                                                        和集合.push_back(rlst[a][i][y][j]);

                                                      

                                                        b[rlst[a][i][y][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t z = 0; z < n; z++) {

                                               

                                                if (m[a][i][z] == 0 && mx[a][i][z] < 9) {

                                                   

                                                    size_t max_z = mx[a][i][z];

                                                   

                                                    for (size_t j = 0; j < max_z; j++) {

                                                       

                                                        if (b[rlst[a][i][z][j] - 1] == 0) {

                                                           

                                                            和集合.push_back(rlst[a][i][z][j]);

                                                           

                                                            b[rlst[a][i][z][j] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                for (size_t s = 0; s < n; s++) {

                                                   

                                                    if (m[a][i][s] == 0 && mx[a][i][s] < 9) {

                                                       

                                                        size_t max_s = mx[a][i][s];

                                                       

                                                        for (size_t j = 0; j < max_s; j++) {

                                                           

                                                            if (b[rlst[a][i][s][j] - 1] == 0) {

                                                              

                                                                和集合.push_back(rlst[a][i][s][j]);

                                                             

                                                                b[rlst[a][i][s][j] - 1] = 1;

                                                            }

                                                        }

                                                    }

                                                    if (和集合.size() == 8) {                                                       

                                                        for (size_t j = 0; j < N; j++) {

                                                            if (j != t && j != u && j != v && j != w && j != x && j != y && j != z && j != s) {

                                                                if (m[a][i][j] == 0) {

                                                                    wb[a][i][j][和集合[0] - 1] = 1;

                                                                    wb[a][i][j][和集合[1] - 1] = 1;

                                                                    wb[a][i][j][和集合[2] - 1] = 1;

                                                                    wb[a][i][j][和集合[3] - 1] = 1;

                                                                    wb[a][i][j][和集合[4] - 1] = 1;

                                                                    wb[a][i][j][和集合[5] - 1] = 1;

                                                                    wb[a][i][j][和集合[6] - 1] = 1;

                                                                    wb[a][i][j][和集合[7] - 1] = 1;

                                                                }

                                                            }

                                                        }

                                                        for (size_t j = 0; j < N; j++) {

                                                            if (j != t && j != u && j != v && j != w && j != x && j != y && j != z && j != s) {

                                                                if (m[a][i][j] == 0) {

                                                                    局所解析関数(i, j, a);

                                                                }

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 八対八確定および排除列関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 8) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t t = 0; t < n; t++) {

              

                if (m[a][t][i] == 0 && mx[a][t][i] < 9) {

                  

                    size_t max_t = mx[a][t][i];

                  

                    for (size_t j = 0; j < max_t; j++) {

                   

                        if (b[rlst[a][t][i][j] - 1] == 0) {

                   

                            和集合.push_back(rlst[a][t][i][j]);

                    

                            b[rlst[a][t][i][j] - 1] = 1;

                        }

                    }

                    for (size_t u = 0; u < n; u++) {

                       

                        if (m[a][u][i] == 0 && mx[a][u][i] < 9) {

                           

                            size_t mau_u = mx[a][u][i];

                           

                            for (size_t j = 0; j < mau_u; j++) {

                               

                                if (b[rlst[a][u][i][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][u][i][j]);

                                   

                                    b[rlst[a][u][i][j] - 1] = 1;

                                }

                            }

                            for (size_t v = 0; v < n; v++) {

                               

                                if (m[a][v][i] == 0 && mx[a][v][i] < 9) {

                                  

                                    size_t mav_v = mx[a][v][i];

                                   

                                    for (size_t j = 0; j < mav_v; j++) {

                                     

                                        if (b[rlst[a][v][i][j] - 1] == 0) {

                                         

                                            和集合.push_back(rlst[a][v][i][j]);

                                        

                                            b[rlst[a][v][i][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t w = 0; w < n; w++) {

                                   

                                    if (m[a][w][i] == 0 && mx[a][w][i] < 9) {

                                      

                                        size_t maw_w = mx[a][w][i];

                                       

                                        for (size_t j = 0; j < maw_w; j++) {

                                           

                                            if (b[rlst[a][w][i][j] - 1] == 0) {

                                              

                                                和集合.push_back(rlst[a][w][i][j]);

                                       

                                                b[rlst[a][w][i][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t x = 0; x < n; x++) {

                                       

                                        if (m[a][x][i] == 0 && mx[a][x][i] < 9) {

                                           

                                            size_t max_x = mx[a][x][i];

                                           

                                            for (size_t j = 0; j < max_x; j++) {

                                               

                                                if (b[rlst[a][x][i][j] - 1] == 0) {

                                                 

                                                    和集合.push_back(rlst[a][x][i][j]);

                                                 

                                                    b[rlst[a][x][i][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t y = 0; y < n; y++) {

                                           

                                            if (m[a][y][i] == 0 && mx[a][y][i] < 9) {

                                               

                                                size_t max_y = mx[a][y][i];

                                               

                                                for (size_t j = 0; j < max_y; j++) {

                                                   

                                                    if (b[rlst[a][y][i][j] - 1] == 0) {

                                                      

                                                        和集合.push_back(rlst[a][y][i][j]);

                                                       

                                                        b[rlst[a][y][i][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t z = 0; z < n; z++) {

                                               

                                                if (m[a][z][i] == 0 && mx[a][z][i] < 9) {

                                                   

                                                    size_t max_z = mx[a][z][i];

                                                   

                                                    for (size_t j = 0; j < max_z; j++) {

                                                       

                                                        if (b[rlst[a][z][i][j] - 1] == 0) {

                                                           

                                                            和集合.push_back(rlst[a][z][i][j]);

                                                           

                                                            b[rlst[a][z][i][j] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                for (size_t s = 0; s < n; s++) {

                                                   

                                                    if (m[a][s][i] == 0 && mx[a][s][i] < 9) {

                                                       

                                                        size_t max_s = mx[a][s][i];

                                                       

                                                        for (size_t j = 0; j < max_s; j++) {

                                                           

                                                            if (b[rlst[a][s][i][j] - 1] == 0) {

                                                              

                                                                和集合.push_back(rlst[a][s][i][j]);

                                                              

                                                                b[rlst[a][s][i][j] - 1] = 1;

                                                            }

                                                        }

                                                    }

                                                    if (和集合.size() == 8) {

                                                        for (size_t j = 0; j < N; j++) {

                                                            if (j != t && j != u && j != v && j != w && j != x && j != y && j != z && j != s) {

                                                                if (m[a][j][i] == 0) {

                                                                    wb[a][j][i][和集合[0] - 1] = 1;

                                                                    wb[a][j][i][和集合[1] - 1] = 1;

                                                                    wb[a][j][i][和集合[2] - 1] = 1;

                                                                    wb[a][j][i][和集合[3] - 1] = 1;

                                                                    wb[a][j][i][和集合[4] - 1] = 1;

                                                                    wb[a][j][i][和集合[5] - 1] = 1;

                                                                    wb[a][j][i][和集合[6] - 1] = 1;

                                                                    wb[a][j][i][和集合[7] - 1] = 1;

                                                                }

                                                            }

                                                        }

                                                        for (size_t j = 0; j < N; j++) {

                                                            if (j != t && j != u && j != v && j != w && j != x && j != y && j != z && j != s) {

                                                                if (m[a][j][i] == 0) {

                                                                    局所解析関数(j, i, a);

                                                                }

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 八対八確定および排除ブロック関数(size_t a) {

    for (size_t i = 0; i < N; i++) {

        size_t n = 行値0番号集合[i].size();

        if (n >= 8) {

            vector<int> 和集合;

            size_t b[N] = { 0 };//値の重複を防ぐための配列

            for (size_t t = 0; t < n; t++) {

               

                if (m[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)] == 0 && mx[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)] < 9) {

                   

                    size_t max_t = mx[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)];

                   

                    for (size_t j = 0; j < max_t; j++) {

                       

                        if (b[rlst[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)][j] - 1] == 0) {

                          

                            和集合.push_back(rlst[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)][j]);

                          

                            b[rlst[a][RN * (i / RN) + (t / RN)][RN * (i % RN) + (t % RN)][j] - 1] = 1;

                        }

                    }

                    for (size_t u = 0; u < n; u++) {

                       

                        if (m[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)] == 0 && mx[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)] < 9) {

                          

                            size_t mau_u = mx[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)];

                           

                            for (size_t j = 0; j < mau_u; j++) {

                               

                                if (b[rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j] - 1] == 0) {

                                   

                                    和集合.push_back(rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j]);

                                   

                                    b[rlst[a][RN * (i / RN) + (u / RN)][RN * (i % RN) + (u % RN)][j] - 1] = 1;

                                }

                            }

                            for (size_t v = 0; v < n; v++) {

                               

                                if (m[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] == 0 && mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)] < 9) {

                                   

                                    size_t mav_v = mx[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)];

                                   

                                    for (size_t j = 0; j < mav_v; j++) {

                                       

                                        if (b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] == 0) {

                                           

                                            和集合.push_back(rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j]);

                                           

                                            b[rlst[a][RN * (i / RN) + (v / RN)][RN * (i % RN) + (v % RN)][j] - 1] = 1;

                                        }

                                    }

                                }

                                for (size_t w = 0; w < n; w++) {

                                   

                                    if (m[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] == 0 && mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)] < 9) {

                                      

                                        size_t maw_w = mx[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)];

                                       

                                        for (size_t j = 0; j < maw_w; j++) {

                                           

                                            if (b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] == 0) {

                                              

                                                和集合.push_back(rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j]);

                                               

                                                b[rlst[a][RN * (i / RN) + (w / RN)][RN * (i % RN) + (w % RN)][j] - 1] = 1;

                                            }

                                        }

                                    }

                                    for (size_t x = 0; x < n; x++) {

                                       

                                        if (m[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] == 0 && mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)] < 9) {

                                           

                                            size_t max_x = mx[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)];

                                           

                                            for (size_t j = 0; j < max_x; j++) {

                                               

                                                if (b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] == 0) {

                                                   

                                                    和集合.push_back(rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j]);

                                                   

                                                    b[rlst[a][RN * (i / RN) + (x / RN)][RN * (i % RN) + (x % RN)][j] - 1] = 1;

                                                }

                                            }

                                        }

                                        for (size_t y = 0; y < n; y++) {

                                           

                                            if (m[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] == 0 && mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)] < 9) {

                                               

                                                size_t max_y = mx[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)];

                                               

                                                for (size_t j = 0; j < max_y; j++) {

                                                   

                                                    if (b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] == 0) {

                                                       

                                                        和集合.push_back(rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j]);

                                                       

                                                        b[rlst[a][RN * (i / RN) + (y / RN)][RN * (i % RN) + (y % RN)][j] - 1] = 1;

                                                    }

                                                }

                                            }

                                            for (size_t z = 0; z < n; z++) {

                                               

                                                if (m[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] == 0 && mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)] < 9) {

                                                   

                                                    size_t max_z = mx[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)];

                                                   

                                                    for (size_t j = 0; j < max_z; j++) {

                                                      

                                                        if (b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] == 0) {

                                                           

                                                            和集合.push_back(rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j]);

                                                          

                                                            b[rlst[a][RN * (i / RN) + (z / RN)][RN * (i % RN) + (z % RN)][j] - 1] = 1;

                                                        }

                                                    }

                                                }

                                                for (size_t s = 0; s < n; s++) {

                                                   

                                                    if (m[a][RN * (i / RN) + (s / RN)][RN * (i % RN) + (s % RN)] == 0 && mx[a][RN * (i / RN) + (s / RN)][RN * (i % RN) + (s % RN)] < 9) {

                                                       

                                                        size_t max_s = mx[a][RN * (i / RN) + (s / RN)][RN * (i % RN) + (s % RN)];

                                                       

                                                        for (size_t j = 0; j < max_s; j++) {

                                                           

                                                            if (b[rlst[a][RN * (i / RN) + (s / RN)][RN * (i % RN) + (s % RN)][j] - 1] == 0) {

                                                              

                                                                和集合.push_back(rlst[a][RN * (i / RN) + (s / RN)][RN * (i % RN) + (s % RN)][j]);

                                                              

                                                                b[rlst[a][RN * (i / RN) + (s / RN)][RN * (i % RN) + (s % RN)][j] - 1] = 1;

                                                            }

                                                        }

                                                    }

                                                    if (和集合.size() == 8) {

                                                        for (size_t j = 0; j < N; j++) {

                                                            if (j != t && j != u && j != v && j != w && j != x && j != y && j != z && j != s) {

                                                                if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[0] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[1] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[2] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[3] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[4] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[5] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[6] - 1] = 1;

                                                                    wb[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)][和集合[7] - 1] = 1;

                                                                }

                                                            }

                                                        }

                                                        for (size_t j = 0; j < N; j++) {

                                                            if (j != t && j != u && j != v && j != w && j != x && j != y && j != z && j != s) {

                                                                if (m[a][RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                                                                    局所解析関数(RN * (i / RN) + (j / RN), RN * (i % RN) + (j % RN), a);

                                                                }

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

 

void 八対八確定および排除関数(size_t a) {

 

    八対八確定および排除行関数(a);

 

    八対八確定および排除列関数(a);

 

    八対八確定および排除ブロック関数(a);

 

}

 

void #排除関数(size_t a) {

 

    size_t i, j, wx, wy, k;

 

    size_t yk[N][N], xk[N][N];

 

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

 

        wy = 0;

 

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

 

            wx = 0;

 

            for (k = 0; k < N; k++) {

 

                if (m[a][j][k] == 0) {

 

                    if (wb[a][j][k][i] == 0) {

 

                        yk[wy][wx] = j;

 

                        xk[wy][wx] = k;

 

                        wx = wx + 1;

 

                    }

 

                }

 

            }

 

            if (wx == 2) {

 

                wy = wy + 1;

 

            }

 

        }

 

        if (wy == 2) {

 

            if (xk[0][0] == xk[1][0] && xk[0][1] == xk[1][1]) {

 

                for (k = 0; k < N; k++) {

 

                    if (k != xk[0][0] && k != xk[0][1]) {

 

                        if (m[a][yk[0][0]][k] == 0) {

 

                            wb[a][yk[0][0]][k][i] = 1;

 

                        }

 

                        if (m[a][yk[1][1]][k] == 0) {

 

                            wb[a][yk[1][1]][k][i] = 1;

 

                        }

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (k != xk[0][0] && k != xk[0][1]) {

 

                        if (m[a][yk[0][0]][k] == 0) {

 

                            局所解析関数(yk[0][0], k, a);

 

                        }

 

                        if (m[a][yk[1][1]][k] == 0) {

 

                            局所解析関数(yk[1][1], k, a);

 

                        }

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (k != yk[0][0] && k != yk[1][1]) {

 

                        if (m[a][k][xk[0][0]] == 0) {

 

                            wb[a][k][xk[0][0]][i] = 1;

 

                        }

 

                        if (m[a][k][xk[1][1]] == 0) {

 

                            wb[a][k][xk[1][1]][i] = 1;

 

                        }

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (k != yk[0][0] && k != yk[1][1]) {

 

                        if (m[a][k][xk[0][0]] == 0) {

 

                            局所解析関数(k, xk[0][0], a);

 

                        }

 

                        if (m[a][k][xk[1][1]] == 0) {

 

                            局所解析関数(k, xk[1][1], a);

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

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

 

        wx = 0;

 

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

 

            wy = 0;

 

            for (k = 0; k < N; k++) {

 

                if (m[a][k][j] == 0) {

 

                    if (wb[a][k][j][i] == 0) {

 

                        yk[wx][wy] = k;

 

                        xk[wx][wy] = j;

 

                        wy = wy + 1;

 

                    }

 

                }

 

            }

 

            if (wy == 2) {

 

                wx = wx + 1;

 

            }

 

        }

 

        if (wx == 2) {

 

            if (yk[0][0] == yk[1][0] && yk[0][1] == yk[1][1]) {

 

                for (k = 0; k < N; k++) {

 

                    if (k != yk[0][0] && k != yk[0][1]) {

 

                        if (m[a][k][xk[0][0]] == 0) {

 

                            wb[a][k][xk[0][0]][i] = 1;

 

                        }

 

                        if (m[a][k][xk[1][1]] == 0) {

 

                            wb[a][k][xk[1][1]][i] = 1;

 

                        }

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (k != yk[0][0] && k != yk[1][1]) {

 

                        if (m[a][k][xk[0][0]] == 0) {

 

                            局所解析関数(k, xk[0][0], a);

 

                        }

 

                        if (m[a][k][xk[1][1]] == 0) {

 

                            局所解析関数(k, xk[1][1], a);

 

                        }

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (k != xk[0][0] && k != xk[1][1]) {

 

                        if (m[a][yk[0][0]][k] == 0) {

 

                            wb[a][yk[0][0]][k][i] = 1;

 

                        }

 

                        if (m[a][yk[1][1]][k] == 0) {

 

                            wb[a][yk[1][1]][k][i] = 1;

 

                        }

 

                    }

 

                }

 

                for (k = 0; k < N; k++) {

 

                    if (k != xk[0][0] && k != xk[1][1]) {

 

                        if (m[a][yk[0][0]][k] == 0) {

 

                            局所解析関数(yk[0][0], k, a);

 

                        }

 

                        if (m[a][yk[1][1]][k] == 0) {

 

                            局所解析関数(yk[1][1], k, a);

 

                        }

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void リスト法関数(size_t a) {

 

    size_t i, j, k, s, t;

 

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

 

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

 

            if (m[a][i][j] == 0) {

 

                if (mx[a][i][j] == 0) {

 

                    cn[a] = 2;

 

                    return;

 

                }

 

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

 

                    m[a][i][j] = rlst[a][i][j][0];

 

                    空欄数[a] = 空欄数[a] - 1;

 

                    if (空欄数[a] == 0)return;

 

                    for (k = 0; k < N; k++) {

 

                        if (m[a][i][k] == 0) {

 

                            wb[a][i][k][m[a][i][j] - 1] = 1;

 

                        }

 

                        if (m[a][k][j] == 0) {

 

                            wb[a][k][j][m[a][i][j] - 1] = 1;

 

                        }

 

                        s = RN * (i / RN) + (k / RN);

 

                        t = RN * (j / RN) + (k % RN);

 

                        if (m[a][s][t] == 0) {

 

                            wb[a][s][t][m[a][i][j] - 1] = 1;

 

                        }

 

                    }

 

                    for (k = 0; k < N; k++) {

 

                        if (m[a][i][k] == 0) 局所解析関数(i, k, a);

 

                        if (m[a][k][j] == 0) 局所解析関数(k, j, a);

 

                        s = RN * (i / RN) + (k / RN);

 

                        t = RN * (j / RN) + (k % RN);

 

                        if (m[a][s][t] == 0) 局所解析関数(s, t, a);

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 非対称配列関数(size_t a) {

 

    size_t sss = rand() % (N * N);

 

    size_t rnk;

 

    size_t g = rand() % 26;

 

    if (g <= 10)rnk = 2;

 

    if (g == 11)rnk = 3;

 

    if (g == 12)rnk = 4;

 

    if (g == 13)rnk = 6;

 

    if (g == 14)rnk = 7;

 

    if (g == 15)rnk = 8;

 

    if (g == 16)rnk = 9;

 

    if (g == 17)rnk = 11;

 

    if (g == 18)rnk = 12;

 

    if (g == 19)rnk = 13;

 

    if (g == 20)rnk = 14;

 

    if (g == 21)rnk = 16;

 

    if (g == 22)rnk = 17;

 

    if (g == 23)rnk = 18;

 

    if (g == 24)rnk = 19;

 

    if (g == 25)rnk = 21;

 

    if (g == 26)rnk = 22;

 

    if (g == 27)rnk = 23;

 

    if (g == 28)rnk = 24;

 

    if (g == 19)rnk = 26;

 

    if (g == 20)rnk = 27;

 

    if (g == 21)rnk = 28;

 

    if (g == 22)rnk = 29;

 

    if (g == 23)rnk = 31;

 

    if (g == 24)rnk = 137;

 

    if (g == 25)rnk = 139;

 

 

 

    for (size_t i = 0; i < N * N; i++) {

 

        yy[a][i] = ((i * rnk + sss) % (N * N)) / N;

 

        xx[a][i] = ((i * rnk + sss) % (N * N)) % N;

 

    }

 

}

 

void 左右対称配列関数(size_t a) {

 

    size_t ty, gz;

 

    if (ヒント数 % 2 == 0) {

 

        gz = rand() % 27;

 

        if (gz >= 0 && gz < 5)ty = 12;

 

        if (gz >= 5 && gz < 9)ty = 10;

 

        if (gz >= 9 && gz < 12)ty = 8;

 

        if (gz >= 12 && gz < 14)ty = 6;

 

        if (gz == 14)ty = 4;

 

        if (gz == 15)ty = 2;

 

        if (gz == 16)ty = 0;

 

        if (gz >= 17 && gz < 21)ty = 14;

 

        if (gz >= 21 && gz < 24)ty = 16;

 

        if (gz >= 24 && gz < 26)ty = 18;

 

        if (gz == 24)ty = 20;

 

        if (gz == 25)ty = 22;

 

        if (gz == 26)ty = 24;

 

    }

 

    else {

 

        gz = rand() % 27;

 

        if (gz >= 0 && gz < 5)ty = 13;

 

        if (gz >= 5 && gz < 9)ty = 11;

 

        if (gz >= 9 && gz < 12)ty = 9;

 

        if (gz >= 12 && gz < 14)ty = 7;

 

        if (gz == 14)ty = 5;

 

        if (gz == 15)ty = 3;

 

        if (gz == 16)ty = 1;

 

        if (gz >= 17 && gz < 21)ty = 15;

 

        if (gz >= 21 && gz < 24)ty = 17;

 

        if (gz >= 24 && gz < 26)ty = 19;

 

        if (gz == 24)ty = 21;

 

        if (gz == 25)ty = 23;

 

        if (gz == 26)ty = 25;

 

    }

 

    gz = rand() % 6;

 

    size_t tyrnk;

 

    if (gz == 0) tyrnk = 2;

 

    if (gz == 1) tyrnk = 3;

 

    if (gz == 2) tyrnk = 4;

 

    if (gz == 3) tyrnk = 6;

 

    if (gz == 4) tyrnk = 7;

 

    if (gz == 5) tyrnk = 9;

 

    size_t ss = rand() % N;

 

    size_t sss = rand() % ((N * (N - 1)) / 2);

 

    size_t rnk = rand() % N;   // 024の範囲で初期化

 

    gz = rand() % 20;

 

    if (gz == 0)rnk = 7;

 

    if (gz == 1)rnk = 11;

 

    if (gz == 2)rnk = 13;

 

    if (gz == 3)rnk = 17;

 

    if (gz == 4)rnk = 19;

 

    if (gz == 5)rnk = 23;

 

    if (gz == 6)rnk = 29;

 

    if (gz == 7)rnk = 31;

 

    if (gz == 8)rnk = 37;

 

    if (gz == 9)rnk = 41;

 

    if (gz == 20)rnk = 43;

 

    if (gz == 21)rnk = 47;

 

    if (gz == 22)rnk = 53;

 

    for (size_t i = 0; i < ((ヒント数 - ty) / 2); i++) {

 

        for (size_t i = 0; i < (ヒント数 - ty) / 2; i++) {

 

            xx[a][i] = ((i * rnk + sss) % ((N * (N - 1)) / 2)) / N;

 

            xx[a][ヒント数 - 1 - i] = 8 - xx[a][i];

 

            yy[a][i] = ((i * rnk + sss) % (N * (N - 1)) / 2) % N;

 

            yy[a][ヒント数 - 1 - i] = yy[a][i];

 

        }

 

    }

 

    for (size_t i = 0; i < ty; i++) {

 

        xx[a][i + (ヒント数 - ty) / 2] = 12;

 

        yy[a][i + (ヒント数 - ty) / 2] = (i * tyrnk + ss) % N;

 

    }

 

}

 

void 上下対称配列関数(size_t a) {

 

    size_t ty, gz;

 

    if (ヒント数 % 2 == 0) {

 

        gz = rand() % 27;

 

        if (gz >= 0 && gz < 5)ty = 12;

 

        if (gz >= 5 && gz < 9)ty = 10;

 

        if (gz >= 9 && gz < 12)ty = 8;

 

        if (gz >= 12 && gz < 14)ty = 6;

 

        if (gz == 14)ty = 4;

 

        if (gz == 15)ty = 2;

 

        if (gz == 16)ty = 0;

 

        if (gz >= 17 && gz < 21)ty = 14;

 

        if (gz >= 21 && gz < 24)ty = 16;

 

        if (gz >= 24 && gz < 26)ty = 18;

 

        if (gz == 24)ty = 20;

 

        if (gz == 25)ty = 22;

 

        if (gz == 26)ty = 24;

 

    }

 

    else {

 

        gz = rand() % 27;

 

        if (gz >= 0 && gz < 5)ty = 13;

 

        if (gz >= 5 && gz < 9)ty = 11;

 

        if (gz >= 9 && gz < 12)ty = 9;

 

        if (gz >= 12 && gz < 14)ty = 7;

 

        if (gz == 14)ty = 5;

 

        if (gz == 15)ty = 3;

 

        if (gz == 16)ty = 1;

 

        if (gz >= 17 && gz < 21)ty = 15;

 

        if (gz >= 21 && gz < 24)ty = 17;

 

        if (gz >= 24 && gz < 26)ty = 19;

 

        if (gz == 24)ty = 21;

 

        if (gz == 25)ty = 23;

 

        if (gz == 26)ty = 25;

 

    }

 

    gz = rand() % 6;

 

    size_t tyrnk;

 

    if (gz == 0) tyrnk = 2;

 

    if (gz == 1) tyrnk = 3;

 

    if (gz == 2) tyrnk = 4;

 

    if (gz == 3) tyrnk = 6;

 

    if (gz == 4) tyrnk = 7;

 

    if (gz == 5) tyrnk = 9;

 

    size_t ss = rand() % N;

 

    size_t sss = rand() % ((N * (N - 1)) / 2);

 

    size_t rnk = rand() % N;   // 024の範囲で初期化

 

    gz = rand() % 20;

 

    if (gz == 0)rnk = 7;

 

    if (gz == 1)rnk = 11;

 

    if (gz == 2)rnk = 13;

 

    if (gz == 3)rnk = 17;

 

    if (gz == 4)rnk = 19;

 

    if (gz == 5)rnk = 23;

 

    if (gz == 6)rnk = 29;

 

    if (gz == 7)rnk = 31;

 

    if (gz == 8)rnk = 37;

 

    if (gz == 9)rnk = 41;

 

    if (gz == 20)rnk = 43;

 

    if (gz == 21)rnk = 47;

 

    if (gz == 22)rnk = 53;

 

    for (size_t i = 0; i < ((ヒント数 - ty) / 2); i++) {

 

        yy[a][i] = ((i * rnk + sss) % ((N * (N - 1)) / 2)) / N;

 

        yy[a][ヒント数 - 1 - i] = 24 - xx[a][i];

 

        xx[a][i] = ((i * rnk + sss) % ((N * (N - 1)) / 2)) % N;

 

        xx[a][ヒント数 - 1 - i] = yy[a][i];

 

    }

 

    for (size_t i = 0; i < ty; i++) {

 

        yy[a][i + (ヒント数 - ty) / 2] = 12;

 

        xx[a][i + (ヒント数 - ty) / 2] = (i * tyrnk + ss) % N;

 

    }

 

}

 

void 点対称配列関数(size_t a) {

 

    size_t s, rnk, sss;

 

    rnk = rand() % N;

 

    s = rand() % 21;

 

    if (s == 0) rnk = 7;

 

    if (s == 1) rnk = 11;

 

    if (s == 2) rnk = 13;

 

    if (s == 3) rnk = 17;

 

    if (s == 4) rnk = 19;

 

    if (s == 5) rnk = 23;

 

    if (s == 6) rnk = 29;

 

    if (s == 7) rnk = 31;

 

    if (s == 8) rnk = 37;

 

    if (s == 9) rnk = 41;

 

    if (s == 10) rnk = 43;

 

    if (s == 11) rnk = 44;

 

    if (s == 10) rnk = 46;

 

    if (s == 11) rnk = 47;

 

    if (s == 12) rnk = 48;

 

    if (s == 13) rnk = 49;

 

    if (s == 14) rnk = 51;

 

    if (s == 15) rnk = 52;

 

    if (s == 16) rnk = 53;

 

    if (s == 17) rnk = 54;

 

    if (s == 18) rnk = 56;

 

    if (s == 19) rnk = 57;

 

    if (s == 20) rnk = 58;

 

    while (1) {

 

        s = rand() % (ヒント数 / N + 2);

 

        if ((ヒント数 - s) % 2 == 0) break;

 

    }

 

    sss = rand() * 625;

 

    if (ヒント数 % 2 == 0) {

 

        for (size_t i = 0; i < ヒント数 / 2; i++) {

 

            yy[a][i] = ((i * rnk + sss) % 625) / N;

 

            yy[a][ヒント数 - 1 - i] = 24 - yy[a][i];

 

            xx[a][i] = ((i * rnk + sss) % 625) % N;

 

            xx[a][ヒント数 - 1 - i] = 24 - xx[a][i];

 

        }

 

    }

 

    else {

 

        for (size_t i = 0; i < ヒント数 / 2; i++) {

 

            yy[a][i] = ((i * rnk + sss) % 625) / N;

 

            yy[a][ヒント数 - 1 - i] = 24 - yy[a][i];

 

            xx[a][i] = ((i * rnk + sss) % 625) % N;

 

            xx[a][ヒント数 - 1 - i] = 24 - xx[a][i];

 

        }

 

        yy[a][(ヒント数 - 1) / 2] = 12;

 

        xx[a][(ヒント数 - 1) / 2] = 12;

 

    }

 

}

 

void 左右上下対称配列関数(size_t a) {

 

    size_t sss, b, rnk, s, mns;

 

    size_t kh[16];

 

    if (ヒント数 % 2 == 0) {

 

        if (ヒント数 % 4 == 0) {

 

            s = rand() % 5;

 

            if (s == 0) rnk = 3;

 

            if (s == 1) rnk = 5;

 

            if (s == 2) rnk = 7;

 

            if (s == 3) rnk = 11;

 

            if (s == 4) rnk = 13;

 

            sss = rand() % 16;

 

            b = ヒント数 / 4 - 1;

 

            for (size_t i = 0; i < b + 1; i++) {

 

                kh[i] = (sss + rnk * i) % 16;

 

            }

 

            for (size_t i = 0; i < b + 1; i++) {

 

                yy[a][i] = kh[i] / 4;

 

                xx[a][i] = kh[i] % 4;

 

                yy[a][2 * (b + 1) - i - 1] = yy[a][i];

 

                xx[a][2 * (b + 1) - i - 1] = 8 - xx[a][i];

 

                yy[a][3 * (b + 1) - i - 1] = 8 - yy[a][i];

 

                xx[a][3 * (b + 1) - i - 1] = xx[a][i];

 

                yy[a][4 * (b + 1) - i - 1] = 8 - yy[a][i];

 

                xx[a][4 * (b + 1) - i - 1] = 8 - xx[a][i];

 

            }

 

            return;

 

        }

 

        s = rand() % 3;

 

        if (s < 2) mns = 1; else mns = 3;

 

        s = rand() % 4;

 

        for (size_t i = 0; i < mns + 1; i++) {

 

            xx[a][i] = 4;

 

            xx[a][2 * mns - 1 - i] = 4;

 

            yy[a][i] = (s + 3 * i) % 4;

 

            yy[a][2 * mns - 1 - i] = 8 - yy[a][i];

 

        }

 

        b = (ヒント数 - 2 * mns) / 4 - 1;

 

        s = rand() % 5;

 

        if (s == 0) rnk = 3;

 

        if (s == 1) rnk = 5;

 

        if (s == 2) rnk = 7;

 

        if (s == 3) rnk = 11;

 

        if (s == 4) rnk = 13;

 

        sss = rand() % 16;

 

        for (size_t i = 0; i < b + 1; i++) {

 

            kh[i] = (sss + rnk * i) % 16;

 

        }

 

        for (size_t i = 0; i < b + 1; i++) {

 

            yy[a][2 * mns + i] = kh[i] / 4;

 

            xx[a][2 * mns + i] = kh[i] % 4;

 

            yy[a][2 * mns + 2 * (b + 1) - i - 1] = yy[a][2 * mns + i];

 

            xx[a][2 * mns + 2 * (b + 1) - i - 1] = 8 - xx[a][2 * mns + i];

 

            yy[a][2 * mns + 3 * (b + 1) - i - 1] = 8 - yy[a][2 * mns + i];

 

            xx[a][2 * mns + 3 * (b + 1) - i - 1] = xx[a][2 * mns + i];

 

            yy[a][2 * mns + 4 * (b + 1) - i - 1] = 8 - yy[a][2 * mns + i];

 

            xx[a][2 * mns + 4 * (b + 1) - i - 1] = 8 - xx[a][2 * mns + i];

 

        }

 

        return;

 

    }

 

    if (ヒント数 % 2 == 1) {

 

        xx[a][0] = 4;

 

        yy[a][0] = 4;

 

        if (((ヒント数 - 1) % 4) == 0) {

 

            s = rand() % 5;

 

            if (s == 0) rnk = 3;

 

            if (s == 1) rnk = 5;

 

            if (s == 2) rnk = 7;

 

            if (s == 3) rnk = 11;

 

            if (s == 4) rnk = 13;

 

            sss = rand() % 16;

 

            b = (ヒント数 - 1) / 4 - 1;

 

            for (size_t i = 0; i < b + 1; i++) {

 

                kh[i] = (sss + rnk * i) % 16;

 

            }

 

            for (size_t i = 0; i < b + 1; i++) {

 

                yy[a][1 + i] = kh[i] / 4;

 

                xx[a][1 + i] = kh[i] % 4;

 

                yy[a][1 + 2 * (b + 1) - i - 1] = yy[a][1 + i];

 

                xx[a][1 + 2 * (b + 1) - i - 1] = 8 - xx[a][1 + i];

 

                yy[a][1 + 3 * (b + 1) - i - 1] = 8 - yy[a][1 + i];

 

                xx[a][1 + 3 * (b + 1) - i - 1] = xx[a][1 + i];

 

                yy[a][1 + 4 * (b + 1) - i - 1] = 8 - yy[a][1 + i];

 

                xx[a][1 + 4 * (b + 1) - i - 1] = 8 - xx[a][1 + i];

 

            }

 

            return;

 

        }

 

        s = rand() % 3;

 

        if (s < 2) mns = 1; else mns = 3;

 

        s = rand() % 4;

 

        mns = 3;

 

        for (size_t i = 0; i < mns; i++) {

 

            xx[a][1 + i] = 4;

 

            xx[a][1 + 2 * mns - 1 - i] = 4;

 

            yy[a][1 + i] = (s + 3 * i) % 4;

 

            yy[a][1 + 2 * mns - 1 - i] = 8 - yy[a][1 + i];

 

        }

 

        b = (ヒント数 - 1 - 2 * mns) / 4 - 1;

 

        s = rand() % 4;

 

        if (s == 0) rnk = 3;

 

        if (s == 1) rnk = 5;

 

        if (s == 2) rnk = 7;

 

        if (s == 3) rnk = 11;

 

        sss = rand() % 16;

 

        for (size_t i = 0; i < b + 1; i++) {

 

            kh[i] = (sss + rnk * i) % 16;

 

        }

 

        for (size_t i = 0; i < b + 1; i++) {

 

            yy[a][1 + 2 * mns + i] = kh[i] / 4;

 

            xx[a][1 + 2 * mns + i] = kh[i] % 4;

 

            yy[a][1 + 2 * mns + 2 * (b + 1) - i - 1] = yy[a][1 + 2 * mns + i];

 

            xx[a][1 + 2 * mns + 2 * (b + 1) - i - 1] = 8 - xx[a][1 + 2 * mns + i];

 

            yy[a][1 + 2 * mns + 3 * (b + 1) - i - 1] = 8 - yy[a][1 + 2 * mns + i];

 

            xx[a][1 + 2 * mns + 3 * (b + 1) - i - 1] = xx[a][1 + 2 * mns + i];

 

            yy[a][1 + 2 * mns + 4 * (b + 1) - i - 1] = 8 - yy[a][1 + 2 * mns + i];

 

            xx[a][1 + 2 * mns + 4 * (b + 1) - i - 1] = 8 - xx[a][1 + 2 * mns + i];

 

        }

 

    }

 

}

 

void ハート型配列関数(size_t a) {

 

    size_t b[N - 1][N - 1];

 

    for (size_t i = 0; i < 5; i++) {

 

        yy[a][i] = 8 - i;

 

        xx[a][i] = 4 - i;

 

    }

 

    for (size_t i = 5; i < N; i++) {

 

        yy[a][i] = yy[a][i - 4];

 

        xx[a][i] = 8 - xx[a][i - 4];

 

    }

 

    yy[a][N] = 3;

 

    xx[a][N] = 0;

 

    yy[a][10] = 3;

 

    xx[a][10] = 8;

 

    for (size_t i = 11; i < 13; i++) {

 

        yy[a][i] = 13 - i;

 

        xx[a][i] = i - 11;

 

        yy[a][i + 2] = yy[a][i];

 

        xx[a][i + 2] = 8 - xx[a][i];

 

    }

 

    for (size_t i = 15; i < 17; i++) {

 

        yy[a][i] = i - 14;

 

        xx[a][i] = i - 13;

 

        yy[a][i + 2] = yy[a][i];

 

        xx[a][i + 2] = 8 - xx[a][i];

 

    }

 

    yy[a][19] = 3;

 

    xx[a][19] = 4;

 

    for (size_t i = 0; i < 20; i++) {

 

        b[yy[a][i]][xx[a][i]] = 10;

 

    }

 

    size_t sa, h;

 

    sa = ヒント数 - 20;

 

    for (size_t i = 1; i < 8; i++) {

 

        h = 0;

 

        for (size_t j = 1; j < N; j++) {

 

            if (b[j - 1][i] == 10)  h = h + 1;

 

            if (h == 1 && b[j][i] != 10)  b[j][i] = 3;

 

        }

 

    }

 

    size_t k, i, j;

 

    if (ヒント数 % 2 == 0) {

 

        for (size_t k = 20; k < 20 + sa / 2; k++) {

 

            while (1) {

 

                i = rand() % N;

 

                j = rand() % 4;

 

                if (b[i][j] == 3) {

 

                    b[i][j] = 4;

 

                    b[i][8 - j] = 4;

 

                    yy[a][k] = i;

 

                    xx[a][k] = j;

 

                    yy[a][k + sa / 2] = i;

 

                    xx[a][k + sa / 2] = 8 - j;

 

                    break;

 

                }

 

            }

 

        }

 

        return;

 

    }

 

    else {

 

        while (1) {

 

            j = 4 + rand() % 4;

 

            if (b[j][4] == 3) {

 

                b[j][4] = 4;

 

                yy[a][20] = j;

 

                xx[a][20] = 4;

 

                break;

 

            }

 

        }

 

        if (ヒント数 > 21) {

 

            for (size_t i = 21; i < 21 + (ヒント数 - 21) / 2; i++) {

 

                size_t s, t;

 

                while (1) {

 

                    s = rand() % N;

 

                    t = rand() % 4;

 

                    if (b[s][t] == 3) {

 

                        b[s][t] = 4;

 

                        b[s][8 - t] = 4;

 

                        yy[a][i] = s;

 

                        xx[a][i] = t;

 

                        yy[a][i + (ヒント数 - 21) / 2] = s;

 

                        xx[a][i + (ヒント数 - 21) / 2] = 8 - t;

 

                        break;

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

void 代入関数(size_t a) {

 

    for (size_t i = 0; i < N2; i++) {

 

        cm[a][yy[a][i]][xx[a][i]] = m[a][yy[a][i]][xx[a][i]];

 

    }

 

}

 

void 色塗り関数(size_t a) {

 

    初期化1(a);

 

    for (size_t i = 0; i < ヒント数; i++) {

 

        size_t s, t;

 

        s = yy[a][i];

 

        t = xx[a][i];

 

        m[a][s][t] = cm[a][s][t];

 

        for (size_t j = 0; j < N; j++) {

 

            if (m[a][s][j] == 0) {

 

                if (wb[a][s][j][m[a][s][t] - 1] == 0) {

 

                    wb[a][s][j][m[a][s][t] - 1] = 1;

 

                }

 

            }

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            if (m[a][j][t] == 0) {

 

                if (wb[a][j][t][m[a][s][t] - 1] == 0) {

 

                    wb[a][j][t][m[a][s][t] - 1] = 1;

 

                }

 

            }

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            size_t p, q;

 

            p = RN * (s / RN) + (j / RN);

 

            q = RN * (t / RN) + (j % RN);

 

            if (p != s && q != t) {

 

                if (m[a][p][q] == 0) {

 

                    if (wb[a][p][q][m[a][s][t] - 1] == 0) {

 

                        wb[a][p][q][m[a][s][t] - 1] = 1;

 

                    }

 

                }

 

            }

 

        }

 

    }

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            if (m[a][i][j] == 0)局所解析関数(i, j, a);

 

        }

 

    }

 

}

 

void 0収集関数(size_t a) {

    //各行の空欄番号を集める

    for (size_t i = 0; i < N; i++) {

        for (size_t j = 0; j < N; j++) {

            if (m[i][j] == 0) {

                行値0番号集合[i].push_back(j);  // i 行の空欄セルとして j を追加

            }

        }

    }

    //各列の空欄番号を集める

    for (size_t i = 0; i < N; i++) {

        for (size_t j = 0; j < N; j++) {

            if (m[i][j] == 0) {

                列値0番号集合[i].push_back(j);  // i 列の空欄セルとして j を追加

            }

        }

    }

    //各ブロックの空欄番号を集める

    for (size_t i = 0; i < N; i++) {//iはブロック番号

        for (size_t j = 0; j < N; j++) {//jはブロック内番号

            if (m[RN * (i / RN) + (j / RN)][RN * (i % RN) + (j % RN)] == 0) {

                ブロック値0番号集合[i].push_back(j);  //ブロック番号i内のブロック内番号取得

                //(i,j)は通常の座標では

                // (RN * (i / RN) + (j / RN),RN * (i % RN) + (j % RN))

                // に対応する

            }

        }

    }

}

 

void 初期化0(size_t a) {

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            m[a][i][j] = 0;

 

            cm[a][i][j] = 0;

 

            mx[a][i][j] = N;

 

            for (size_t k = 0; k < N; k++) {

 

                wb[a][i][j][k] = 0;

 

            }

 

        }

 

    }

 

}

 

void 初期化1(size_t a) {

 

    cn[a] = 0;

 

    空欄数[a] = N2 - ヒント数;

 

    hj1[a] = clock();

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            m[a][i][j] = 0;

 

            //cm[a][i][j] = 0;

 

            mx[a][i][j] = N;

 

            for (size_t k = 0; k < N; k++) {

 

                wb[a][i][j][k] = 0;

 

            }

 

        }

 

    }

 

}

 

void 初期化2(size_t a) {

 

    cn[a] = 0;

 

    空欄数[a] = N2 - ヒント数;

 

    hj1[a] = clock();

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            m[a][i][j] = 0;

 

            cm[a][i][j] = 0;

 

            mx[a][i][j] = N;

 

            for (size_t k = 0; k < N; k++)rlst[a][i][j][k] = k + 1;

 

            for (size_t k = 0; k < N; k++) {

 

                wb[a][i][j][k] = 0;

 

            }

 

        }

 

    }

 

}

 

void 入力順決定関数(size_t g, size_t a) {

 

    size_t ik, jk, mn = 1000;

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            if (m[a][i][j] == 0) {

 

                if (mx[a][i][j] <= mn) {

 

                    mn = mx[a][i][j];

 

                    ik = i;

 

                    jk = j;

 

                }

 

            }

 

        }

 

    }

 

    y[a][g] = ik;

 

    x[a][g] = jk;

 

    局所解析関数(ik, jk, a);

 

}

 

void 問題生成関数(size_t g, size_t a) {

 

    size_t i, j, s, t, p, q, ii, iii, k;

 

    size_t [N], [N], ブロック[N];

 

    if (g < 初期配置数) {

 

        s = yy[a][g];

 

        t = xx[a][g];

 

        局所解析関数(s, t, a);

 

    }

 

    else {

 

        入力順決定関数(g, a);

 

        s = y[a][g];

 

        t = x[a][g];

 

        局所解析関数(s, t, a);

 

    }

 

    if (mx[a][s][t] == 0)return;

 

    ii = rand() % mx[a][s][t];

 

    if (cn[a] == 1)return;

 

    if (継続 == 0)return;

 

    for (i = 0; i < mx[a][s][t]; i++) {

 

        iii = (i + ii) % mx[a][s][t];

 

        m[a][s][t] = rlst[a][s][t][iii];

 

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

 

            [j] = 0;

 

            [j] = 0;

 

            ブロック[j] = 0;

 

        }

 

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

 

            if (m[a][s][j] == 0) {

 

                if (wb[a][s][j][m[a][s][t] - 1] == 0) {

 

                    wb[a][s][j][m[a][s][t] - 1] = 1;

 

                    局所解析関数(s, j, a);

 

                    [j] = 1;

 

                }

 

            }

 

        }

 

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

 

            if (m[a][j][t] == 0) {

 

                if (wb[a][j][t][m[a][s][t] - 1] == 0) {

 

                    wb[a][j][t][m[a][s][t] - 1] = 1;

 

                    局所解析関数(j, t, a);

 

                    [j] = 1;

 

                }

 

            }

 

        }

 

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

 

            p = RN * (s / RN) + (j / RN);

 

            q = RN * (t / RN) + (j % RN);

 

            if (p != s && q != t) {

 

                if (m[a][p][q] == 0) {

 

                    if (wb[a][p][q][m[a][s][t] - 1] == 0) {

 

                        wb[a][p][q][m[a][s][t] - 1] = 1;

 

                        局所解析関数(p, q, a);

 

                        ブロック[j] = 1;

 

                    }

 

                }

 

            }

 

        }

 

        if (継続 == 0)return;

 

        if (g + 1 < N2) {

 

            問題生成関数(g + 1, a);

 

            if (cn[a] == 1)return;

 

            if (継続 == 0)return;

 

        }

 

        else {

 

            代入関数(a);

 

            cn[a]++;

 

            if (cn[a] == 1)return;

 

            if (継続 == 0)return;

 

        }

 

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

 

            if ([j] == 1) {

 

                wb[a][s][j][m[a][s][t] - 1] = 0;

 

            }

 

            if ([j] == 1) {

 

                wb[a][j][t][m[a][s][t] - 1] = 0;

 

            }

 

            p = RN * (s / RN) + (j / RN);

 

            q = RN * (t / RN) + (j % RN);

 

            if (ブロック[j] == 1) {

 

                wb[a][p][q][m[a][s][t] - 1] = 0;

 

            }

 

        }

 

    }

 

    m[a][s][t] = 0;

 

    return;

 

}

 

void 問題生成検証関数(size_t g, size_t a) {

 

    size_t i, j, s, t, p, q, ii, iii, k;

 

    size_t [N], [N], ブロック[N];

 

    if (g < ヒント数) {

 

        s = yy[a][g];

 

        t = xx[a][g];

 

        局所解析関数(s, t, a);

 

    }

 

    else {

 

        入力順決定関数(g, a);

 

        s = y[a][g];

 

        t = x[a][g];

 

        局所解析関数(s, t, a);

 

    }

 

    if (mx[a][s][t] == 0)return;

 

    ii = rand() % mx[a][s][t];

 

    if (cn[a] >= 2)return;

 

    if (継続 == 0)return;

 

    for (i = 0; i < mx[a][s][t]; i++) {

 

        iii = (i + ii) % mx[a][s][t];

 

        m[a][s][t] = rlst[a][s][t][iii];

 

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

 

            [j] = 0;

 

            [j] = 0;

 

            ブロック[j] = 0;

 

        }

 

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

 

            if (m[a][s][j] == 0) {

 

                if (wb[a][s][j][m[a][s][t] - 1] == 0) {

 

                    wb[a][s][j][m[a][s][t] - 1] = 1;

 

                    局所解析関数(s, j, a);

 

                    [j] = 1;

 

                }

 

            }

 

        }

 

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

 

            if (m[a][j][t] == 0) {

 

                if (wb[a][j][t][m[a][s][t] - 1] == 0) {

 

                    wb[a][j][t][m[a][s][t] - 1] = 1;

 

                    局所解析関数(j, t, a);

 

                    [j] = 1;

 

                }

 

            }

 

        }

 

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

 

            p = RN * (s / RN) + (j / RN);

 

            q = RN * (t / RN) + (j % RN);

 

            if (p != s && q != t) {

 

                if (m[a][p][q] == 0) {

 

                    if (wb[a][p][q][m[a][s][t] - 1] == 0) {

 

                        wb[a][p][q][m[a][s][t] - 1] = 1;

 

                        局所解析関数(p, q, a);

 

                        ブロック[j] = 1;

 

                    }

 

                }

 

            }

 

        }

 

        if (継続 == 0)return;

 

        if (g + 1 < N2) {

 

            問題生成検証関数(g + 1, a);

 

            if (cn[a] >= 1)return;

 

            if (継続 == 0)return;

 

        }

 

        else {

 

            //代入関数(a);

 

            cn[a]++;

 

            if (cn[a] == 1)return;

 

            if (継続 == 0)return;

 

        }

 

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

 

            if ([j] == 1) {

 

                wb[a][s][j][m[a][s][t] - 1] = 0;

 

            }

 

            if ([j] == 1) {

 

                wb[a][j][t][m[a][s][t] - 1] = 0;

 

            }

 

            p = RN * (s / RN) + (j / RN);

 

            q = RN * (t / RN) + (j % RN);

 

            if (ブロック[j] == 1) {

 

                wb[a][p][q][m[a][s][t] - 1] = 0;

 

            }

 

        }

 

    }

 

    m[a][s][t] = 0;

 

    return;

 

}

 

void 局所解析関数(size_t s, size_t t, size_t a) {

 

    //セルの候補数字を探索する関数

 

    size_t w = 0;

 

    for (size_t i = 0; i < N; i++) {

 

        if (wb[a][s][t][i] == 0) {

 

            rlst[a][s][t][w] = i + 1;

 

            w++;

 

        }

 

    }

 

    mx[a][s][t] = w;//候補数字数

 

}

 

size_t 検証関数(size_t a) {

 

    size_t p[N];

 

    //以下行部分に重複がないか調べている。ある場合は0を返す。

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            p[j] = 0;

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            p[m[a][i][j] - 1] = 1;

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            if (p[j] == 0)return(0);

 

        }

 

    }

 

    //以下は列部分に重複がないかを知べている。ある場合は0を返す。

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            p[j] = 0;

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            p[m[a][j][i] - 1] = 1;

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            if (p[j] == 0)return(0);

 

        }

 

    }

 

    //以下はブロック部分に重複がないかを調べている。ある場合は0を返す。

 

    for (size_t i = 0; i < N; i++) {

 

        for (size_t j = 0; j < N; j++) {

 

            p[j] = 0;

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            size_t s, t;

 

            s = RN * (i / RN) + (j / RN);//ブロック内を動くy座標(通常とは逆方向を

 

            //向いていることに注意)

 

            t = RN * (i % RN) + (j % RN);//ブロック内を動くx座標

 

            p[m[a][s][t] - 1] = 1;

 

        }

 

        for (size_t j = 0; j < N; j++) {

 

            if (p[j] == 0)return(0);

 

        }

 

    }

 

    return(1);//行・列・ブロックに重複がないときにはじめて1を返している。

 

}