Skip to content

Added English Tutorial for LOJ-1397: Sudoku Solver #400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 4, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions 1397
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Sudoku Solver

###### Helpful Resources:

[Sudoku Solver Geeks For Geeks](https://www.geeksforgeeks.org/sudoku-backtracking-7/)

[Understanding Sudo solves in CPP](https://www.youtube.com/watch?v=lIOupNAafT0)

[Introduction to Backtracking](https://www.youtube.com/watch?v=DKCbsiDBN6c)

###### Solution Approach

Firstly we implement a basic sudoku solver with four important points:

1)We first have to find the empty positions for that we have the findEmptyLocation function
2) To solve a sudoku we have to place a number at an empty position, '.' in this case such that this number is not present in the respective row, column or box, this is why we use the isSafe function
3) If empty location found, we check if there exists a value that satisfies our required conditions of possible values that can be placed in that box, if for all boxes the number of values that needs to be exceeded exceeds 9 then that sudoku is unsolvable
4) Here we are using a brute force to find the required solution via backtracking

## Solution in C++
```cpp
#include<bits/stdc++.h>
using namespace std;
#define N 9

int grid[N][N];

bool isSafeInRow(int& row,int value){
for(int i=0;i<N;i++){
if(grid[row][i]==value){
return false;
}
}
return true;
}

bool isSafeInCol(int& col,int value){
for(int i=0;i<N;i++){
if(grid[i][col]==value){
return false;
}
}
return true;
}

bool isSafeBox(int& row,int& col, int value){
int rowFactor=row-row%3;
int colFactor=col-col%3;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(grid[i+rowFactor][j+colFactor]==value){
return false;
}
}
}
return true;
}

bool isSafe(int& row,int& col,int value){
if(isSafeInRow(row,value) && isSafeInCol(col,value) && isSafeBox(row,col,value)){
return true;
}
return false;
}

bool findEmptyLocation(int& x,int& y){
/*
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(grid[i][j]==0){
x=i;
y=j;
return true;
}
}
}
return false;
*/
int Min=10,cnt=0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if(grid[i][j]==0){
int cnt=0;
for(int k=1;k<=9;k++)
{
if (isSafe(i,j,k))
cnt++;
}
if(cnt<Min)
{
Min=cnt;
x=i;
y=j;
}
}
}
}
if(Min<10)
return true;
return false;
}



bool solveSudoku(){
int row,col;
if(!findEmptyLocation(row,col)){
return true;
}
for(int i=1;i<=9;i++){
if(isSafe(row,col,i)){
grid[row][col]=i;
if(solveSudoku()){
return true;
}
grid[row][col]=0;
}
}
return false;
}

void solve(){
string inp[N];
string s;
getline(cin,s);
for(int i=0;i<N;i++){
getline(cin,inp[i]);
}
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(inp[i][j]=='.'){
grid[i][j]=0;
}
else grid[i][j]=inp[i][j]-'0';
}
}
solveSudoku();
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cout<<grid[i][j];
}
cout<<endl;
}
}



int main(void){
int t;
cin>>t;
cin.ignore();
for(int i=1;i<=t;i++){
cout<<"Case "<<i<<": "<<endl;
solve();
}
return 0;
}

```