#include <stdio.h>
#define N 3
#define N2 N*N
#define N3 N*N*N
#define N4 N2*N2

// global
const int n2 = N2;
const int n3 = N3;
const int n4 = N4;
char board[N4 + 1];
char candidate[N4][N2 + 2];

// prototype
void initialize();
int continueCheck();
void printBoard();
void decideAll();
void spread(int);

void candidatePrint()
{
  int i;
  for (i = 0; i < n4; ++i)
    if (board[i] == ' ')printf("candidate[%d] = %s\n", i, candidate[i]);
}

void initialize()
{
  int i;
  printBoard();
  for (i = 0; i < n4; ++i)
    sprintf(candidate[i], " 123456789" );
  for (i = 0; i < n4; ++i)
    if (board[i] > '0')
      spread(i);
}

int continueCheck()
{
  char *s = board;
  printBoard();
  for (s = board; *s; ++s)
    if (*s < '0') return 1;
  return 0;
}

void printBoard()
{
  int i = 0;
  char *x = board;
  printf("\n------------------");
  for (; *x; ++i, ++x) {
    if (i % n2 == 0)putchar('\n');
    printf("%c ", *x);
  }
  printf("\n------------------");
}

void decideAll()
{
  int i, count;
  char *s, w;
  for (i = 0; i < n4; ++i) {
    if (board[i] != ' ')continue;
    // count candidate chars
    for (s = candidate[i], count = 0; *s; ++s) {
      if (*s != ' ') {
        w = *s;
        ++count;
      }
    }
    if (count == 1) {
      board[i] = w;
      spread(i);
    }
  }
}

void spread(const int n)
{
  int i, j, ii, jj, w;
  w = board[n] - '0';
  // horizontal
  i = n / n2;
  for (j = 0; j < n2; ++j)
    candidate[i * n2 + j ][w] = ' ';
  // vertical
  j = n % n2;
  for (i = 0 ; i < n2; ++i)
    candidate[i * n2 + j ][w] = ' ';
  // local
  for (i = n / n2 / N * N, ii = 0; ii < N; ++i, ++ii) {
    for (j = n % n2 / N * N, jj = 0; jj < N; ++j, ++jj) {
      candidate[i * n2 + j][w] = ' ';
    }
  }
}

int main()
{
  sprintf(board,
          "53  7    " \
          "6  195   " \
          " 98    6 " \
          "8   6   3" \
          "4  8 3  1" \
          "7   2   6" \
          " 6    28 " \
          "   419  5" \
          "    8  79"
         );
  initialize();
  do {
    decideAll();
  } while (continueCheck());

  return 0;
}
