Stuck in a maze loop - c++

The problem
I'm new to this sort of programming, and my C++ maze solver is stuck in a loop.
The maze is a simple char 2-D matrix with an asterisk (*) for a valid path square, and a slash (/) for a wall square.
Why doesn't the program stop when it finds a '/'?
# include < iostream >
using namespace std;
char lab[6][6] =
{ { '/','/','/','/','/' },
{ '/','*','/','/','/' },
{ '/','*','*','*','/' },
{ '/','/','*','/','/' },
{ '/','/','*','/','/' },
{ '/','/','*','*','*' } };
int x, y;
void run(char lab[][6], int, int);
bool movU() // Move Up
{
if (lab[x][y - 1] == '*')
return true;
else
return false;
}
bool movR() // Move right
{
if (lab[x + 1][y] == '*')
return true;
else
return false;
}
bool movD() // Move Down
{
if (lab[x][y + 1] == '*')
return true;
else
return false;
}
bool movL() // Move Left
{
if (lab[x - 1][y] == '*')
return true;
else
return false;
}
void run(char lab[][6], int x, int y)
{
if (movU() == true) // I'm getting stuck right here
run(lab, x, y - 1); // Getting negative numbers here
else if (movR() == true)
run(lab, x + 1, y);
else if (movD() == true)
run(lab, x, y + 1);
else if (movL() == true)
run(lab, x - 1, y);
else
cout << "Error" << endl;
}
int main()
{
x = 1, y = 2; // Start position
run(lab, x, y);
return 0;
}

Besides the global scoping problem with x and y, you haven't done anything to keep the subscripts from running over the edge of the maze into random memory locations. As a result, y continues to decrement, and you back up through memory looking for an asterisk. Since you also recur, you continue this until you blow all your stack space.
Also, you don't seem to be comfortable with boolean values yet: you do a lot of extra work to deal with constants true and false, rather than simply using the value of a boolean expression.
I've fixed these items in your code:
# include <iostream>
using namespace std;
char lab[6][6] =
{
{ '/','/','/','/','/' },
{ '/','*','/','/','/' },
{ '/','*','*','*','/' },
{ '/','/','*','/','/' },
{ '/','/','*','/','/' },
{ '/','/','*','*','*' }
};
void run(char lab[][6], int, int);
bool movU(int x, int y) // Move Up
{
return x >= 0 && y >= 1 &&
x < 6 && y < 6 &&
lab[x][y - 1] == '*';
}
bool movR(int x, int y) // Move right
{
return x >= 0 && y >= 0 &&
x < 5 && y < 6 &&
lab[x+1][y] == '*';
}
bool movD(int x, int y) // Move Down
{
return x >= 0 && y >= 0 &&
x < 6 && y < 5 &&
lab[x][y + 1] == '*';
}
bool movL(int x, int y) // Move Left
{
return x >= 1 && y >= 0 &&
x < 6 && y < 6 &&
lab[x-1][y] == '*';
}
void run(char lab[][6], int x, int y)
{
cout << "ENTER run; x = " << x << "\ty = " << y << endl;
if (movU(x, y)) // I'm getting stuck right here
run(lab, x, y - 1); // Getting negative numbers here
else if (movR(x, y))
run(lab, x + 1, y);
else if (movD(x, y))
run(lab, x, y + 1);
else if (movL(x, y))
run(lab, x - 1, y);
else
cout << "Error" << endl;
}
int main()
{
// x = 1, y = 2; // Start position
run(lab, 1, 2);
return 0;
}
This stays within bounds ... and loops until it runs out of stack space. You need to add code to avoid rechecking ground you've already visited. For instance, you can mark the location with another character, such as an underscore.
You also need to recognize when you're done. What marks the maze exit? You'll need a check in your run routine for that.

Related

c++ Knights tour using recursion

I know my code is extremely close I have all of my functions working except the moveKnight() function if you do not know what knights Tour is, it's a program we are writing to help learn recursion in class. The knight is suppose to touch every space on the 8*8 chessboard only once and then prints out the move number that it took to get there. It currently only prints out the first position board[0][0]=1
but does not give "No solution".
I can not figure out where I should start looking for the problem any help is greatly appreciated.
#include <iostream>
using namespace std;
//Global Variables
//Defining the 8 possible Moves in the order from class
int yMove[8] = { 1,2, 2, 1,-1,-2,-2,-1 };
int xMove[8] = { 2,1,-1,-2,-2,-1, 1, 2 };
int board[8][8];
int startx, starty = 0;
int movecount = 1;
//checks if move is safe
bool checkSafe(int x, int y)
{
return (x >= 0 && x < 8 && y >= 0 && y < 8 && board[x][y] == 0);
}
//Prints Current board
void printBoard(int board[8][8])
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
cout << " " << board[x][y] << " ";
cout << endl;
}
}
bool moveKnight(int x, int y, int movecount)
{
if (!checkSafe(x, y))
{
board[x][y] = movecount;
return true;
}
//end condition
if (movecount == 64)
return true;
if (moveKnight(x + xMove[1], y + yMove[1], movecount + 1))
return true;
else if (moveKnight(x + xMove[0], y + yMove[0], movecount + 1))
return true;
else if (moveKnight(x + xMove[2], y + yMove[2], movecount + 1))
return true;
else if (moveKnight(x + xMove[3], y + yMove[3], movecount + 1))
return true;
else if (moveKnight(x + xMove[4], y + yMove[4], movecount + 1))
return true;
else if (moveKnight(x + xMove[5], y + yMove[5], movecount + 1))
return true;
else if (moveKnight(x + xMove[6], y + yMove[6], movecount + 1))
return true;
else if (moveKnight(x + xMove[7], y + yMove[7], movecount + 1))
return true;
else
{
board[x][y] = 0;
return false;
}
}
int KnightTour()
{
//creating board
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
board[x][y] = 0;
}
board[startx][starty] = 1;
movecount + 1;
//No possible moves
if (!moveKnight(startx, starty, movecount))
cout << "Not possible";
else
{
//yes possible now print
printBoard(board);
}
//exits
return 0;
}
int main()
{
//calls knights tour
KnightTour();
cout << endl;
system("pause");
return 0;
}
Your moveKnight function returns immediately because it determines the very first position is not a valid move. The reason is you initialized the board with a non-zero value at the start position.
Remove these two lines from main:
board[startx][starty] = 1;
movecount + 1;
The first one breaks your recursion, and the second one does nothing at all.
Additionally, the logic after calling checkSafe() is screwy, because at the moment when you determine a move is either out-of-bounds or already-played, you are writing a value to the board. That's going to result in undefined behavior.
Correcting these things, and also simplifying the recursive calls:
bool moveKnight(int x, int y, int movecount)
{
if (checkSafe(x, y))
{
board[x][y] = movecount;
if (movecount == 64)
return true;
for (int i = 0; i < 8; i++)
{
if (moveKnight(x + xMove[i], y + yMove[i], movecount + 1))
return true;
}
board[x][y] = 0;
}
return false;
}

How can I get the common digits of two int in C++? Example: (1234, 41567) --> 1 4

Given two int I want to get all the common digits and print out them separated by spaces.
So for example, if int x=1234; int y=41567; then I want to print out: 1 4.
This is my code. It does not work properly. When I run it, it prints 0 1 2 3 4 5 then stops.
I don't want to use vector nor arrays.
void problema3() {
int x, y, kX=0, kY=0;
cout << "x="; cin >> x;
cout << "y="; cin >> y;
int cx = x;
int cy = y;
for (int i = 0; i < 10; i++) {
kX = 0;
kY = 0;
x = cx;
y = cx;
while (x != 0 || kX==0) {
if (x % 10 == i) kX=1;
x /= 10;
}
while (y != 0 || kY == 0) {
if (y % 10 == i) kY=1;
y /= 10;
}
if (kX == 1 && kY == 1) cout << i << ' ';
}
}
int main()
{
problema3();
return 0;
}
If you're allowed to use std::set then you can do what you want as follows:
#include <iostream>
#include <set>
void print(int x, int y)
{
int individual_number1 = 0, individual_number2 = 0;
std::set<int> myset;
int savey = y;//this will be used to reset y when the 2nd do while loop finishes
do
{
individual_number1 = x % 10;
do
{
individual_number2 = y % 10;
if(individual_number1 == individual_number2)
{
myset.insert(individual_number1);
break;
}
y = y / 10;
}while( y > 0);
y = savey;
x = x / 10;
} while (x > 0);
//print out the element of the set
for(int i: myset)
{
std::cout<<i<<" ";
}
}
int main()
{
int x = 1234, y = 41567;
print(x, y);
return 0;
}
The output of the above program is as follows:
1 4
which can be seen here.
Your main bug is when assigning copies of cy.
//...
for (int i = 0; i < 10; i++) {
//...
x = cx;
y = cx; // <-- BUG! should read y = cy;
But that's not the only bug in your program.
Your digit detection logic is wrong. In particular, zero is not handled correctly, and since you did not put that reusable code in a function, your program is way more complex than it needs.
Here's the corrected logic for digit detection.
// checks if base 10 representation of a positive integer contains a certain digit (0-9)
bool hasDigit(int x, int d)
{
do
{
if (x % 10 == d)
return true;
x /= 10;
} while (x != 0);
return false;
}
Your main loop then becomes:
// assuming int x, y as inputs.
// ...
for (int i = 0; i < 10; ++i)
{
if (hasDigit(x, i) && hasDigit(y, i))
std::cout << i << ' ';
}
Which leaves very little room for bugs.
You can play with the code here: https://godbolt.org/z/5c5brEcEq

Finding a path in a maze via backtracking

I want to make a program to find if a path exists from upper right corner to down left corner in a maze via backtracking. The input numbers are n and m which are the dimensions of rectangular maze and a maze, character '.' means a tile which you can go through and character 'x' means a tile which you cant go through. I have wrote the code, its fairly simple but nothing gets displayed whilst it should display "da" (on Serbian "yes") and "ne" (on Serbian "no").
#include <bits/stdc++.h>
using namespace std;
bool maze[20][20]; //defined maze of maximum size 20x20
//checking if a position is viable for moving through
bool Safe(int n, int m, int x, int y)
{
if(x >= 0 && x < n && y >= 0 && y < m)
{
if(maze[x][y] == 1) return true;
}
return false;
}
bool Utility(int n, int m, int x, int y) //main utility function
{
if(x == n - 1 && y == m - 1 && maze[x][y] == 1) // base case, end of maze
{
return true;
}
if(Safe(n, m, x, y))
{
if(Safe(n, m, x + 1, y)) // checking if it is viable to move down
{
if(Utility(n, m, x + 1, y))
{
return true;
}
}
if(Safe(n, m, x, y + 1))
{
if(Utility(n, m, x, y + 1)) // checking if it is viable to move right
{
return true;
}
}
if(Safe(n, m, x - 1, y))
{
if(Utility(n, m, x - 1, y)) // checking if it is viable to move up
{
return true;
}
}
if(Safe(n, m, x, y - 1))
{
if(Utility(n, m, x, y - 1)) // checking if it is viable to move left
{
return true;
}
}
}
return false; // returning false
}
int main()
{
int n, m;
cin >> n >> m; // input dimensions of the maze
for(int i = 0; i < n; i++) // input maze
{
for(int j = 0; j < m; j++)
{
char c;
cin >> c;
if(c == '.') //character '.' means a tile which you can go through
{
maze[i][j] = 1;
}
else //character 'x' means a tile which you cannot go through
{
maze[i][j] = 0;
}
}
}
if(Utility(n, m, 0, 0)) //printing yes or no
{
cout << "da";
}
else
{
cout << "ne";
}
return 0;
}
Sample Input:
8 8
.x.....x
.x.x.x.x
.x.x.x.x
.x.x.x.x
.x.x.x.x
.x.x.x.x
.x.x.x.x
...x.x..
Sample output: da
The problem was that, say if you go from (0, 0) -> (1, 0), then at (1, 0) you can again go back to (0, 0) and this would loop forever. To avoid that, I created a visited array which will have value true if cell (x, y) is already visited, else false.
I have marked where I made the changes with ///////////// change here ///////////// comment
#include <bits/stdc++.h>
using namespace std;
bool maze[20][20]; //defined maze of maximum size 20x20
///////////// change here /////////////
bool visited[20][20];
bool Safe(int n, int m, int x, int y) //checking if a position is viable for moving through
{
if(x >= 0 && x < n && y >= 0 && y < m)
{
if(maze[x][y] == 1) return true;
}
return false;
}
bool Utility(int n, int m, int x, int y) //main utility function
{
if(x == n - 1 && y == m - 1 && maze[x][y] == 1) // base case, end of maze
{
return true;
}
///////////// change here /////////////
if(!visited[x][y] && Safe(n, m, x, y))
{
///////////// change here /////////////
visited[x][y] = true;
if(Safe(n, m, x + 1, y)) // checking if it is viable to move down
{
if(Utility(n, m, x + 1, y))
{
return true;
}
}
if(Safe(n, m, x, y + 1))
{
if(Utility(n, m, x, y + 1)) // checking if it is viable to move right
{
return true;
}
}
if(Safe(n, m, x - 1, y))
{
if(Utility(n, m, x - 1, y)) // checking if it is viable to move up
{
return true;
}
}
if(Safe(n, m, x, y - 1))
{
if(Utility(n, m, x, y - 1)) // checking if it is viable to move left
{
return true;
}
}
}
return false; // returning false
}
int main()
{
int n, m;
cin >> n >> m; // input dimensions of the maze
for(int i = 0; i < n; i++) // input maze
{
for(int j = 0; j < m; j++)
{
char c;
cin >> c;
if(c == '.') //character '.' means a tile which you can go through
{
maze[i][j] = true;
}
else //character 'x' means a tile which you cannot go through
{
maze[i][j] = false;
}
///////////// change here /////////////
visited[i][j] = false;
}
}
if(Utility(n, m, 0, 0)) //printing yes or no
{
cout << "da";
}
else
{
cout << "ne";
}
return 0;
}
Here's the link where I tested it: https://ideone.com/vVqAjF

Multiplying using recursive function C++

I did a recursive function to calculate x*y with x and y are all integers (x and y >= 0). My formula is:
x * y =
0, if x is equal 0
(x >> 1)*(y << 1), if x is an even number
(x >> 1)*(y << 1) + y, if x is an odd number
"<<" and ">>" are Left Shift and Right Shift Bitwise Operator. Here is my code:
int multiply(int x, int y) {
int y1 = 0;
if (x == 0) return 0;
else if (x % 3 == 0) {
y1 = y;
x = x >> 1;
y = y << 1;
return (multiply(x, y) + y1);
}
else if (x % 2 == 0) {
x = x >> 1;
y = y << 1;
return multiply(x, y);
}
}
The recursive function above is supposed to return (x*y) value but they were all wrong when i tested and i don't know why. What did i do wrong? How can i fix this?
Your problem is wit x % 3, what happens if x = 5? you skip it. Here is improved version of your code.
int multiply(int x, int y) {
if (x == 0)
return 0;
else if (x % 2 == 1)
return (multiply(x >> 1, y << 1) + y);
return multiply(x >> 1, y << 1);
}
or maybe even this:
int multiply(int x, int y) {
if (x == 0)
return 0;
int m = multiply(x >> 1, y << 1);
if (x % 2 == 1)
m += y;
return m;
}
Here is super fast version suggested by Andy:
int multiply(int x, int y) {
if (x == 0)
return 0;
int m = multiply(x >> 1, y << 1);
if (x & 1)
m += y;
return m;
}
As a challenge of speed, here is non recursive version:
int multiply (int x, int y) {
int y1 = 0;
for (; x > 0; x = (x >> 1), y = (y << 1))
if (x&1)
y1 += y;
return y1;
}
NOTE: I know this question is about recursive method but just as a challenge I wrote non-recursive algorithm.
You are not checking if x is odd correctly here:
else if (x % 3 == 0) { // e.g. fails on x = 1
Instead, you need to do
else if (x % 2 == 1) {
Here's a demo.
Note that this makes the following else check for even values of x redundant:
else if (x % 2 == 0) { // can just be an unconditional else
Also, since you are returning from the x == 0, and x % 2 == 1 branches, the else conditions can be removed as well. You can also factor out the repeated code to make the function simpler, like this:
int multiply(int x, int y) {
if (x == 0) return 0;
if (x % 2 == 1)
return (multiply(x >> 1, y << 1) + y);
else
return multiply(x >> 1, y << 1);
}
Here's a demo.
This is what i feel is the simplest approach to carry out recursive multiplication.
Do let me know if its efficient enough for you.
#include<iostream>
using namespace std;
float multiply(float a, float b) {
//no zeros bro
if (b == 0)
return 0;
//let the recursion begin
if (b > 0)
return x + multiply(a, b - 1);
//negatives stay away pliz
if (y < 0)
return -multiply(a, -b);
}
int main() {
float a, b, result;
cout << "Enter the two numbers";
cin >> a >> b;
result = multiply(a, b);
//And the result is.................
cout << result;
return 0;
}
Recursive function related to multiplication of natural numbers:
int multCool(int a, int b)
{
return (b==1 ? a: a+ multCool(a,b-1));
}

Segmentation fault in recursive backtracking maze generator C++

I am trying to create a maze generator using recursive backtracking and have come across a problem that I just can't get my head around. For some reason my move function is returning the value "18446744073709551615". This is (of course) leading to a segmentation fault. Why is my move function returning such a large value when my move function can only increase or decrease the value by 2?
bool maze::generate(size_t x, size_t y) {
//mark the position as visited
labyrinth.s[y][x] = true;
//print to see progress
//this->print();
//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
return true;
}
}
//pick a random direction
do {
d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;
if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
return true;
}
}
void maze::initialize(size_t x, size_t y) {
//set the maxhight and the maxwidth to y and x
labyrinth.MAXHIGHT = y;
labyrinth.MAXWIDTH = x;
//set all elements in the vector to #
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<char> temp;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp.push_back(labyrinth.wall);
}
labyrinth.v.push_back(temp);
}
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
labyrinth.v[j][i] = labyrinth.path;
}
}
}
//set all posistions to unvisited
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<bool> temp2;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp2.push_back(false);
}
labyrinth.s.push_back(temp2);
}
//setup the start point
labyrinth.v[0][1] = 'S';
//setup the endpoint
labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';
}
//if a position has been visited or if not possible to go to return true
bool maze::pos_test(size_t x, size_t y, size_t d) const {
//if the position is out of bounds return false
if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
return true;
}
else if (x == 1 && d == LEFT) {
return true;
}
else if (y == 1 && d == UP) {
return true;
}
else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
return true;
}
else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
return true;
}
else if (d == UP) {
return labyrinth.s[y - 2][x];
}
else if (d == DOWN) {
return labyrinth.s[y + 2][x];
}
else if (d == RIGHT) {
return labyrinth.s[y][x + 2];
}
else if (d == LEFT) {
return labyrinth.s[y][x - 2];
}
else {
return true;
}
}
size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
return y;
}
else if (d == UP) {
labyrinth.v[y - 1][x] = labyrinth.path;
return y = y - 2;
}
else if (d == DOWN) {
labyrinth.v[y + 1][x] = labyrinth.path;
return y = y + 2;
}
else if (d == RIGHT) {
labyrinth.v[y][x + 1] = labyrinth.path;
return x = x + 2;
}
else if (d == LEFT) {
labyrinth.v[y][x - 1] = labyrinth.path;
return x = x - 2;
}
else {
}
}
You are underflowing your unsigned 64-bit return type size_t.
You are checking whether x and y are below zero, but that's not enough, because 0 and 1 will still be too low because you are subtracting 2!
The number you get is 0xFFFFFFFFFFFFFFFF in hexadecimal. This is the highest possible value for an unsigned 64-bit integer.
It comes from calculating 1 - 2. Yes, this is supposed to be -1, but because your move function doesn't return a signed number but an unsigned one (check the docs on size_t), it can't be negative! Instead, it wraps around to the highest possible number.
You can imagine this in the same way you would get ...99999999999 when you try to calculate 1 - 2 on paper ignoring the "you can't subtract a higher number from a smaller one on paper" rule.
As a side note: I guess the negative result is undesired anyway, because actually your huge number, once added to a pointer, will in turn overflow back into positive, so basically it will work the same is a real -1 in your case and the segmentation fault comes from accessing something right before the beginning of your buffer, not far beyond it, but it comes down to the same thing.
Apart from that, there is no need to do return y = y - 2 and such. Just return y - 2.