Recursively determine minimum moves to all fields on gameboard - c++

I'm in the process of trying to understand recursion better, so I decided to write a program to determine the shortest paths to all fields on an N * N game board, using recursion (I know BFS would be faster here, this is just for the sake of learning):
void visit(int x, int y, int moves)
{
if (x < 0 || x >= n || y < 0 || y >= n) {
return; // out of board
} else if (board[y][x] != -1) {
// already visited, check if path is shorter
if (moves < board[y][x]) board[y][x] = moves;
return;
} else {
// first time visiting
board[y][x] = moves;
visit(x + 1, y, moves + 1); // right
visit(x, y + 1, moves + 1); // down
visit(x, y - 1, moves + 1); // up
visit(x - 1, y, moves + 1); // left
}
}
# called with visit(0, 0, 0), so it should be able to start at any field
However, for a 3x3 board, it yields the following board:
0 1 2
1 2 3
6 5 4
The first two rows are right, however, the last row (except the last column in the last row) is wrong. It should be:
0 1 2
1 2 3
2 3 4
Here's a 4x4 board:
0 1 2 3
1 2 3 4
12 9 6 5
13 8 7 6

else if (board[y][x] != -1) {
// already visited, check if path is shorter
if (moves < board[y][x]) board[y][x] = moves;
return;
}
Returning here is wrong. You've just lowered the score on this path—there are probably other paths in the area whose scores could be lowered:
void visit(int x, int y, int moves)
{
if (x < 0 || x >= n || y < 0 || y >= n) {
return; // out of board
} else if (board[y][x] == -1 || moves < board[y][x]) {
// first time visiting
board[y][x] = moves;
visit(x + 1, y, moves + 1);
visit(x, y + 1, moves + 1);
visit(x, y - 1, moves + 1);
visit(x - 1, y, moves + 1);
} else {
return;
}
}
Works as expected.

You are doing a depth first search which may find sub-optimal paths to some squares.
To get optimal paths, if your path is shorter you should still visit from it, even if it is already visited.

This would work.
void visit(int x, int y, int moves)
{
if (x < 0 || x >= n || y < 0 || y >= n) {
return; // out of board
}
else if ( board[y][x] == -1 || moves < board[y][x])
{
board[y][x] = moves;
visit(x + 1, y, moves + 1);
visit(x, y + 1, moves + 1);
visit(x, y - 1, moves + 1);
visit(x - 1, y, moves + 1);
}
}
Moreover, if you initialize each element of board with (2*n-2) instead of -1, you can drop the ( board[y][x] == -1 ) condition and have just (moves < board[y][x]) in the else if part.

Related

Simplifying a code snippet - vector rotation in a circle

Given the following code pattern, wherein I am trying to state a vector direction in increments of 45 degrees over the integers int x and int y, inside of a circle positioned at the origin
// x == 0 && y == 0 case is already taken cared of
if(x > 1) {
if(y == 0) {
// horizontal right
m_rotation = 0;
}else if(y < 1) {
// diagonal down right
m_rotation = 315;
} else if(y > 1) {
// diagonal up right
m_rotation = 45;
}
} else if(x == 0) {
if(y < 1) {
// vertical down
m_rotation = 270;
} else if(y > 1) {
// vertical up
m_rotation = 90;
}
} else if(x < 1){
if(y == 0) {
// horizontal left
m_rotation = 180;
}else if(y < 1) {
// diagonal down left
m_rotation = 225;
} else if(y > 1) {
// diagonal up left
m_rotation = 135;
}
}
I am looking for an elegant way to make this compact. I know there's the spaceship operator <=>, but I need to restrict myself to C++17.
Things I have tried
Nesting ternary operators with m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));, but this looks weird
I tried putting the x == 0 case inside x < 1 case and transform the later into else, but that does not simplify enough the code
Using absolute values to compare x and y, but I quickly get lost
Nothing else really, I don't know what else to try
Something like
constexpr int rotation[3][3] = {
{225, 180, 135},
{270, 0, 90},
{315, 0, 45},
};
if (x != 0 || y != 0) // if (!(x == 0 && y == 0))
m_rotation = rotation[1 + sign(x)][1 + sign(y)];
There is a closed form:
// standard sign functions
int xs = x < 0 ? -1 : x > 0;
int ys = y < 0 ? -1 : y > 0;
return 180 - 45 * (xs + 2) * ys + 90 * (xs * xs + xs) * (ys * ys - 1);
or shorter
return 180 * (x < 0 || y) - 45 * (xs + 2) * ys;

How do I make it go in diagonal directions?

I have code that I already have four basic directions (Up, Down, Left, Right). However, I want to have them go in diagonal directions as well, so it will add up to eight directions. How would I do that? What I see from it, I basically have to have two directions change at the same time, but I don't know how to do that.
Code:
// problem with backtracking using stack
#include <cstring>
#include <iostream>
#include <stack>
using namespace std;
#define N 4
#define M 5
class node {
public:
int x, y;
int dir;
node(int i, int j)
{
x = i;
y = j;
// Initially direction
// set to 0
dir = 0;
}
};
// maze of n*m matrix
int n = N, m = M;
// Coordinates of food
int fx, fy;
bool visited[N][M];
bool isReachable(int maze[N][M])
{
// Initially starting at (0, 0).
int i = 0, j = 0;
cout << '[' << i << ':' << j << ']';
stack<node> s;
node temp(i, j);
s.push(temp);
while (!s.empty()) {
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.top();
int d = temp.dir;
i = temp.x, j = temp.y;
// Increment the direction and
// push the node in the stack again.
temp.dir++;
s.pop();
s.push(temp);
// If we reach the Food coordinates
// return true
if (i == fx and j == fy) {
return true;
}
// Checking the Up direction.
if (d == 0) {
if (i - 1 >= 0 and maze[i - 1][j] == 1 and
!visited[i - 1][j]) {
cout <<'['<< i - 1 << ':'<<j << ']' ;
node temp1(i - 1, j);
visited[i - 1][j] = true;
s.push(temp1);
}
}
// Checking the left direction
else if (d == 1) {
if (j - 1 >= 0 and maze[i][j - 1] == 1 and
!visited[i][j - 1]) {
cout << '[' << i << ':' << j-1 << ']' ;
node temp1(i, j - 1);
visited[i][j - 1] = true;
s.push(temp1);
}
}
// Checking the down direction
else if (d == 2) {
if (i + 1 < n and maze[i + 1][j] == 1 and
!visited[i + 1][j]) {
cout << '[' << i + 1 << ':' << j << ']' ;
node temp1(i + 1, j);
visited[i + 1][j] = true;
s.push(temp1);
}
}
// Checking the right direction
else if (d == 3) {
if (j + 1 < m and maze[i][j + 1] == 1 and
!visited[i][j + 1]) {
cout << '[' << i << ':' << j + 1<< ']' ;
node temp1(i, j + 1);
visited[i][j + 1] = true;
s.push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else {
visited[temp.x][temp.y] = false;
s.pop();
}
//system("pause");
}
// If the stack is empty and
// no path is found return false.
return false;
}
// Driver code
int main()
{
// Initially setting the visited
// array to true (unvisited)
memset(visited, false, sizeof(visited));
// Maze matrix
int maze[N][M] = {
{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 }
};
// Food coordinates
fx = 2;
fy = 3;
if (isReachable(maze)) {
cout << "Path Found!" << '\n';
}
else
cout << "No Path Found!" << '\n';
return 0;
}```
By combining the conditions you already have... You have the following for checking the second dimension:
if (j + 1 < m and maze[i][j + 1] == 1 and !visited[i][j + 1])
If you want to increment both at once you would do something like:
if (i + 1 < n and j + 1 < m and maze[i + 1][j + 1] == 1 and !visited[i + 1][j + 1])
Since you have 4 diagonals, you would do similar checkings for the other 3 diagonals. Be careful with copy and paste not to forget to increment/decrement both i and j.
Let's assume a board, with row 0 and column 0 in the upper left corner.
Also, assume the present position is at <row, column>.
There are 8 locations relative to the present position (unless you are near the edge of the board).
+---------------------+---------------------+--------------------+
| row - 1, column - 1 | row - 1, column + 0 | row - 1, column + 1|
+---------------------+---------------------+--------------------+
| row + 0, column - 1 | row, column | row + 0, column + 1|
+---------------------+---------------------+--------------------+
| row + 1, column - 1 | row + 1, column + 0 | row + 1, column + 1|
+---------------------+---------------------+--------------------+
Before making a move, check the validity of the next move.
The next move would be based on the above table.

Rat in maze problems, how to display coordinates where rat stepped in random generated matrix?

I started coding and searched a lot codes on internet but couldn't find the solution for my problem. I'm gonna paste there my current code. I already coded that if there is perfect path for rat or no (rat can only step on number one, "0" and "2" are walls.) But I cant display the coordinates of each "number one". For an example:
1,0,1,
1,2,2,
1,1,1,
Then the path is, (0,0) -> (1,0) -> (2,0) -> (1,2) -> (2,2)
if the matrix is
1,0,2,
0,2,1,
1,0,1,
Then no path for the rat.
Please edit my code and paste it there please or if you have already solved program for my problem please share it with me... I'm really new in c++.
// CPP program to solve Rat in a maze
// problem with backtracking using stack
#include <cstring>
#include <iostream>
#include <stack>
using namespace std;
#define N 4
#define M 5
void mtxkeres(int (&mat)[N][M]);
class node {
public:
int x, y;
int dir;
node(int i, int j)
{
x = i;
y = j;
// Initially direction
// set to 0
dir = 0;
}
};
// maze of n*m matrix
int n = N, m = M;
// Coordinates of food
int fx, fy;
bool visited[N][M];
bool isReachable(int maze[N][M])
{
// Initially starting at (0, 0).
int i = 0, j = 0;
stack<node> s;
node temp(i, j);
s.push(temp);
while (!s.empty()) {
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.top();
int d = temp.dir;
i = temp.x, j = temp.y;
// Increment the direction and
// push the node in the stack again.
temp.dir++;
s.pop();
s.push(temp);
// If we reach the Food coordinates
// return true
if (i == fx and j == fy) {
return true;
}
// Checking the Up direction.
if (d == 0) {
if (i - 1 >= 0 and maze[i - 1][j] and
visited[i - 1][j]) {
node temp1(i - 1, j);
visited[i - 1][j] = false;
s.push(temp1);
}
}
// Checking the left direction
else if (d == 1) {
if (j - 1 >= 0 and maze[i][j - 1] and
visited[i][j - 1]) {
node temp1(i, j - 1);
visited[i][j - 1] = false;
s.push(temp1);
}
}
// Checking the down direction
else if (d == 2) {
if (i + 1 < n and maze[i + 1][j] and
visited[i + 1][j]) {
node temp1(i + 1, j);
visited[i + 1][j] = false;
s.push(temp1);
}
}
// Checking the right direction
else if (d == 3) {
if (j + 1 < m and maze[i][j + 1] and
visited[i][j + 1]) {
node temp1(i, j + 1);
visited[i][j + 1] = false;
s.push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else {
visited[temp.x][temp.y] = true;
s.pop();
}
}
// If the stack is empty and
// no path is found return false.
return false;
}
// Driver code
int main()
{
// Initially setting the visited
// array to true (unvisited)
memset(visited, true, sizeof(visited));
// Maze matrix
int maze[N][M] = {
{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 }
};
// Food coordinates
fx = 2;
fy = 3;
if (isReachable(maze)) {
cout << "Path Found!" << '\n';
}
else
cout << "No Path Found!" << '\n';
return 0;
}

How do I check the neighbors of the cells around me in a 2D array (C++)?

So I'm trying to check if the cells surrounding the current cell of any given 2D array have a certain value (0 or 1) and depending on the value I want to count the total amount (total 1 values surrounding the current cell) however I'm not sure how to grab the positions below is some psuedocode I wrote that I think will consider each general position for a cell to be in however I'm not completely certain it is correct, and if it is correct I'm not sure how to grab the surrounding cells. Its not necessary to write out the whole code but basically I'm looking for conditions for positions to check for in future nested if statements that will of these big if statements such as array
if array([xPosition+1][yPosition+1] == 1)
Here is the pesudocode
if (xPosition==0 && yPosition==0) {
} else if (xPosition==rows && yPosition==columns) {
} else if (xPosition==rows && yPosition==0) {
} else if (xPosition==0 && yPosition==columns) {
} else if (xPosition==0) {
} else if (xPosition==rows) {
} else if (yPosition==0) {
} else if (yPosition==columns) {
} else {
}
You can use nested loops
int sum{0};
for (int x{std::max(xPosition, 1) - 1}; x < std::min(xPosition + 2, columns); ++x) {
for (int y{std::max(yPosition, 1) - 1}; y < std::min(xPosition + 2, rows); ++y) {
if (x == xPosition && y == yPosition) continue;
sum += array[x][y];
}
}
The code is self explanatory and I have added the comments
bool isSafe(int xPosition, int yPosition,
int rows, int columns) { // checking the boundry
return (xPosition >= 0 && xPosition < rows &&
yPosition >= 0 && yPosition < columns);
}
void checkNeighbours(int xPosition, int yPosition,
int rows, int columns) {
// Considering only 4 directions up, down , right, left
int count = 0;
if(isSafe(xPosition - 1, yPosition)) { // one cell up
if(array[xPosition - 1][yPosition] == 1) {
count ++;
}
}
if(isSafe (xPosition + 1, yPosition)) { // one cell down
if(array[xPosition + 1][yPosition] == 1) {
count ++;
}
}
if(isSafe(xPosition, yPosition - 1)) { // one cell left
if(array[xPosition][yPosition - 1] == 1) {
count ++;
}
}
if(isSafe(xPosition, yPosition + 1)) { // one cell right
if(array[xPosition][yPosition + 1] == 1) {
count ++;
}
}
// use count for whatever
}

C++ Pascal's triangle

I'm looking for an explanation for how the recursive version of pascal's triangle works
The following is the recursive return line for pascal's triangle.
int get_pascal(const int row_no,const int col_no)
{
if (row_no == 0)
{
return 1;
}
else if (row_no == 1)
{
return 1;
}
else if (col_no == 0)
{
return 1;
}
else if (col_no == row_no)
{
return 1;
}
else
{
return(get_pascal(row_no-1,col_no-1)+get_pascal(row_no-1,col_no));
}
}
I get how the algorithm works
What I wonder is how the recursion does the work.
Your algorithm contains a couple of unnecessary predicates for the base cases. It can be stated more simply as follows:
int pascal(int row, int col) {
if (col == 0 || col == row) {
return 1;
} else {
return pascal(row - 1, col - 1) + pascal(row - 1, col);
}
}
This of course assumes that you're guaranteeing that the arguments passed to the function are non-negative integers; you can always include an assertion if you can't impose such a guarantee from outside the function.
Pascal's triangle is essentially the sum of the two values immediately above it....
1
1 1
1 2 1
1 3 3 1
etc
In this, the 1's are obtained by adding the 1 above it with the blank space (0)
For code, all the 1's are occupied in either the first column (0), or when the (col == row)
For these two border conditions, we code in special cases (for initialization). The main chunk of the code (the recursive part) is the actual logic.
(The condition 'row == 1' is not necessary)
The most optimized way is this one:
int pascal(int row, int col) {
if (col == 0 || col == row) return 1;
else if(col == 1 || (col + 1) == row) return row;
else return pascal(row - 1, col - 1) + pascal(row - 1, col);
}
Unlike Fox's algorithm it prevents recursive calls for values which can be easily computed right from the input values.
Refer to the page for the source code:
#include <stdio.h>
int main()
{
int n, x, y, c, q;
printf("Pascal Triangle Program\n");
printf("Enter the number of rows: ");
scanf("%d",&n);
for (y = 0; y < n; y++)
{
c = 1;
for(q = 0; q < n - y; q++)
{
printf("%3s", " ");
}
for (x = 0; x <= y; x++)
{
printf(" %3d ",c);
c = c * (y - x) / (x + 1);
}
printf("\n");
}
printf("\n");
return 0;
}
The output would be,
Pascal Triangle Program
Enter the number of rows: 11
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
Pascal's triangle can be got from adding the two entries above the current one.
| 0 1 2 3 column
--+----------------------------------------------
0 | 1 (case 1)
1 | 1 (case 2) 1 (case 2)
2 | 1 (case 3) 2 (sum) 1 (case 4)
3 | 1 (case 3) 3 (sum) 3 (sum) 1 (case 4)
row
etc., for example column 2, row 3 = column 2, row 2 + column 1, row 2, where the cases are as follows:
if (row_no == 0) // case 1
{
return 1;
}
else if (row_no == 1) // case 2
{
return 1;
}
else if (col_no == 0) // case 3
{
return 1;
}
else if (col_no == row_no) // case 4
{
return 1;
}
else // return the sum
return pascalRecursive(height-1,width)+pascalRecursive(height-1,width-1);
Here is the code of #kathir-softwareandfinance
with more readable and more meaning variable names
#include <stdio.h>
int main()
{
int nOfRows, cols, rows, value, nOfSpace;
printf("Pascal Triangle Program\n");
printf("Enter the number of rows: ");
scanf("%d",&nOfRows);
for (rows = 0; rows < nOfRows; rows++)
{
value = 1;
for(nOfSpace = 0; nOfSpace < nOfRows - rows; nOfSpace++)
{
printf("%3s", " ");
}
for (cols = 0; cols <= rows; cols++)
{
printf(" %3d ",value);
value = value * (rows - cols) / (cols + 1);
}
printf("\n");
}
printf("\n");
return 0;
}
Here is how the recursion works
We call v(i, j), it calls v(i - 1, j), which calls v(i - 2, j) and so on,
until we reach the values that are already calculated (if you do caching),
or the i and j that are on the border of our triangle.
Then it goes back up eventually to v(i - 1, j), which now calls v(i - 2, j - 1),
which goes all the way to the bottom again, and so on.
....................................................................
_ _ _ _ call v(i, j) _ _ _ _ _
/ \
/ \
/ \
call v(i - 1, j) v(i - 1, j - 1)
/ \ / \
/ \ / \
call v(i - 2, j) v(i - 2, j - 1) v(i - 2, j - 1) v(i - 2, j - 2)
....................................................................
If you need to get the value often, and if you have enough memory:
class PascalTriangle
# unlimited size cache
public
def initialize
#triangle = Array.new
end
def value(i, j)
triangle_at(i, j)
end
private
def triangle_at(i, j)
if i < j
return nil
end
if #triangle[i].nil?
#triangle[i] = Array.new(i + 1)
else
return #triangle[i][j]
end
if (i == 0 || j == 0 || i == j)
#triangle[i][j] = 1
return #triangle[i][j]
end
#triangle[i][j] = triangle_at(i - 1, j) + triangle_at(i - 1, j - 1)
end
end
Using ternary approach for optimization; only 1 return command needed.
int f(int i, int j) {
return (
(i <= 1 || !j || j == i) ? 1 :
(f(i - 1, j - 1) + f(i - 1, j))
);
}
see explanation