ninjakx
ninjakx

Reputation: 35

Find if path exist or not in maze c++

My code is giving me runtime error. I can't figure it out how to resolve it? It's not even working for smaller matrix 4 X 4 . Matrix size for the problem is not more than 20 x 20.

Code:

#include <iostream>
using namespace std;
int a[20][20];
bool findpath(int ar[][20],int i,int j,int size)
{
    if (ar[i][j]==0 || i>(size-1) || j>(size-1) || i<0 || j<0)
        return false;
    if (ar[i][j]==2)
        return true;
    if ((findpath(ar,i+1,j,size)) || (findpath(ar,i,j+1,size)) 
    || (findpath(ar,i-1,j,size)) || (findpath(ar,i,j-1,size)))
        return true;
    return false;
}
int main() {
    int t;
    cin>>t;
    while(t--)
    {   int n;
        cin>>n;

        int r,c;

        //size = n;
        for(int i =0 ;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cin>>a[i][j];
                if (a[i][j]==1)
                   { r=i;
                    c=j;
                   }
            }

        }
        //cout<<r<<c;
        bool b = findpath(a,r,c,n);
        if (b)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;

    }
    return 0;
}

Input:

1
4
3 0 0 0 0 3 3 0 0 1 0 3 0 2 3 3 

Output:

YES

But I am getting Segmentation Fault (SIGSEGV)

Upvotes: 0

Views: 739

Answers (1)

Samer Tufail
Samer Tufail

Reputation: 1894

Check the order of evaluation of your statement if (ar[i][j]==0 || i>(size-1) || j>(size-1) || i<0 || j<0). You will access ar[i][j] to evaluate the first expression even if i is out of bounds or j is out of bounds. It should be in the order so that when a short circuit does happen in the if condition you are safe/does not result in undefined behaviour for example:

if (i < 0 || i >= size || j < 0 || j >= size || ar[i][j]==0). Now if i < 0 it shorcircuits and does not need to check the rest and does not evaluate ar[i][j].

As you mentioned this is not working, here is a working version which I will explain. First I have changed your C style arrays to vectors and rather I use those to get row and col sizes. I also removed your inputs from users which you can add in later and helps keep the problem simple.

#include <vector>
bool findpath(vector<vector<int>>ar,int i,int j,vector<vector<int>>& visited)
{

    if (i < 0 || i >= ar.size() || j < 0 || j >= ar[0].size() || ar[i][j] == 0 || visited[i][j]) return false;

    if (ar[i][j]==2) return true;

    visited[i][j] = true;
    if(findpath(ar,i+1,j,visited) || findpath(ar,i,j+1,visited) || findpath(ar,i-1,j,visited) || findpath(ar,i,j-1,visited)) return true;
    visited[i][j] = false;

    return false;
}
int main() {
        const int rows = 3;
        const int cols = 3;
        vector<vector<int>> arr = {{ 0 , 3 , 2 },
                                   { 3 , 3 , 0 },
                                   { 1 , 3 , 0 }};

        vector<vector<int>> visited(rows,vector<int>(cols,false));
        bool b = findpath(arr,1,1,visited);
        if (b)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;


    return 0;
}

In the main function I have just used a vector<vector<int>> to describe a maze which was in the link you posted. The i and j are the starting points in the example below that is 1 and 1. There is also a visited 2D array same as the maze. This stops you from going in an infinite recursion by marking the spots you have already covered and if they dont work out you set vector[i][j] = false to backtrack. Lastly if any of your arrangements returns a valid result we return else we just return false.

You can view this demo live here

You also mention that 1 is the starting point. In the example I have already started from 1. You can add a loop in main to first figure out the coordinates for the starting point. Again this should be enough to get you going.

Upvotes: 2

Related Questions