Open In App

C Program for Rat in a Maze | Backtracking-2

Improve
Improve
Like Article
Like
Save
Share
Report

We have discussed Backtracking and Knight’s tour problem in Set 1. Let us discuss Rat in a Maze as another example problem that can be solved using Backtracking.

Consider a rat placed at (0, 0) in a square matrix of order N * N. It has to reach the destination at (N – 1, N – 1). Find all possible paths that the rat can take to reach from source to destination. The directions in which the rat can move are ‘U'(up)‘D'(down)‘L’ (left), and ‘R’ (right). Value 0 at a cell in the matrix represents that it is blocked and rat cannot move to it while value 1 at a cell in the matrix represents that rat can travel through it. Return the list of paths in lexicographically increasing order.
Note: In a path, no cell can be visited more than one time. If the source cell is 0, the rat cannot move to any other cell.

C Program for Rat in a Maze using Backtracking:

Backtracking Algorithm: Backtracking is an algorithmic technique for solving problems recursively by trying to build a solution incrementally. Solving one piece at a time, and removing those solutions that fail to satisfy the constraints of the problem at any point of time (by time, here, is referred to as the time elapsed till reaching any level of the search tree) is the process of backtracking.

Approach: 

We use a backtracking algorithm to explore all possible paths. While exploring the paths we keep track of the directions we have moved so far and when we reach to the bottom right cell, we record the path in a vector of strings.

Step-by-step approach: 

  • Instead of using a 2-D array visited[][] of size n*n to keep track of the visited cells we can simply mark the cells as blocked (maze[r] = 0) as we visit them to prevent visiting this cell again.
  • Initialize a function isValid(r, c) which returns true if the cell(r, c) is inside the maze and unblocked.
  • Start at the origin (0,0) with an empty string and try all possible paths, ie. up (U), down (D), left (L) and right (R). Since the answer must be in lexicographical order, it is better to attempt the instructions in lexicographical order ie. (D,L,R,U) and take it as string=”DLRU” to avoid sorting the list in the end.
  • If the current position (r, c) is in the bottom right corner of the grid (i == n – 1 and j == n – 1), then it means a valid top-left-to-bottom-right path was found, so add the currentPath to the ans vector and return.
  • When we are at any cell (r, c), we mark the cell as blocked (maze[r] = 0), and then explore all the possible directions to move (nextr, nextc).
  • If the next cell (nextr, nextc) is valid, then add the direction to the currentPath and move to the next cell.
  • After exploring all the paths from this cell, we can mark the current cell (r, c) again as unblocked.
  • When we have traversed all the paths, return ans.

Below is the implementation of the above approach:

C




#include <stdio.h>
#include <stdbool.h>
#include <string.h>
 
const char direction[] = "DLRU";
const int dr[] = {1, 0, 0, -1};
const int dc[] = {0, -1, 1, 0};
 
const int n = 4; // Define n as the size of the maze
 
bool isValid(int r, int c, int maze[n][n]) {
    return r >= 0 && c >= 0 && r < n && c < n && maze[r];
}
 
void solve(int r, int c, int maze[n][n], char currentPath[], char ans[][100], int* count) {
    if (r == n - 1 && c == n - 1) {
        strcpy(ans[*count], currentPath);
        (*count)++;
        return;
    }
 
    maze[r] = 0;
 
    for (int i = 0; i < 4; i++) {
        int nextr = r + dr[i];
        int nextc = c + dc[i];
 
        if (isValid(nextr, nextc, maze)) {
            currentPath[strlen(currentPath)] = direction[i];
            solve(nextr, nextc, maze, currentPath, ans, count);
            currentPath[strlen(currentPath) - 1] = '\0';
        }
    }
 
    maze[r] = 1;
}
 
void findPath(int maze[n][n]) {
    if (maze[0][0] == 1) {
        char currentPath[100];
        char ans[100][100];
        int count = 0;
        currentPath[0] = '\0';
        solve(0, 0, maze, currentPath, ans, &count);
         
        if (count == 0)
            printf("-1");
        else {
            for (int i = 0; i < count; i++) {
                printf("%s ", ans[i]);
            }
        }
    }
}
 
int main() {
    int maze[4][4] = { {1, 0, 0, 0},
                      {1, 1, 0, 1},
                      {1, 1, 0, 0},
                      {0, 1, 1, 1} };
 
    findPath(maze);
 
    return 0;
}


Output

DDRDRR DRDDRR 

Time Complexity: O(2^(n^2)), the recursion can run upper-bound 2^(n^2) times.
Auxiliary Space: O(n^2), Output matrix is required so an extra space of size n*n is needed.

Please refer to the complete article on Rat in a Maze | Backtracking-2 for more details!



Last Updated : 09 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads