#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define SIZE 3
#define USAGE "USAGE : %s question_file\n"
typedef struct
{
char data[SIZE][SIZE][SIZE][SIZE];
} State;
int GetQuestion(State *state, char *fname)
{
FILE *fp;
char buf[(2+1)*SIZE*SIZE]; // 適当 SIZEが9までなら入ると思う
int bx, by, ix, iy;
char *p;
memset(state->data, 0, SIZE*SIZE*SIZE*SIZE);
if ((fp = fopen(fname, "r")) == NULL)
{
return 0;
}
for (by = 0; by < SIZE; by++)
{
for (iy = 0; iy < SIZE; iy++)
{
fgets(buf, sizeof(buf), fp);
if (buf[strlen(buf) - 1] != '\n')
{
fclose(fp);
return 0;
}
// chop
buf[strlen(buf) - 1] = '\0';
p = strtok(buf, "\t");
for (bx = 0; bx < SIZE; bx++)
{
for (ix = 0; ix < SIZE; ix++)
{
if (p == NULL)
{
fprintf(stderr, "null\n");
return 0;
}
state->data[bx][by][ix][iy] = atoi(p);
p = strtok(NULL, "\t");
}
}
}
}
fclose(fp);
return 1;
}
void ShowState(State state)
{
int bx, by, ix, iy;
int i;
for (i=0; i<SIZE*SIZE*3+1; i++)
{
putchar('-');
}
putchar('\n');
for (by = 0; by < SIZE; by++)
{
for (iy = 0; iy < SIZE; iy++)
{
for (bx = 0; bx < SIZE; bx++)
{
for (ix = 0; ix < SIZE; ix++)
{
printf("|%2d", state.data[bx][by][ix][iy]);
}
}
puts("|");
for (i=0; i<SIZE*SIZE; i++)
{
putchar('+');
putchar('-');
putchar('-');
}
puts("+");
}
}
}
int IsValid(State *state)
{
int bx, by, ix, iy;
char count[SIZE*SIZE];
// 縦
for (bx = 0; bx < SIZE; bx++)
{
for (ix = 0; ix < SIZE; ix++)
{
memset(count, 0, sizeof(count));
for (by = 0; by < SIZE; by++)
{
for (iy = 0; iy < SIZE; iy++)
{
int data = state->data[bx][by][ix][iy];
if (data == 0)
{
continue;
}
if (count[data-1] != 0)
{
return 0;
}
count[data-1] = 1;
}
}
}
}
// 横
for (by = 0; by < SIZE; by++)
{
for (iy = 0; iy < SIZE; iy++)
{
memset(count, 0, sizeof(count));
for (bx = 0; bx < SIZE; bx++)
{
for (ix = 0; ix < SIZE; ix++)
{
int data = state->data[bx][by][ix][iy];
if (data == 0)
{
continue;
}
if (count[data-1] != 0)
{
return 0;
}
count[data-1] = 1;
}
}
}
}
// ブロック
for (by = 0; by < SIZE; by++)
{
for (bx = 0; bx < SIZE; bx++)
{
memset(count, 0, sizeof(count));
for (iy = 0; iy < SIZE; iy++)
{
for (ix = 0; ix < SIZE; ix++)
{
int data = state->data[bx][by][ix][iy];
if (data == 0)
{
continue;
}
if (count[data-1] != 0)
{
return 0;
}
count[data-1] = 1;
}
}
}
}
return 1;
}
int Solve(State state)
{
int bx, by, ix, iy;
for (bx = 0; bx < SIZE; bx++)
{
for (by = 0; by < SIZE; by++)
{
for (ix = 0; ix < SIZE; ix++)
{
for (iy = 0; iy < SIZE; iy++)
{
if (state.data[bx][by][ix][iy] == 0)
{
int i;
for (i = 1; i <= SIZE * SIZE; i++)
{
state.data[bx][by][ix][iy] = i;
if (IsValid(&state))
{
if (Solve(state))
return 1;
}
}
if (!IsValid(&state)) return 0;
}
}
}
}
}
puts("answer");
ShowState(state);
return 1;
}
void ShowTime(void)
{
time_t timer;
time(&timer);
printf("%s", ctime(&timer));
}
int main(int argc, char **argv)
{
State start;
State check_stack[SIZE*SIZE];
ShowTime();
if (argc != 2)
{
fprintf(stderr, USAGE, argv[0]);
exit(EXIT_FAILURE);
}
if (!GetQuestion(&start, argv[1]))
{
fprintf(stderr, "問題の読み込みに失敗しました\n");
exit(EXIT_FAILURE);
}
puts("question");
ShowState(start);
if (!Solve(start))
{
fprintf(stderr, "とけない\n");
}
ShowTime();
return 0;
}