第8講 ハート型・左右上下対称形・点対称形・上下対称性形・上下対称形第2案と解答から解答へ
第2話 左右にも上下にも対称第2案
テキストファイル自動実験版

テキストファイル手動実験版

void sayujyogetaisyou(char a) {
  char q = 0;
  if (hnt % 2 == 1) {//ヒント数が奇数の場合には真ん中の座標(4, 4)に入れないないとだめ
    //左右にも上下にも対称は線対称にして点対称であることと同値であり、
    //点対称の要請から真ん中入力は必要
    Y[a][0] = 4;
    X[a][0] = 4;
    q++;
  }
  if ((hnt - q) % 4 == 2) {//中央列と中央行にの両方に入れてしまうと4で割った時に余りが2であるから、
    //どちらか一方を選ばないと矛盾してしまう
    char b = rand() % 2;
    if (b == 0) {
      Y[a][q] = 4;
      X[a][q] = rand() % 4;
      q++;
      Y[a][q] = 4;
      X[a][q] = 8 - X[a][q - 1];
      q++;
    }
    if (b == 1) {
      Y[a][q] = rand() % 4;
      X[a][q] = 4;
      q++;
      Y[a][q] = 8 - Y[a][q - 1];
      X[a][q] = 4;
      q++;
    }
  }
  if ((hnt - q) % 4 == 0) {//(hnt - q) % 4 == 2の場合とは異なり、両方に入れないと4の倍数にならない
    Y[a][q] = 4;
    X[a][q] = rand() % 4;
    q++;
    Y[a][q] = 4;
    X[a][q] = 8 - X[a][q - 1];
    q++;
    Y[a][q] = rand() % 4;
    X[a][q] = 4;
    q++;
    Y[a][q] = 8 - Y[a][q - 1];
    X[a][q] = 4;
    q++;
  }
  char st = rand() % 16;//中央行と中央列を除いた左上1/4部分に対応
  char tbs[5] = { 3,5,7,11,13 };//すべて素数であるから16との互いに素は保証されている
  char tb = tbs[rand() % 5];
  for (char i = 0; ; i++) {
    Y[a][q] = ((st + tb * i) % 16) / 4;//中央行と中央列を除いた左上1/4部分に対応
    X[a][q] = ((st + tb * i) % 16) % 4;
    //例えば、st = 10,tb = 7とすると
    //10,1,8,15,6,13,4,11,2,9,0,7,14,5,12,19
    //一巡しただけで0~15までに数字がもれなく重複なしにそろう
    //二巡以降も全く同じ動きする
    Y[a][q + 1] = Y[a][q];
    X[a][q + 1] = 8 - X[a][q];//左右対称性
    Y[a][q + 2] = 8 - Y[a][q];//上下対称性
    X[a][q + 2] = X[a][q];
    Y[a][q + 3] = 8 - Y[a][q];//点対称性
    X[a][q + 3] = 8 - X[a][q];
    q += 4;
    if (hnt == q)break;
  }
  //for (char i = 0; i < q; i++)sudoku[a][Y[a][i]][X[a][i]] = 1;
}




第8話へ
 第10話へ

トップへ




第10話 点対称第2案
テキストファイル自動実験版

テキストファイル手動実験版

void tentaisyou(char a) {
  char q = 0;
  if (hnt % 2 == 1) {//点対称の場合はヒント数が奇数の場合には真ん中の座標(4, 4)に入れる必要がある。
    //他のセルは点対称性から偶数個になるため
    Y[a][0] = 4;
    X[a][0] = 4;
    q++;
  }
  char b = rand() % 2;
  if (b == 1) {//中央行に左右対称に入れる
    Y[a][q] = 4;
    X[a][q] = rand() % 4;
    q++;
    Y[a][q] = 4;
    X[a][q] = 8 - X[a][q - 1];
    q++;
  }
  char st = rand() % 36;//36なのは上位4行を対象としているから 9×4 = 36
  char tbs[8] = { 5,7,11,13,17,19,23,29 };//すべて素数であるから36とは互いに素である
  char tb = tbs[rand() % 8];
  for (char i = 0; ; i++) {
    Y[a][q] = ((st + tb * i) % 36) / 9;
    X[a][q] = ((st + tb * i) % 36) % 9;
    Y[a][q + 1] = 8 - Y[a][q];//180°回転した位置
    X[a][q + 1] = 8 - X[a][q];
    q += 2;
    if (hnt == q)break;
  }
  for (char i = 0; i < hnt; i++)sudoku[a][Y[a][i]][X[a][i]] = 1;
}


第9話へ
 第11話へ

トップへ