第7講 左右対称形・上下対称形・点対称形・左右にも上下に対称・ハート型
第4話 左右対称形・上下対称形のコード例
テキストファイルは一番下にあります。
を実現するプログラム例
if (s == n * n - 1) { //一番奥の部屋に到達
int k = rand() % 3;
if (k == 0)hitaisyou(a);
if (k == 1)sayutaisyou(a);
if (k == 2)jyogetaisyou(a);
cn[a]++;
if (cn[a] == 1)return; //数独が1個できた時点でとめる
}
tobi:;
}
}
void hitaisyou(char a) {
char hb; //部屋番号
char tbs[13] = { 11,13,17,19,23,29,31,37,41,43,47,53,59 }; //飛びの選択肢
//素数であれば81と互いに素は保証されている
char st = rand() % 81; //始めの位置
char tb = tbs[rand() % 13]; //飛び
char h = 0; //可否の否
char* gohr = (char*)calloc(hnt, sizeof(char));
for (char t = 0; t < hnt; t++) {
gohr[t] = (st + t * tb) % 81;
}
for (char j = 0; j < n; j++) {
for (char k = 0; k < n; k++) {
if (keizoku == 0)return;
hb = n * j + k; //部屋番号の再初期化 = 空欄の数字候補の個数の小さい順に入れる
char h = 0; //可否の否
for (char t = 0; t < hnt; t++) {
if (gohr[t] == hb) {
h = 1;//可否の可
break;
}
}
if (h == 1) {
mondai[a][j][k] = sudoku[a][j][k]; //問題用の配列に代入
gensudoku[a][j][k] = sudoku[a][j][k];
}
}
}
free(gohr); //メモリ解放
}
void sayutaisyou(char a) {
jyogetaisyou(a);
char sudokud[n][n];
char mondaid[n][n];
char gensudokud[n][n];
for (char i = 0; i < n; i++) {
for (char j = 0; j < n; j++) {
sudokud[j][i] = sudoku[a][i][j];
gensudokud[j][i] = gensudoku[a][i][j];
mondaid[j][i] = mondai[a][i][j];
}
}
for (char i = 0; i < n; i++) {
for (char j = 0; j < n; j++) {
sudoku[a][i][j] = sudokud[i][j];
gensudoku[a][i][j] = gensudokud[i][j];
mondai[a][i][j] = mondaid[i][j];
}
}
}
void jyogetaisyou(char a) {
char c[3];
if (hnt % 2 == 0) {
for (char i = 0; i < 3; i++)c[i] = 2 * i;
}
if (hnt % 2 == 1) {
for (char i = 0; i < 3; i++)c[i] = 2 * i + 1;
}
char q = c[rand() % 3];
char e[n];
e[0] = rand() % 9;
char i = 1;
while (i < q) {
e[i] = rand() % 9;
while (1) {
char h = 1;
e[i] = rand() % 9;
for (char j = 0; j < i; j++) {
if (e[i] == e[j]) {
h = 0;
break;
}
}
if (h == 1)break;
}
i++;
}
for (char i = 0; i < q; i++) {
mondai[a][4][e[i]] = sudoku[a][4][e[i]];
gensudoku[a][4][e[i]] = sudoku[a][4][e[i]];
}
char hb; //部屋番号
char tbs[6] = { 5,11,13,17,19,23 }; //飛びの選択肢
//素数であれば36と互いに素は保証されている
char st = rand() % 36; //始めの位置
char tb = tbs[rand() % 6]; //飛び
char h = 0; //可否の否
char* gohr = (char*)calloc(hnt, sizeof(char));
for (char t = 0; t < hnt - q; t++) {
gohr[t] = (st + t * tb) % 36;
}
for (char j = 0; j < 4; j++) {
for (char k = 0; k < n; k++) {
if (keizoku == 0)return;
hb = n * j + k; //部屋番号の再初期化 = 空欄の数字候補の個数の小さい順に入れる
char h = 0; //可否の否
for (char t = 0; t < (hnt - q) / 2; t++) {
if (gohr[t] == hb) {
h = 1;//可否の可
break;
}
}
if (h == 1) {
mondai[a][j][k] = sudoku[a][j][k];
mondai[a][8 - j][k] = sudoku[a][8 - j][k];
gensudoku[a][j][k] = sudoku[a][j][k];
gensudoku[a][8 - j][k] = sudoku[a][8 - j][k];
}
}
}
free(gohr); //メモリ解放
}
テキストファイル
次の課題は点対称形です。
ノーヒントで皆さんに挑戦していただきます。
第3話へ 第5話へ
トップへ