สมมติว่าเรามีกริดСудอะกุและต้องแก้ปริศนาตัวเลขชื่อดังนี้ สูดอะกุเป็นกริด 9x9 และกริดทั้งหมดแบ่งเป็นกล่อง 3x3 มีกติกาในการแก้:
- ใช้ตัวเลข 1 ถึง 9 ในการแก้
- ตัวเลขซ้ำไม่ได้ในแถวเดียว คอลัมน์เดียว หรือกล่อง 3x3 เดียวกัน
ใช้อัลกอริทึมแบ็กทแร็กกิ้ง (backtracking) ในการแก้ เมื่อกรอกตัวเลขในเซลล์ จะตรวจสอบว่าถูกต้องหรือไม่ ถ้าไม่ถูกต้อง ลองตัวเลขอื่น ถ้าลอง 1-9 ครบแล้วไม่มีตัวเลขที่วางได้ จะย้อนกลับ (backtrack) ไปตัวเลือกก่อนหน้า
ขั้นตอนการแก้ปัญหา
- กำหนดเมธอด isPresentInCol() รับคอลัมน์และตัวเลข
- for แต่ละแถว r ในกริด ถ้า grid[r, col] = num คืนค่า true
- คืนค่า false มิฉะนั้น
- กำหนดเมธอด isPresentInRow() รับแถวและตัวเลข
- for แต่ละคอลัมน์ c ในกริด ถ้า grid[row, c] = num คืนค่า true
- คืนค่า false มิฉะนั้น
- กำหนดเมธอด isPresentInBox() รับ boxStartRow, boxStartCol, num
- for แต่ละแถว r ใน boxStartRow ถึง 3 แถวถัดไป
- for แต่ละคอลัมน์ c ใน boxStartCol ถึง 3 คอลัมน์ถัดไป
- ถ้า grid[r, c] = num คืนค่า true
- for แต่ละคอลัมน์ c ใน boxStartCol ถึง 3 คอลัมน์ถัดไป
- คืนค่า false มิฉะนั้น
- กำหนดเมธอด findEmptyPlace() รับแถวและคอลัมน์
- for แต่ละแถว r ในกริด
- for แต่ละคอลัมน์ c ในกริด
- ถ้า grid[r, c] = 0 คืนค่า true
- for แต่ละคอลัมน์ c ในกริด
- คืนค่า false
- กำหนดเมธอด isValidPlace() รับแถว คอลัมน์ ตัวเลข
- ถ้า isPresentInRow, isPresentInCol, isPresentInBox ล้วนเป็น false คืนค่า true
- กำหนดเมธอด solveSudoku() รับกริด
- ถ้าไม่มีที่ว่างในกริด คืนค่า true
- for ตัวเลข 1 ถึง 9
- ถ้า isValidPlace(row, col, number) แล้ว
- grid[row, col] := number
- ถ้า solveSudoku = true คืนค่า true
- grid[row, col] := 0
- ถ้า isValidPlace(row, col, number) แล้ว
- คืนค่า false
ตัวอย่างโค้ด C++
#include <iostream>
#define N 9
using namespace std;
int grid[N][N] = {
{3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0}
};
bool isPresentInCol(int col, int num){
for (int row = 0; row < N; row++)
if (grid[row][col] == num)
return true;
return false;
}
bool isPresentInRow(int row, int num){
for (int col = 0; col < N; col++)
if (grid[row][col] == num)
return true;
return false;
}
bool isPresentInBox(int boxStartRow, int boxStartCol, int num){
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row+boxStartRow][col+boxStartCol] == num)
return true;
return false;
}
void sudokuGrid(){
for (int row = 0; row < N; row++){
for (int col = 0; col < N; col++){
if(col == 3 || col == 6)
cout << " | ";
cout << grid[row][col] << " ";
}
if(row == 2 || row == 5){
cout << endl;
for(int i = 0; i < N; i++)
cout << "---";
}
cout << endl;
}
}
bool findEmptyPlace(int &row, int &col){
for (row = 0; row < N; row++)
for (col = 0; col < N; col++)
if (grid[row][col] == 0)
return true;
return false;
}
bool isValidPlace(int row, int col, int num){
return !isPresentInRow(row, num) && !isPresentInCol(col, num) && !isPresentInBox(row - row%3, col - col%3, num);
}
bool solveSudoku(){
int row, col;
if (!findEmptyPlace(row, col))
return true;
for (int num = 1; num <= 9; num++){
if (isValidPlace(row, col, num)){
grid[row][col] = num;
if (solveSudoku())
return true;
grid[row][col] = 0;
}
}
return false;
}
int main(){
if (solveSudoku() == true)
sudokuGrid();
else
cout << "No solution exists";
}อินพุต
{3, 0, 6, 5, 0, 8, 4, 0, 0}, {5, 2, 0, 0, 0, 0, 0, 0, 0}, {0, 8, 7, 0, 0, 0, 0, 3, 1}, {0, 0, 3, 0, 1, 0, 0, 8, 0}, {9, 0, 0, 8, 6, 3, 0, 0, 5}, {0, 5, 0, 0, 9, 0, 6, 0, 0}, {1, 3, 0, 0, 0, 0, 2, 5, 0}, {0, 0, 0, 0, 0, 0, 0, 7, 4}, {0, 0, 5, 2, 0, 6, 3, 0, 0}เอาต์พุต
3 1 6 | 5 7 8 | 4 9 2 5 2 9 | 1 3 4 | 7 6 8 4 8 7 | 6 2 9 | 5 3 1 --------------------------- 2 6 3 | 4 1 5 | 9 8 7 9 7 4 | 8 6 3 | 1 2 5 8 5 1 | 7 9 2 | 6 4 3 --------------------------- 1 3 8 | 9 4 7 | 2 5 6 6 9 2 | 3 5 1 | 8 7 4 7 4 5 | 2 8 6 | 3 1 9