#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define SIZE 5
#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 CanPut(State state, const int _bx, const int _by, const int _ix, const int _iy, const int value)
{
int bx, by, ix, iy;
// 縦
for (by = 0; by < SIZE; by++)
{
for (iy = 0; iy < SIZE; iy++)
{
if (state.data[_bx][by][_ix][iy] == value)
{
return 0;
}
}
}
// 横
for (bx = 0; bx < SIZE; bx++)
{
for (ix = 0; ix < SIZE; ix++)
{
if (state.data[bx][_by][ix][_iy] == value)
{
return 0;
}
}
}
// ブロック
for (ix = 0; ix < SIZE; ix++)
{
for (iy = 0; iy < SIZE; iy++)
{
if (state.data[_bx][_by][ix][iy] == value)
{
return 0;
}
}
}
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++)
{
if (CanPut(state, bx, by, ix, iy, i))
{
state.data[bx][by][ix][iy] = i;
if (Solve(state))
{
return 1;
}
state.data[bx][by][ix][iy] = 0;
}
}
if (state.data[bx][by][ix][iy] == 0)
{
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;
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;
}