# 13333 - Stewie vs Brian
> author: daisyliu0225
###### tags: recursion
---
## Thinking
我原先的想法是把所有的可能性全部列出來,但後來發現有一些格子可能會有兩個可能的數字,這樣又會回到遞迴的處理。不然還有另一個解法但助教說很複雜。所以之後乾脆用遞迴寫了。
## Overall thought (Brute-Force)
Step1:看到一個新的格子(以0為代表) --> 開始從1開始測試這一個為0的格子的橫排跟縱排 --> 如果可以,先將這一個格子填為1,如果不行,就加1(其他就依此類推)
Step2:如果這一格格子掛掉了 --> 後退到剛剛那一格 --> 繼續尋找下一個可行的數字
Step3:一直到所有格子都有答案為止,就可以產生答案了!如果沒有答案,就產生no solution的答案
聽起來很簡單,但我錯了...寫的過程真的是一波三折QQ。
程式雛型大概長這樣
```cpp=
int main(){
scanf(sudoku);
check sudoku space to space;
if(sudoku(space)==0){
check from 1 to 9 which fits the space;
if(number fits) sudoku(space)=number;
else{
space-1;
check again;
} //number not fits
}
if(solved) printf(sudoku);
else printf(no solution);
return 0;
}
```
## Problems Occurred!
Q1.測試總是不會第一次就成功,如何知道掛掉?
A1.如果從1~9都無法填入格子內,就可以知道這一個格子是掛掉的 --> 格子後退一格(最鄰近的0的位置)
Q2.慘了,我不知道0在哪裡
A2.創建兩個數獨array,一個是改變前的array,一個是改變後的array,這樣在尋找哪一個數字沒有被填過,找改變前的array就好了
Q3.怎麼一直叭股拉(我搞了三天才想出原因)
A3.沒有清除改變後array的資料當然一直叭股阿廢話! :cry:
Q4.一直跳出no solution,該如何處理?
A4.用exit(0)的指令
:::info
:bulb: **The exit command**
In computing, exit is a command used in many operating system command-line shells and scripting languages. -- from Wiki
簡單來說,使用了exit command就可以讓程式或是者是小函數們立刻停止。我在這邊是使用在no solution 指令上。
一般而言,如果要使用exit command,後面的小括號會打上0,代表正常的中止程序。
像這樣
```cpp=
exit(0);
```
:::
## Code
我懶惰不想要打註解,相信大家一定都看得懂。而且(應該)也不會有人來看我的東西啦XD
```cpp=
//note 1=die 0=live
#include <stdio.h>
#include <stdlib.h>
int skudou[9][9];
int ch_skudou[9][9];
int print=0;
int check_square(int i, int j, int k){
int ri,rj;
ri=(i+1)%3;
rj=(j+1)%3;
if(ri==1){
if(rj==1){
if(ch_skudou[i+1][j+1]==k||ch_skudou[i+1][j+2]==k||ch_skudou[i+2][j+1]==k||ch_skudou[i+2][j+2]==k)
return 0;
else return 1;
}
else if(rj==2){
if(ch_skudou[i+1][j-1]==k||ch_skudou[i+1][j+1]==k||ch_skudou[i+2][j-1]==k||ch_skudou[i+2][j+1]==k)
return 0;
else return 1;
}
else if(rj==0){
if(ch_skudou[i+1][j-2]==k||ch_skudou[i+1][j-1]==k||ch_skudou[i+2][j-2]==k||ch_skudou[i+2][j-1]==k)
return 0;
else return 1;
}
}else if(ri==2){
if(rj==1){
if(ch_skudou[i-1][j]==k||ch_skudou[i-1][j+2]==k||ch_skudou[i+1][j+1]==k||ch_skudou[i+1][j+2]==k)
return 0;
else return 1;
}
else if(rj==2){
if(ch_skudou[i-1][j-1]==k||ch_skudou[i-1][j+1]==k||ch_skudou[i+1][j-1]==k||ch_skudou[i+1][j+1]==k)
return 0;
else return 1;
}
else if(rj==0){
if(ch_skudou[i-1][j-2]==k||ch_skudou[i-1][j-1]==k||ch_skudou[i+1][j-2]==k||ch_skudou[i+1][j-1]==k)
return 0;
else return 1;
}
}else if(ri==0){
if(rj==1){
if(ch_skudou[i-2][j+1]==k||ch_skudou[i-2][j+2]==k||ch_skudou[i-1][j+1]==k||ch_skudou[i-1][j+2]==k)
return 0;
else return 1;
}
else if(rj==2){
if(ch_skudou[i-2][j-1]==k||ch_skudou[i-2][j+1]==k||ch_skudou[i-1][j-1]==k||ch_skudou[i-1][j+1]==k)
return 0;
else return 1;
}
else if(rj==0){
if(ch_skudou[i-2][j-2]==k||ch_skudou[i-2][j-1]==k||ch_skudou[i-1][j-2]==k||ch_skudou[i-1][j-1]==k)
return 0;
else return 1;
}
}
} //ok
int check(int i,int j,int k){
int s=0;
for(int f=0;f<9;f++){
if(ch_skudou[f][j]!=k&&ch_skudou[i][f]!=k){
continue;
}else {
s=1;
return 0;
}
}
if(s==0){
int checksqu;
checksqu=check_square(i,j,k);
if(checksqu==1){
return 1;
}
else {
return 0;
}
}
} //ok
void solve(int i,int j,int x){
int counter=0;
if((i>=0&&i<9)&&(j>=0&&j<9)){
if(skudou[i][j]!=0){
if(j==8){
solve(i+1,0,1);
}
else {
solve(i,j+1,1);
}
}else{
if(x==0) counter=1;
else counter=x;
for(int k=x;k<10;k++){
int c = check(i,j,k);
if(c==1) {
ch_skudou[i][j]=k;
if(j==8) {
solve(i+1,0,1);
}else {
solve(i,j+1,1);
}
}
else{
counter++;
if(counter==10){
counter=0;
ch_skudou[i][j]=0;
if(j==0){
i=i-1;
j=8;
}else j--;
while(skudou[i][j]!=0){
if(j==0){
i=i-1;
j=8;
}else j--;
}
solve(i,j,ch_skudou[i][j]);
break;
}else continue;
}
}
}
}
else if(i==9&&j==0){
for(int k=0;k<9;k++){
for(int l=0;l<8;l++){
printf("%d ",ch_skudou[k][l]);
}
printf("%d\n",ch_skudou[k][8]);
}
}
else{
if(print==0){
print=1;
printf("no solution\n");
exit(0);
}
return 1;
}
}
int main()
{
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
scanf("%d",&skudou[i][j]);
ch_skudou[i][j]=skudou[i][j];
}
}
int sw=0;
solve(0,0,1);
return 0;
} //ok
```
## Reference
--數獨part--
[數獨sudoku解答計算器 by布丁布丁吃什麼?](https://blog.pulipuli.info/2006/05/sudoku.html?showComment=1546683280101)
[iT邦幫忙[演算法][JavaScript]演算法挑戰系列(10)-Valid Sudoku by神Q超人](https://ithelp.ithome.com.tw/articles/10198639)
[學會了回溯演算法,我終於會做數獨了 by@osc_sdc55qra](https://www.gushiciku.cn/pl/glKd/zh-tw)
資工系朋朋們、快被我煩死的室友、HuTAs
--exit command--
[exit(command) from Wikipedia](https://en.wikipedia.org/wiki/Exit_(command))
[exit command from tutorialspoint](https://www.tutorialspoint.com/what-is-exit-function-in-c-language)
--HackMD筆記程式碼--
[曾經使用過NTHU judge的某學長](https://hackmd.io/@Ice1187/nthuoj-solution)
//學長辛苦了!