Showing posts with label Backtracking. Show all posts
Showing posts with label Backtracking. Show all posts

Prison Break

Alfie was a prisoner in mythland. Though Alfie was a witty and intelligent guy.He was confident of escaping prison.After few days of observation,He figured out that the prison consists of (N×N) cells.i.e The shape of prison was (N×N) matrix. Few of the cells of the prison contained motion detectors.So Alfie planned that while escaping the prison he will avoid those cells containing motion detectors.Yet before executing his plan,Alfie wants to know the total number of unique possible paths which he can take to escape the prison.Initially Alfie is in cell
(1,1) while the exit of the cell (N,N).

note:->Alfie can move in all four direction{ if his current location is (X,Y), he can move to either
(X+1,Y)(X1,Y)(X,Y+1)(X,Y1) }. If the first cell (1,1) and the last cell(N,N) contain motion detectors,then Alfie can't break out of the prison.

Example:

Input:  n = 4, arr = {{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}, {0, 1, 1, 0}}
Output: 2

Approach

C++

#include <bits/stdc++.h>
using namespace std;

const int N = 22;

int a[N][N];

bool vis[N][N];

//all four directions
int dx[] = {-1100};
int dy[] = {00, -11};
int ansn;

void dfs(int iint j)
{

    //mark as visited
    vis[i][j] = 1;

    //if we reach to the destination
    if (i == n && j == n)
        ans++;

    for (int z = 0z < 4z++)
    {
        int x = i + dx[z], y = j + dy[z];

        //check for valid cell
        if (x >= 1 && x <= n and y >= 1 && y <= n)
        {

            //if not visited and value is 0
            //then call for dfs
            if (!a[x][y] and !vis[x][y])
                dfs(xy);
        }
    }

    //mark as unvisited (backtrack)
    vis[i][j] = 0;
}

int main()
{

    ans = 0;

    n = 4;
    vector<vector<int>> arr = {{0110},
                               {0010},
                               {0000},
                               {0110}};

    for (int i = 1i <= ni++)
    {
        for (int j = 1j <= nj++)
        {
            a[i][j] = arr[i - 1][j - 1];
        }
    }
    dfs(11);

    cout << ans << "\n";

    return 0;
}


Implement an efficient sudoku solver

Sudoku is a puzzle where you're given a partially-filled 9 by 9 grid with digits. The objective is to fill the grid with the constraint that every row, column, and box (3 by 3 subgrid) must contain all of the digits from 1 to 9.

Implement an efficient sudoku solver.

Example:

Input:  {{0, 9, 0, 0, 0, 0, 8, 5, 3}, {0, 0, 0, 8, 0, 0, 0, 0, 4}, {0, 0, 8, 2, 0, 3, 0, 6, 9}, {5, 7, 4, 0, 0, 2, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 9, 0, 0, 6, 3, 7}, {9, 4, 0, 1, 0, 8, 5, 0, 0}, {7, 0, 0, 0, 0, 6, 0, 0, 0}, {6, 8, 2, 0, 0, 0, 0, 9, 0}}

Output:

------------------------------------- 2 | 9 | 7 | 6 | 1 | 4 | 8 | 5 | 3 | ------------------------------------- 1 | 3 | 6 | 8 | 5 | 9 | 7 | 2 | 4 | ------------------------------------- 4 | 5 | 8 | 2 | 7 | 3 | 1 | 6 | 9 | ------------------------------------- 5 | 7 | 4 | 3 | 6 | 2 | 9 | 1 | 8 | ------------------------------------- 3 | 6 | 9 | 7 | 8 | 1 | 2 | 4 | 5 | ------------------------------------- 8 | 2 | 1 | 9 | 4 | 5 | 6 | 3 | 7 | ------------------------------------- 9 | 4 | 3 | 1 | 2 | 8 | 5 | 7 | 6 | ------------------------------------- 7 | 1 | 5 | 4 | 9 | 6 | 3 | 8 | 2 | ------------------------------------- 6 | 8 | 2 | 5 | 3 | 7 | 4 | 9 | 1 | -------------------------------------

Approach:

C++

#include <bits/stdc++.h>
using namespace std;

#define LINE "|"
#define NEWROW "-------------------------------------"

// Prints the Soduko grid
void printGrid(int grid[9][9])
{
    for (int i = 0i < 9i++)
    {
        cout << "    \n";
        cout << NEWROW << endl;
        for (int j = 0j < 9j++)
        {
            cout << " ";

            //empty cell of the grid
            if (grid[i][j] == 0)
            {
                cout << " ";
            }

            //otherwise print that
            else
            {
                cout << grid[i][j];
            }
            cout << " ";
            cout << LINE;
        }
    }
    cout << "\n"
         << NEWROW << "\n"
         << "\n";
}

//check for valid row by assigning value to any
//cell
bool isValidRow(int grid[9][9], int rowint num)
{
    for (int col = 0col < 9col++)
        if (grid[row][col] == num)
        {
            return true;
        }
    return false;
}

//check for valid col by assigning value  by assigning
//any cell
bool isValidCol(int grid[9][9], int colint num)
{
    for (int row = 0row < 9row++)
        if (grid[row][col] == num)
        {
            return true;
        }
    return false;
}

//check if the box of 3x3 is valid ot not
bool isValidBox(int grid[9][9], int boxStartRow
int boxStartColint num)
{
    for (int row = 0row < 3row++)
        for (int col = 0col < 3col++)
            if (grid[row + boxStartRow][col + boxStartCol] == num)
            {
                return true;
            }
    return false;
}

//check whether it will be legal to assign
// num to the given row,col location.
bool isSafe(int grid[9][9], int rowint colint num)
{
    // Check if 'num' is not already placed in current row,
    // current column and current 3x3 box
    return !isValidRow(gridrownum) &&
           !isValidCol(gridcolnum) &&
           !isValidBox(gridrow - row % 3col - col % 3num);
}

//check for empty cell
pair<intintgetEmptyLocation(int grid[9][9])
{
    for (int row = 0row < 9row++)
        for (int col = 0col < 9col++)
            if (grid[row][col] == 0)
            {
                return make_pair(rowcol);
            }
    return make_pair(99);
}

//function to check if we can solve the sudoku
bool solveSudoku(int grid[9][9])
{
    // If the Soduko grid has been filled, we are done
    if (getEmptyLocation(grid== make_pair(99))
    {
        return true;
    }

    // Get an unassigned Soduko grid location
    std::pair<intintrow_and_col = getEmptyLocation(grid);
    int row = row_and_col.first;
    int col = row_and_col.second;

    // Consider digits 1 to 9
    for (int num = 1num <= 9num++)
    {
        //if by placing current value into
        //the current cell is valid then place it
        if (isSafe(gridrowcolnum))
        {
            //assign value to current cell
            grid[row][col] = num;

            //call recursively
            if (solveSudoku(grid))
            {
                return true;
            }
            //backtrack
            grid[row][col] = 0;
        }
    }
    //if not valid then return false;
    return false;
}
int main()
{

    int grid[9][9] = {{090000853},
                      {000800004},
                      {008203069},
                      {574002000},
                      {000000000},
                      {000900637},
                      {940108500},
                      {700006000},
                      {682000090}};

    if (solveSudoku(grid))
    {
        printGrid(grid);
    }
    else
    {
        cout << "No solution exists for the given Soduko\n";
    }

    return 0;
}


N-Queens

The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space, respectively.

Example:

Input: n = 4
Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]

Approach:

C++

#include <bits/stdc++.h>
using namespace std;

vector<vector<string>> ans;

bool isValid(vector<string&currint rint c)
{
    for (int i = ri >= 0i--)
    {
        if (curr[i][c] == 'Q')
            return false;
    }
    for (int i = rj = ci >= 0 && j >= 0i--, j--)
    {
        if (curr[i][j] == 'Q')
            return false;
    }
    for (int i = rj = ci >= 0 && j < curr.size(); i--, j++)
    {
        if (curr[i][j] == 'Q')
            return false;
    }
    return true;
}

void dfs(vector<string&currint r)
{
    if (curr.size() == r)
    {
        ans.push_back(curr);
        return;
    }
    for (int i = 0i < curr.size(); i++)
    {
        if (isValid(currri))
        {
            curr[r][i] = 'Q';
            dfs(currr + 1);
            curr[r][i] = '.';
        }
    }
}

vector<vector<string>> solveNQueens(int n)
{
    vector<stringcurr(nstring(n'.'));
    dfs(curr0);
    return ans;
}

int main()
{
    int n = 4;

    vector<vector<string>> queens = solveNQueens(n);

    cout << "[";
    for (int i = 0i < queens.size(); i++)
    {
        cout << "[";
        for (int j = 0j < queens[i].size(); j++)
        {
            cout << queens[i][j];
            if (j != queens[i].size() - 1)
                cout << ", ";
        }
        cout << "]";
        if (i != queens.size() - 1)
            cout << ", ";
    }
    cout << "]";

    return 0;
}