This is the variation of Rat in Maze
A Maze is given as N*N binary matrix of blocks where source block is the upper left most block i.e., maze[0][0] and destination block is lower rightmost block i.e., maze[N-1][N-1]. A rat starts from source and has to reach destination. The rat can move only in two directions: forward and down.
In the maze matrix, 0 means the block is dead end and non-zero number means the block can be used in the path from source to destination. The non-zero value of mat[i][j] indicates number of maximum jumps rat can make from cell mat[i][j].
In this variation, Rat is allowed to jump multiple steps at a time instead of 1.
Examples:
Input : { {2, 1, 0, 0},
{3, 0, 0, 1},
{0, 1, 0, 1},
{0, 0, 0, 1}
}
Output : { {1, 0, 0, 0},
{1, 0, 0, 1},
{0, 0, 0, 1},
{0, 0, 0, 1}
}
Explanation
Rat started with M[0][0] and can jump upto 2 steps right/down.
Let's try in horizontal direction -
M[0][1] won't lead to solution and M[0][2] is 0 which is dead end.
So, backtrack and try in down direction.
Rat jump down to M[1][0] which eventually leads to solution.
Input : {
{2, 1, 0, 0},
{2, 0, 0, 1},
{0, 1, 0, 1},
{0, 0, 0, 1}
}
Output : Solution doesn't exist
Naive Algorithm:
The Naive Algorithm is to generate all paths from source to destination and one by one check if the generated path satisfies the constraints.
while there are untried paths
{
generate the next path
if this path has all blocks as non-zero
{
print this path;
}
}
Backtracking Algorithm:
If destination is reached
print the solution matrix
Else
a) Mark current cell in solution matrix as 1.
b) Move forward/jump (for each valid steps) in horizontal direction
and recursively check if this move leads to a solution.
c) If the move chosen in the above step doesn't lead to a solution
then move down and check if this move leads to a solution.
d) If none of the above solutions work then unmark this cell as 0
(BACKTRACK) and return false.
Implementation of Backtracking solution
C++
#include <stdio.h>
#define N 4
bool solveMazeUtil( int maze[N][N], int x, int y,
int sol[N][N]);
void printSolution( int sol[N][N])
{
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++)
printf ( " %d " , sol[i][j]);
printf ( "\n" );
}
}
bool isSafe( int maze[N][N], int x, int y)
{
if (x >= 0 && x < N && y >= 0 &&
y < N && maze[x][y] != 0)
return true ;
return false ;
}
bool solveMaze( int maze[N][N])
{
int sol[N][N] = { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } };
if (solveMazeUtil(maze, 0, 0, sol) == false ) {
printf ( "Solution doesn't exist" );
return false ;
}
printSolution(sol);
return true ;
}
bool solveMazeUtil( int maze[N][N], int x, int y,
int sol[N][N])
{
if (x == N - 1 && y == N - 1) {
sol[x][y] = 1;
return true ;
}
if (isSafe(maze, x, y) == true ) {
sol[x][y] = 1;
for ( int i = 1; i <= maze[x][y] && i < N; i++) {
if (solveMazeUtil(maze, x + i, y, sol) == true )
return true ;
if (solveMazeUtil(maze, x, y + i, sol) == true )
return true ;
}
sol[x][y] = 0;
return false ;
}
return false ;
}
int main()
{
int maze[N][N] = { { 2, 1, 0, 0 },
{ 3, 0, 0, 1 },
{ 0, 1, 0, 1 },
{ 0, 0, 0, 1 } };
solveMaze(maze);
return 0;
}
|
Java
class GFG
{
static int N = 4 ;
static void printSolution( int sol[][])
{
for ( int i = 0 ; i < N; i++)
{
for ( int j = 0 ; j < N; j++)
{
System.out.printf( " %d " , sol[i][j]);
}
System.out.printf( "\n" );
}
}
static boolean isSafe( int maze[][], int x, int y)
{
if (x >= 0 && x < N && y >= 0 &&
y < N && maze[x][y] != 0 )
{
return true ;
}
return false ;
}
static boolean solveMaze( int maze[][])
{
int sol[][] = {{ 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 }};
if (solveMazeUtil(maze, 0 , 0 , sol) == false )
{
System.out.printf( "Solution doesn't exist" );
return false ;
}
printSolution(sol);
return true ;
}
static boolean solveMazeUtil( int maze[][], int x,
int y, int sol[][])
{
if (x == N - 1 && y == N - 1 )
{
sol[x][y] = 1 ;
return true ;
}
if (isSafe(maze, x, y) == true )
{
sol[x][y] = 1 ;
for ( int i = 1 ; i <= maze[x][y] && i < N; i++)
{
if (solveMazeUtil(maze, x + i, y, sol) == true )
{
return true ;
}
if (solveMazeUtil(maze, x, y + i, sol) == true )
{
return true ;
}
}
sol[x][y] = 0 ;
return false ;
}
return false ;
}
public static void main(String[] args)
{
int maze[][] = {{ 2 , 1 , 0 , 0 },
{ 3 , 0 , 0 , 1 },
{ 0 , 1 , 0 , 1 },
{ 0 , 0 , 0 , 1 }};
solveMaze(maze);
}
}
|
Python3
N = 4
def printSolution(sol):
for i in range (N):
for j in range (N):
print (sol[i][j], end = " " )
print ()
def isSafe(maze, x, y):
if (x > = 0 and x < N and y > = 0 and
y < N and maze[x][y] ! = 0 ):
return True
return False
def solveMaze(maze):
sol = [[ 0 , 0 , 0 , 0 ],
[ 0 , 0 , 0 , 0 ],
[ 0 , 0 , 0 , 0 ],
[ 0 , 0 , 0 , 0 ]]
if (solveMazeUtil(maze, 0 , 0 , sol) = = False ):
print ( "Solution doesn't exist" )
return False
printSolution(sol)
return True
def solveMazeUtil(maze, x, y, sol):
if (x = = N - 1 and y = = N - 1 ) :
sol[x][y] = 1
return True
if (isSafe(maze, x, y) = = True ):
sol[x][y] = 1
for i in range ( 1 , N):
if (i < = maze[x][y]):
if (solveMazeUtil(maze, x + i,
y, sol) = = True ):
return True
if (solveMazeUtil(maze, x,
y + i, sol) = = True ):
return True
sol[x][y] = 0
return False
return False
maze = [[ 2 , 1 , 0 , 0 ],
[ 3 , 0 , 0 , 1 ],
[ 0 , 1 , 0 , 1 ],
[ 0 , 0 , 0 , 1 ]]
solveMaze(maze)
|
C#
using System;
class GFG
{
static int N = 4;
static void printSolution( int [,]sol)
{
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < N; j++)
{
Console.Write( " {0} " , sol[i, j]);
}
Console.Write( "\n" );
}
}
static Boolean isSafe( int [,]maze,
int x, int y)
{
if (x >= 0 && x < N && y >= 0 &&
y < N && maze[x, y] != 0)
{
return true ;
}
return false ;
}
static Boolean solveMaze( int [,]maze)
{
int [,]sol = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};
if (solveMazeUtil(maze, 0, 0, sol) == false )
{
Console.Write( "Solution doesn't exist" );
return false ;
}
printSolution(sol);
return true ;
}
static Boolean solveMazeUtil( int [,]maze, int x,
int y, int [,]sol)
{
if (x == N - 1 && y == N - 1)
{
sol[x, y] = 1;
return true ;
}
if (isSafe(maze, x, y) == true )
{
sol[x, y] = 1;
for ( int i = 1;
i <= maze[x, y] && i < N; i++)
{
if (solveMazeUtil(maze, x + i,
y, sol) == true )
{
return true ;
}
if (solveMazeUtil(maze, x,
y + i, sol) == true )
{
return true ;
}
}
sol[x, y] = 0;
return false ;
}
return false ;
}
public static void Main(String[] args)
{
int [,]maze = {{2, 1, 0, 0},
{3, 0, 0, 1},
{0, 1, 0, 1},
{0, 0, 0, 1}};
solveMaze(maze);
}
}
|
Javascript
<script>
let N = 4;
function printSolution(sol)
{
for (let i = 0; i < N; i++)
{
for (let j = 0; j < N; j++)
{
document.write(sol[i][j] + " " );
}
document.write( "<br/>" );
}
}
function isSafe(maze, x, y)
{
if (x >= 0 && x < N && y >= 0 &&
y < N && maze[x][y] != 0)
{
return true ;
}
return false ;
}
function solveMaze(maze)
{
let sol = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]];
if (solveMazeUtil(maze, 0, 0, sol) == false )
{
document.write( "Solution doesn't exist" );
return false ;
}
printSolution(sol);
return true ;
}
function solveMazeUtil(maze, x,
y, sol)
{
if (x == N - 1 && y == N - 1)
{
sol[x][y] = 1;
return true ;
}
if (isSafe(maze, x, y) == true )
{
sol[x][y] = 1;
for (let i = 1; i <= maze[x][y] && i < N; i++)
{
if (solveMazeUtil(maze, x + i, y, sol) == true )
{
return true ;
}
if (solveMazeUtil(maze, x, y + i, sol) == true )
{
return true ;
}
}
sol[x][y] = 0;
return false ;
}
return false ;
}
let maze = [[2, 1, 0, 0],
[3, 0, 0, 1],
[0, 1, 0, 1],
[0, 0, 0, 1]];
solveMaze(maze);
</script>
|
Output: 1 0 0 0
1 0 0 1
0 0 0 1
0 0 0 1
Time Complexity: The time complexity of the backtracking algorithm used in the code is exponential, which means O(2^(n^2)) in the worst case scenario where n is the size of the maze.
Space Complexity: The space complexity of the code is O(n^2) because it requires a 2D array of size n x n to store the solution matrix. Additionally, the recursive calls to the function also require additional space on the stack, which can go up to O(n^2) in the worst case.