まずは正解のパターンを作成するプログラム。
一定の並びの数字をランダムに並べ替えて作成します。
► スポイラーを表示
#include
#include
#include
void init_random(void) {
srand((unsigned int)time(NULL));
}
int get_random(int max) {
return rand()%max;
}
int main(void) {
const char* mozi[10]={" ","1","2","3","4","5","6","7","8","9"};
const int zyunban[6][3]={
{0,1,2},
{0,2,1},
{1,0,2},
{1,2,0},
{2,0,1},
{2,1,0}
};
int suuzi[9][9]={
{1,2,3,4,5,6,7,8,9},
{4,5,6,7,8,9,1,2,3},
{7,8,9,1,2,3,4,5,6},
{2,3,4,5,6,7,8,9,1},
{5,6,7,8,9,1,2,3,4},
{8,9,1,2,3,4,5,6,7},
{3,4,5,6,7,8,9,1,2},
{6,7,8,9,1,2,3,4,5},
{9,1,2,3,4,5,6,7,8}
};
int suuzi2[9][9];
int i,j,k;
int where;
init_random();
/*縦の仲間の列の順番を入れ替える*/
for(i=0;i
#include
#include
void init_random(void) {
srand((unsigned int)time(NULL));
}
int get_random(int max) {
return rand()%max;
}
void solve(int result[9][9],int question[9][9]) {
int possible[9];
int i,j,k;
int found;
int x,y;
for(i=0;i
#include
#include
void init_random(void) {
srand((unsigned int)time(NULL));
}
int get_random(int max) {
return rand()%max;
}
void solve(int result[9][9],int question[9][9]) {
int possible[9][9][9];
int m,n;
int i,j,k,l;
int found;
int x,y;
for(m=0;m<9;m++) {
for(n=0;n<9;n++) {
/*単純な解析*/
for(i=0;i<9;i++) {
for(j=0;j<9;j++) {
if(question[i][j] && !(m==i && n==j)) {
/*特定の数字である*/
for(k=0;k<9;k++) {
if(k+1==question[i][j])possible[i][j][k]=1;
else possible[i][j][k]=0;
}
} else {
/*全ての数字の可能性がある*/
for(k=0;k<9;k++)possible[i][j][k]=1;
/*既に入っている数字を消す*/
for(k=0;k<9;k++) {
/*横にある数字を消す*/
if(k!=j) {
if(question[i][k] && !(i==m && k==n))
possible[i][j][question[i][k]-1]=0;
}
/*縦にある数字を消す*/
if(k!=i) {
if(question[k][j] && !(k==m && j==n))
possible[i][j][question[k][j]-1]=0;
}
/*同じブロックにある数字を消す*/
x=(j/3)*3+k%3;
y=(i/3)*3+k/3;
if(x!=j || y!=i) {
if(question[y][x] && !(y==m && x==n))
possible[i][j][question[y][x]-1]=0;
}
}
}
}
}
/*列単位の解析*/
for(i=0;i<9;i++) {
for(j=0;j<9;j++) {
if(i==m && j==n)continue;
for(k=0;k<9;k++) {
if(possible[i][j][k]) {
/*他の行に置けないならその行確定*/
found=0;
for(l=0;l<9;l++) {
x=(j/3)*3+l%3;
y=(i/3)*3+l/3;
if(y==i)continue;
if(y==m && x==n)continue;
if(possible[i][j][k])found=1;
}
if(!found) {
for(l=0;l<9;l++) {
if(j/3!=l/3)possible[i][l][k]=0;
}
}
/*他の列に置けないならその列確定*/
found=0;
for(l=0;l<9;l++) {
x=(j/3)*3+l%3;
y=(i/3)*3+l/3;
if(x==j)continue;
if(y==m && x==n)continue;
if(possible[i][j][k])found=1;
}
if(!found) {
for(l=0;l<9;l++) {
if(i/3!=l/3)possible[l][j][k]=0;
}
}
}
}
}
}
/*そこにしか置けないなら置く*/
for(i=0;i<9;i++) {
if(possible[m][n][i]) {
/*横の解析*/
found=0;
for(j=0;j<9;j++) {
if(j==n)continue;
if(possible[m][j][i]) {
found=1;
break;
}
}
if(!found) {
/*横でそこにしか置けなければ置く*/
for(j=0;j<9;j++) {
if(j!=i)possible[m][n][j]=0;
}
}
/*縦の解析*/
found=0;
for(j=0;j<9;j++) {
if(j==m)continue;
if(possible[j][n][i]) {
found=1;
break;
}
}
if(!found) {
/*縦でそこにしか置けなければ置く*/
for(j=0;j<9;j++) {
if(j!=i)possible[m][n][j]=0;
}
}
/*グループの解析*/
found=0;
for(j=0;j<9;j++) {
x=(n/3)*3+j%3;
y=(m/3)*3+j/3;
if(x==n && y==m)continue;
if(possible[y][x][i]) {
found=1;
break;
}
}
if(!found) {
/*グループでそこにしか置けなければ置く*/
for(j=0;j<9;j++) {
if(j!=i)possible[m][n][j]=0;
}
}
}
}
/*可能性のある数字を探す*/
found=0;
for(k=0;k<9;k++) {
if(possible[m][n][k]) {
if(found) {
result[m][n]=0;
break;
} else {
result[m][n]=k+1;
found=1;
}
}
}
if(!found)result[m][n]=0;
}
}
}
int main(void) {
const char* mozi[10]={" ","1","2","3","4","5","6","7","8","9"};
const int zyunban[6][3]={
{0,1,2},
{0,2,1},
{1,0,2},
{1,2,0},
{2,0,1},
{2,1,0}
};
int suuzi[9][9]={
{1,2,3,4,5,6,7,8,9},
{4,5,6,7,8,9,1,2,3},
{7,8,9,1,2,3,4,5,6},
{2,3,4,5,6,7,8,9,1},
{5,6,7,8,9,1,2,3,4},
{8,9,1,2,3,4,5,6,7},
{3,4,5,6,7,8,9,1,2},
{6,7,8,9,1,2,3,4,5},
{9,1,2,3,4,5,6,7,8}
};
int suuzi2[9][9];
int i,j,k;
int where;
int delok[81][2];
int deloknum;
init_random();
/*縦の仲間の列の順番を入れ替える*/
for(i=0;i<3;i++) {
where=get_random(6);
for(j=0;j<3;j++) {
for(k=0;k<9;k++) {
suuzi2[k][i+j*3]=suuzi[k][i+zyunban[where][j]*3];
}
}
}
for(i=0;i<9;i++) {
for(j=0;j<9;j++)suuzi[i][j]=suuzi2[i][j];
}
/*縦のブロックの列の順番を入れ替える*/
for(i=0;i<3;i++) {
where=get_random(6);
for(j=0;j<3;j++) {
for(k=0;k<9;k++) {
suuzi2[k][i*3+j]=suuzi[k][i*3+zyunban[where][j]];
}
}
}
for(i=0;i<9;i++) {
for(j=0;j<9;j++)suuzi[i][j]=suuzi2[i][j];
}
/*横のブロックの列の順番を入れ替える*/
for(i=0;i<3;i++) {
where=get_random(6);
for(j=0;j<3;j++) {
for(k=0;k<9;k++) {
suuzi2[i*3+j][k]=suuzi[i*3+zyunban[where][j]][k];
}
}
}
for(i=0;i<9;i++) {
for(j=0;j<9;j++)suuzi[i][j]=suuzi2[i][j];
}
/*まわりから特定できる数字を消していく*/
while(1) {
/*消せる数字を探す*/
solve(suuzi2,suuzi);
deloknum=0;
for(i=0;i<9;i++) {
for(j=0;j<9;j++) {
if(suuzi2[i][j] && suuzi[i][j]) {
delok[deloknum][0]=i;
delok[deloknum][1]=j;
deloknum++;
}
}
}
/*消せなくなったら終了*/
if(deloknum<=0)break;
/*数字を一つ消す*/
where=get_random(deloknum);
suuzi[delok[where][0]][delok[where][1]]=0;
}
/*数字を消した表を表示する*/
puts("┏━┯━┯━┳━┯━┯━┳━┯━┯━┓");
for(i=0;i<9;i++) {
printf("┃%s│%s│%s┃%s│%s│%s┃%s│%s│%s┃\n",
mozi[suuzi[i][0]],mozi[suuzi[i][1]],mozi[suuzi[i][2]],
mozi[suuzi[i][3]],mozi[suuzi[i][4]],mozi[suuzi[i][5]],
mozi[suuzi[i][6]],mozi[suuzi[i][7]],mozi[suuzi[i][8]]);
if(i==8)puts("┗━┷━┷━┻━┷━┷━┻━┷━┷━┛");
else if(i%3==2)puts("┣━┿━┿━╋━┿━┿━╋━┿━┿━┫");
else puts("┠─┼─┼─╂─┼─┼─╂─┼─┼─┨");
}
return 0;
}
┏━┯━┯━┳━┯━┯━┳━┯━┯━┓
┃9│ │5┃ │4│8┃ │6│ ┃
┠─┼─┼─╂─┼─┼─╂─┼─┼─┨
┃ │ │2┃ │1│5┃ │3│ ┃
┠─┼─┼─╂─┼─┼─╂─┼─┼─┨
┃ │ │ ┃ │ │ ┃1│ │ ┃
┣━┿━┿━╋━┿━┿━╋━┿━┿━┫
┃ │5│9┃7│ │ ┃2│1│ ┃
┠─┼─┼─╂─┼─┼─╂─┼─┼─┨
┃7│ │ ┃ │ │6┃ │ │9┃
┠─┼─┼─╂─┼─┼─╂─┼─┼─┨
┃1│ │6┃ │5│ ┃8│7│ ┃
┣━┿━┿━╋━┿━┿━╋━┿━┿━┫
┃ │6│ ┃ │ │4┃3│ │ ┃
┠─┼─┼─╂─┼─┼─╂─┼─┼─┨
┃2│ │7┃ │ │ ┃9│8│4┃
┠─┼─┼─╂─┼─┼─╂─┼─┼─┨
┃8│ │ ┃2│3│ ┃ │ │1┃
┗━┷━┷━┻━┷━┷━┻━┷━┷━┛
六重ループまで使ったのに、思ったほど成果があげられませんでした。
残忍ながら今の俺にはこれが限界です。orz