#include <stdio.h>
char sudoku[9][9+1]; //9x9 스도쿠판. +1은 여유공간
char* r[9][9]; //스도쿠판의 행 우선 참조
char* c[9][9]; //스도쿠판의 열 우선 참조
char* s[9][9]; //스도쿠판의 3x3 섹터 우선 참조
typedef struct {int rn, cn; bool num[9];} Set; //rn cn 칸에 가능한 숫자 세트
void init() { //참조 포인터 초기화
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
r[i][j] = c[j][i] = &sudoku[i][j];
for (int rn = 0; rn < 9; rn += 3)
for (int cn = 0; cn < 9; cn += 3)
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
s[rn + (cn / 3)][i * 3 + j] = &sudoku[rn + i][cn + j];
}
inline int sizeofNumset(Set set) { //가능한 숫자 개수 카운터
bool *n=set.num;
return n[0]+n[1]+n[2]+n[3]+n[4]+n[5]+n[6]+n[7]+n[8];
}
Set findAblNum(int rn, int cn) { //해당 칸의 가능한 숫자 세트 탐색
Set nums = { rn, cn, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; //true로 초기화
int sn = rn / 3 * 3 + cn / 3; //섹터 번호 구함
for (int i = 0; i < 9; i++) {
//행(*r),열(*c),섹터(*s) 탐색
if (*r[rn][i] > 0) //채워져 있으면
nums.num[*r[rn][i] - 1] = false; //마킹
if (*c[cn][i] > 0)
nums.num[*c[cn][i] - 1] = false;
if (*s[sn][i] > 0)
nums.num[*s[sn][i] - 1] = false;
}
return nums;
}
Set findMinPossible() { //가장 경우의 수가 적은칸의 세트 리턴
int size = 10;
Set minset = { -1, -1 };
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (sudoku[i][j] > 0) continue; //채워진칸 무시
Set temp = findAblNum(i, j);
int nsize = sizeofNumset(temp);
if (!nsize) //빈칸인데 가능한 숫자가 없으면
return Set { 10, 10 }; //오답 표시 리턴 (C++11 이상)
else if (nsize == 1) //가능한 숫자가 하나일 경우 바로 리턴
return temp;
else if (nsize < size) {
size = nsize;
minset = temp;
}
}
}
return minset;
}
bool solve() {
Set set = findMinPossible(); //가장 경우의 수가 적은 칸 탐색
if (set.rn > 9) //불가능한 칸이 있음을 뜻함
return false;
if (set.rn < 0) //더 이상 빈칸이 없음을 뜻함.
return true; //풀린것!
for (int i = 1; i <= 9; i++) { //숫자 1~9를 채우는 부분
if (!set.num[i - 1]) continue; //불가능한 숫자는 스킵
sudoku[set.rn][set.cn] = i; //가능한 숫자를 채움
if (solve()) //채운걸 풀어봄
return true; // 그게 풀렸으면 탈출
}
// 채울 수 있는 숫자가 없거나 다 채워봤는데 안된거니까
sudoku[set.rn][set.cn] = 0; //지우고
return false; //오답 리턴
}
int main() {
init(); //참조 포인터 초기화
char input[10]; //입력
//문자를 숫자로 변환
for (int i = 0; i < 9; i++) {
scanf("%s", input);
for (int j = 0; j < 9; j++)
sudoku[i][j] = input[j] - '0';
}
printf("%s\n", solve() ? "[Solved]" : "[No solution]"); //풀어
//결과 출력
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
printf("%d", sudoku[i][j]);
printf("\n");
}
}