Finding path in a 2-d maze - c++

Why is this code giving run-time error. I am trying to find if their exist a path inside the maze to reach the food(2). 0 representing obstacle, 1 representing path, and 2 is for the destination.
`{0,1,1,0,0},
{1,0,1,1,1},
{0,0,0,0,0},
{0,1,1,1,1},
{0,0,1,1,0},
{1,0,1,1,2}`
I'm passing the starting point as findpath(a,3,2) where a is the maze and i=3, j=2 as the starting point.
Code on ideone: http://ideone.com/poF9um
Thanks guys, for helping me. I have rectified my mistake.
Here's the ideone link for the updated code: http://ideone.com/poF9um
Thanks.
#include <iostream>
using namespace std;
/*int insideMaze(int x, int y){
if(x>=6 || y >=5 || x<0 || y< 0)
{
return 0;
}
return 1;
}*/
bool findPath(int a[6][5], int n1, int m1){
if(n1>=6 || m1 >=5 || n1<0 || m1<0){
return false;
}
if(a[n1][m1] == 0){
return false;
}
if(a[n1][m1]==2){
return true;
}
//a[n1][m1] = 4;
if(findPath(a,n1-1,m1)==true){
return true;
}
if(findPath(a,n1,m1-1)==true){
return true;
}
if(findPath(a,n1+1,m1)==true){
return true;
}
if(findPath(a,n1,m1+1)==true){
return true;
}
return false;
}
int main() {
// your code goes here
//int a[10][10];
int a[6][5] = {
{0,1,1,0,0},
{1,0,1,1,1},
{0,0,0,0,0},
{0,1,1,1,1},
{0,0,1,1,0},
{1,0,1,1,2}
};
if(findPath(a,3,2)){
cout<<"Path Found";
}
return 0;
}

The problem is caused by stack overflow. Your depth-first search does not mark locations that it visits, so the same location would be visited multiple times.
You start at (3, 2), and try going left.
This takes you to (3, 1).
There is no path left of (3, 1), so you go right.
This takes you back to (3, 2), from where you try to go left.
This takes you to (3, 1).
There is no path left of (3, 1), so you go right...
See the problem? To fix it, add another array of the spots that you have visited, and check it before continuing with the search. This will fix the issue.

I guess that the code causes infinite recursive calls.
You begin with executing findPath(a,3,2).
Since a[3][2]==1, the code will call findPath(a,3,1).
Now, since a[3][1]==1, the code will later call again to findPath(a,3,2) again...
And so on... Until you run out of memory / stack overflow...

Related

Creating a function using the binary search

I am trying to use a function to find a number in an array using the binary search. The code runs in visual studio community but does not work in code blocks. It just shows found.Would appreciate if some could point out why it's not working. This is the function
void sort(int array[7],int num)
{
int left=0,right=7;
while (left<=right)
{
int mid = (left+right)/2;
if(array[mid]==num)
{
cout<<"found";
break;
}
else if(num<array[mid])
right = mid-1;
else
left = mid+1;
}
if(left > right) cout<<"not found";
}
When you write, int array[7], then you create an array which can be indexed 0..6. Therefore, you should use right = 6.
Also, be very careful when you write right = mid - 1 or left = mid + 1. You need to be sure that the new values are within 0..6. E.g., left == 0, right == 1, mid == 0 - after this, you say right = - 1. That's not ok, you need boundary checks.

Calling functions randomly using a vector

#assume everything needed is included
void Robot::moveRobot()
{
//calls a random directon for robot to move in
//if direction returns false (not able to move in that direction),
//call another random direction up to 4 times, excluding the one(s)
//already called. If they all return false, do not move the robot.
//vecDir = {moveForward(), moveBackward(), moveRight(), moveLeft()}
// = {0,1,2,3} initially
vector<int> vecDir{0,1,2,3}; //vetor indicating direction to move
int num = rand() % vecDir.size();
if(num == vecDir[0])
{
//if not able to move forward, try a different random direction
if(Robot::moveForward() == false)
{
vecDir.erase(num);
//here, vector will be vecDir={1,2,3}
}
}
else if(num == vecDir[1])
{
Robot::moveBackward();
}
else if(num == vecDir[2])
{
Robot::moveRight();
}
else //num == vecDir[3]
{
Robot::moveLeft();
}
}
Hi! I'm trying to randomly call these four functions within the moveRobot() function using a vector whose size is changed depending on if a direction cannot be called. I set moveForward() to the first element, moveBackward() to the second element, etc. If any of the moveXXXX() functions are false, I want to delete that element of the array. Example code shown
Example output:
//before doing anything, vecDir = {0,1,2,3}
int num = rand() % vecDir.size(); //assume num = 1, so it calls moveBackward()
//assume moveBackward() is false, so gets rid of that element
vecDir.erase(num); //new vecDir = {0,2,3};
// vecDir(0) would be moveForward(), vecDir(1) is now moveRight(), vecDir(1) is now moveLeft()
How would I continue this process to exhaust all elements and not move a robot? I know a for loop would be involved, but I cannot think of where to use it. I am also not sure if my thinking is correct by using if else for each element. Any help is appreciated, and I apologize if the question is confusing. I can clear it up if there are any misunderstandings.
Just have a vector of function pointers, rather then numbers.
void Robot::moveRobot() {
// vector of pointers to functions to move
std::vector<bool()> moves{
moveForward(), moveBackward(), moveRight(), moveLeft()
};
// we repeat the process until any moves are available.
while (moves.size() > 0) {
// pick a random move
const int num = rand() % moves.size();
// try to move
if (moves[num]() == true) {
// yay, we moved!
break;
}
// we did not move - remove current option and repeat
moves.erase(moves.begin() + num);
}
}

staircase child always getting a 0?

Hi I am a beginner in recursions.
Question:
A child is running up a staircase he can hop 1, 2 or 3 steps at a time I need to find and return the number of ways he can climb a certain stair number?
My approach:
I am trying to divide the problem into smaller base cases and add 1 when a correct ans is reached.
My code:
void helper(int n ,int& a){
if(n==0){
a = a+1;
return;
}
if(n<0)
return;
helper(n-1,a);
helper(n-2,a);
helper(n-3,a);
}
int staircase(int n){
int ans = 0;
helper(n,ans);
return ans;
}
Problem:
I seem to be getting only 0 as answer?
I dont see why your code won't work. Here is a demo of it working with some changes: Live Demo
It is recommended that you don't pass in a reference and rather make each sub-problem which is either step 1, 2 or 3 self contained problems where you combine the results and that is the final answer similar to:
int staircase_without_reference(int n)
{
if(n == 0) return 1;
if(n < 0) return 0;
return staircase(n - 1) + staircase(n - 2) + staircase(n - 3);
}
This returns the similar to your program without the reference parameter.

Recursive Mazes: when multiple paths

Following is a representation of a maze that I wish to solve using recursion. S is the starting point and F is the finishing point. The numbers on top and left represent the coordinates.
I have written the code but the problem is that when the current position is 3,2 then there are 3 options for next current position: top, left and down.
If I remove the option to go leftward, then it is solved correctly and the output is "Maze not solved" because current positive never reaches F(finishing coordinate).
However, with leftward condition, I get no solution and an infinite loop is run.
Here's part of the code (only including direction==3 which means if next move will be leftward):
bool solveRecursive(char grid[][6],int siz, int curRow, int curCol, int direction,bool check)
{
while(check==0)
{
if(curRow==4 && curCol==0)
{
check = 1;
}
else if (direction == 3) // If open space in west
{
//}
if(grid[curRow][curCol-1] == '.')
{
curCol--;
check = solveRecursive(grid,siz,curRow,curCol,3,check);
}
if (grid[curRow-1][curCol] == '.')
{
curRow--;
check = solveRecursive(grid,siz,curRow,curCol, 0,check);
}
else if (grid[curRow+1][curCol] == '.')
{
curRow++;
check = solveRecursive(grid,siz,curRow, curCol, 2,check);
}
else
return 0;
}
}
return check;
}

While loop not equaling std::queue size

I have this code:
std::queue<unsigned int> offsets;
// (fill offsets here)
DEBUG(std::to_string(offsets.size())) // print offsets.size() to console
int iterations = 0;
while (!offsets.empty())
{
iterations++;
unsigned int currOffset = offsets.front();
offsets.pop();
if (currOffset == 0)
{
DEBUG("breaking from while loop")
break;
}
// do something with currOffset
}
DEBUG(std::to_string(iterations))
For some reason, iterations never equals offsets.size(). I'm not sure why this is. In my test application, offsets.size() == 28, but iterations == 11. I only break from the while loop once in this application.
Any idea why this is happening? Help is greatly appreciated.
Because the 11th offset is zero and the conditional break triggers before the loop reaches the end of your data structure?
Either that or // do something with currOffset involves popping more things from the queue.
The if breaks the loop if front() == 0, doesn't need be empty.
while (!offsets.empty())
{
iterations++;
unsigned int currOffset = offsets.front();
offsets.pop();
if (currOffset == 0) // *** Here is the problem ***
{
DEBUG("breaking from while loop")
break;
}
// do something with currOffset
}