check if index is out of bounds to satisfy if conditions - c++

Hello I am practicing working with 2d arrays in c++ and my question is for example if I want to check if 4 has either 0 or 11 to the north , east, south, west as neighbour it should return false.
this is my if
if((grid[0-1][0] == 0 || grid[0-1][0] == 11 ) &&
(grid[0+1][0] == 0 || grid[0+1][0] == 11 ) &&
(grid[0][0+1] == 0 || grid[0][0+1] ==11) &&
(grid[0][0-1] == 0 || grid[0][0-1] ==11 ))
{
return false;
}
Now my problem is since west of 4 and north of four is out of bounds it will never return false.
How could I optimise my if condition to make it return false?
This is my 2d array
int grid[ROW][COL] = {{ 4, 11, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 5, 0},
{ 0, 5, 0,0 } };

TL;DR
you are missing boundary conditions
// Boundary Conditions
if( i == ROW || j == COL || i < 0 || j < 0 )
return false;
Based on the question the matrix is defined as
#define ROW 4
#define COL 4
int grid[ROW][COL] = {{ 4, 11, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 5, 0},
{ 0, 5, 0,0 } };
given a cell at row i and col j denoted by cordinated i, j the visualization in a 2-D array for that will look like this
i-1, j-1 i-1, j i-1,j+1
i, j-1 i, j i,j+1
i+1, j-1 i+1, j i+1,j+1
from above we can now deduce the corresponding cordinates/points reference to given i,j
i,j ---> North( i-1, j )
i,j ---> South( i+1, j )
i,j ---> East( i , j+1)
i,j ---> West( i , j-1)
now we can write a small function to check if a given value at any cell denoted by i and j is true or not, this below function does similar .. checks if supplied coordinates are within boundary and if the value at grid[j]j] matches what we need to match
bool Check( int grid[ROW][COL], int expected, int i, int j )
{
// Boundary Conditions
if( i == ROW || j == COL || i < 0 || j < 0 )
return false;
return ( grid[i][j] == expected );
}
Now time to put the North, South, West, East calculation to code and expose them as nice functions,
bool northHas( int grid[ROW][COL], int expected, int i, int j )
{
return check(grid, expected, i-1, j );
}
bool southHas( int grid[ROW][COL], int expected, int i, int j )
{
return check(grid, expected, i+1, j );
}
bool eastHas( int grid[ROW][COL], int expected, int i, int j )
{
return check(grid, expected, i, j+1 );
}
bool westHas( int grid[ROW][COL], int expected, int i, int j )
{
return check(grid, expected, i, j-1 );
}
each of these functions above exposes a nicer interface to deal with what logic program wants to do
if( (northHas( grid, 0, i, j ) || northHas( grid, 11, i, j)) &&
( eastHas( grid, 0, i, j ) || eastHas( grid, 11, i, j)) &&
(southHas( grid, 0, i, j ) || southHas( grid, 11, i, j)) &&
( westHas( grid, 0, i, j ) || westHas( grid, 11, i, j)) )
{
return false
}

Related

checking the values of the neighboring points

I am currently working on a code that checks the giving index neighbors (north, west, east, south) and if the neighbors have the value 0 or 11 it should return false. The start point is 0,0 which has the value 4.
This is my test function.
bool testG(int grid[ROW][COL], int row, int col) {
if (row < 0 || col < 0 || row >= ROW || col >= COL)
return false;
return grid[row][col] == 0 || grid[row][col] == 11;
}
this is my query:
if(testG(grid,-1,0) && testG(grid,0,-1) && testG(grid,1,0) && testG(grid,0,1))
{
return false;
}
and this is my 2d array that should return false if the function is called.
int grid[ROW][COL] {{ 4, 11, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 5, 0},
{ 0, 5, 0,0 } };
if the array looks like this it should return true.
int grid[ROW][COL] {{ 4, 11, 1, 1 },
{ 1, 1, 1, 0 },
{ 0, 1, 5, 0},
{ 0, 5, 0,0 } };
My problem is the first two parts of the if queryif(testG(grid,-1,0) && testG(grid,0,-1) this won't return true for the 2d array above because to the west and north of the number 4 is out of bounds.
How can I optimize my code so that one part of the index is left out if it's out of bounds but if the other queries are correct it should return false?
Thanks in advance.
It looks like you want to judge if each cells are one of:
out-of-bounds
have value 0
have value 11
To realize this, the function testG should return true for not only the "have value 0" and "have value 11" case but also "out-of-bounds" case.
bool testG(int grid[ROW][COL], int row, int col) {
if (row < 0 || col < 0 || row >= ROW || col >= COL)
return true; // return true for out-of-bounds case
return grid[row][col] == 0 || grid[row][col] == 11;
}
struct location {
int row = 0;
int col = 0;
};
int get( int grid[ROW][COL], location l ) {
return grid[l.row][l.col];
}
std::vector<location> get_adjacents( location l ) {
std::vector<location> retval;
if (l.row-1 >= 0) retval.push_back( {l.row-1, l.col} );
if (l.row+1 < ROW) retval.push_back( {l.row+1, l.col} );
if (l.col-1 >= 0) retval.push_back( {l.row, l.col-1} );
if (l.col+1 < COL) retval.push_back( {l.row, l.col+1} );
return retval;
}
bool testG_adjacents( int grid[ROW][COL], location l ) {
for (auto adjacent : get_adjacents(l) )
if (!testG(grid, adjacent.row, adjacent.col))
return false;
return true;
}
this attempts to split the adjacent in-bounds logic from the test logic.

runtime error: reference binding to misaligned address 0xbebebebebebebec6 for type 'int', which requires 4 byte alignment (stl_vector.h)

i am writing code to solve this problem on leetcode
my strategy to solve this is:
run dfs for each cell index (x,y)
on each dfs call check if cell is a destination cell
accordingly set the flags
if both flags are true then add this cell to "ans" vector else carry on with the next dfs
class Solution {
public:
void psUtil(vector<vector<int> >&mat, int x, int y, int m, int n, int &isP, int &isA, vector<vector<int> >&vis, vector<vector<int> >&ans)
{
//check dstinations
if(x == 0 || y == 0)
{
isP = 1;
}
if(x == m || y == n)
{
isA = 1;
}
vector<int> cell(2);
cell[0] = x;
cell[1] = y;
// check both dst rched
if(isA && isP)
{
// append to ans
ans.push_back(cell);
return;
}
// mark vis
vis.push_back(cell);
int X[] = {-1, 0, 1, 0};
int Y[] = {0, 1, 0, -1};
int x1, y1;
// check feasible neighbours
for(int i = 0; i < 4; ++i)
{
x1 = x + X[i];
y1 = y + Y[i];
if(x1 < 0 || y1 < 0) continue;
if(mat[x1][y1] <= mat[x][y])
{
vector<vector<int> > :: iterator it;
vector<int> cell1(2);
cell1[0] = x1;
cell1[1] = y1;
it = find(vis.begin(), vis.end(), cell1);
if(it == vis.end());
else continue;
psUtil(mat, x1, y1, m, n, isP, isA, vis, ans);
if(isA && isP) return;
}
}
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix)
{
// find dimensions
int m = matrix.size(); // rows
int n = matrix[0].size(); // cols
vector<vector<int> >ans;
// flags if rched destinations
int isP, isA;
isP = isA = 0;
// iterate for all indices
for(int x = 0; x < m; ++x)
{
for(int y = 0; y < n; ++y)
{
// visited nested vector
vector<vector<int> >vis;
psUtil(matrix, x, y, m, n, isP, isA, vis, ans);
isP = isA = 0;
}
}
return ans;
}
};
and my error on running this is
Runtime Error Message:
Line 924: Char 9: runtime error: reference binding to misaligned address 0xbebebebebebebec6 for type 'int', which requires 4 byte alignment (stl_vector.h)
Last executed input:
[[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
why am i getting this message and how do i fix it?
i found my error ! it was because of a missing boundary check for the newly calculated coordinate and improper boundary check for a coordinate in the beginning of psUtil.
instead of this:
if(x == m || y == n)
.
.
.
if(x1 < 0 || y1 < 0) continue;
it should be this:
if(x == m-1 || y == n-1)
.
.
.
if(x1 < 0 || y1 < 0 || x1 >= m || y1 >= n) continue;
Your method is pretty good, but maybe we can improve on the implementation a bit. Here is an accepted solution with a similar DFS method.
class Solution {
public:
int direction_row[4] = {0, 1, -1, 0};
int direction_col[4] = {1, 0, 0, -1};
void depth_first_search(vector<vector<int>> &grid, vector<vector<bool>> &visited, int row, int col, int height) {
if (row < 0 || row > grid.size() - 1 || col < 0 || col > grid[0].size() - 1 || visited[row][col])
return;
if (grid[row][col] < height)
return;
visited[row][col] = true;
for (int iter = 0; iter < 4; iter++)
depth_first_search(grid, visited, row + direction_row[iter], col + direction_col[iter], grid[row][col]);
}
vector<vector<int>> pacificAtlantic(vector<vector<int>> &grid) {
vector<vector<int>> water_flows;
int row_length = grid.size();
if (!row_length)
return water_flows;
int col_length = grid[0].size();
vector<vector<bool>> pacific(row_length, vector<bool>(col_length, false));
vector<vector<bool>> atlantic(row_length, vector<bool>(col_length, false));
for (int row = 0; row < row_length; row++) {
depth_first_search(grid, pacific, row, 0, INT_MIN);
depth_first_search(grid, atlantic, row, col_length - 1, INT_MIN);
}
for (int col = 0; col < col_length; col++) {
depth_first_search(grid, pacific, 0, col, INT_MIN);
depth_first_search(grid, atlantic, row_length - 1, col, INT_MIN);
}
for (int row = 0; row < row_length; row++)
for (int col = 0; col < col_length; col++)
if (pacific[row][col] && atlantic[row][col]) {
water_flows.push_back({row, col});
}
return water_flows;
}
};
I'm not also sure, if this would be the most efficient algorithm for the Pacific Atlantic Water Flow problem. You can check out the discussion board.
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions, explanations, efficient algorithms with a variety of languages, and time/space complexity analysis in there.
417. Pacific Atlantic Water Flow
417. Pacific Atlantic Water Flow - Discussion

maximize a function with recursion c++

I am trying to maximize this function in c++:
I have put this in the function:
int F(int n , int T ){
if( T >= 0 && n == 0){
return 0;
}else if( T < 0){
return INT_MIN;
} else if(T >= 0 && n > 0){
for(int i = 0 ; i <= m[n-1] ; i++){
ganancia = max(i * v[n-1] + F(n-1,T-i*t[n-1]),ganancia );
}
}
}
but when I put on n 3 , T 8, t {1, 2, 2}, v {12, 15, 30} and finally on m{3, 3, 2} my program return 2, when it had to return 99.
You have three branches in the function, but only two return values. If you fail to return a value you will have undefined behavior. You need to return a value from all branches.
Now I have my code like this:
int F(int n , int T ){
if( T >= 0 && n == 0){
return 0;
}else if( T < 0){
return INT_MIN;
} else if(T >= 0 && n > 0){
for(int i = 0 ; i <= m[n-1]-1 ; i++){
return (max(i * v[n-1] + F(n-1,T-i*t[n-1]),(i+1) * v[n-1] + F(n-1,T- (i+1)*t[n-1]) ));
}
}
}
And now it is showing my program 12 instead of 13, at least I have left that 2 value. Thanks!

How are vectors different from arrays when used in recursive calls?

I have 2 very similar programs based on this challenge here. One uses arrays, one uses vectors. But their outputs are different. Even though algorithm is the same. Please explain?
Here is the code.
Array version (output is 2, which is incorrect):
#include <iostream>
#define SIZE 4
int step(int grid[][SIZE], int i, int j)
{
if (i < 0 || j < 0 || i > 3 || j > 3)
return 0;
if (grid[i][j] == 1)
return 0;
if ( i == 3 && j == 3)
return 1;
grid[i][j] = 1;
return step(grid, i - 1, j) + step(grid, i + 1, j) + step(grid, i, j - 1) + step(grid, i, j + 1);
}
int main()
{
int grid[][SIZE] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
std::cout<<step(grid, 0, 0)<<std::endl;
return 0;
}
And the vector version (output 184, correct):
#include <iostream>
#include <vector>
#define SIZE 4
int step(std::vector<std::vector<int> > grid, int i, int j)
{
if (i < 0 || j < 0 || i > 3 || j > 3)
return 0;
if (grid[i][j] == 1)
return 0;
if ( i == 3 && j == 3)
return 1;
grid[i][j] = 1;
return step(grid, i - 1, j) + step(grid, i + 1, j) + step(grid, i, j - 1) + step(grid, i, j + 1);
}
int main()
{
std::vector<std::vector<int> > grid;
std::vector<int> column1(4,0);
for (int i = 0; i < SIZE; ++i)
grid.push_back(column1);
std::cout<<step(grid, 0, 0)<<std::endl;
return 0;
}
The first version passes array by reference because it is equivalent to passing pointer to array. The second version passes vector by value which means that each recursive call vector is created on stack and you change only local copy. This change disappears immediately when you return from function.
You should use the following signature to pass vector by reference:
int step(std::vector<std::vector<int> >& grid, int i, int j)

find sum of diagonal elements from given index in 2d array

I have to construct a 2d array with N,M rows and columns (N & M <= 5), then the user enters a certain index(location) like 2,3 (matrix[2][3]) it's assumed that the two numbers are in the bounds of the matrix. From then on I have to find the sum of the left and right diagonal that goes through the number, however the number is excluded from the sum.
So for example the 2d array is myArray[3][3]
*1* 15 *2*
2 *71* 8
*5* 22 *5*
So the user enters 1,1 that is myArray[1][1], in this case the number 71, the sum would be 1 + 5 + 2 + 5 ... And well my problem is how can i find those diagonals without going out of the bounds.
For the left top i would go:
row--
column--
while(row >= 0|| column >= 0)
For left bottom:
row++
colum++
while(row < N || column < M)
for right top:
row--
column++
while(row >= 0 || column < M)
for right bottom:
row++
column--
while(row < N || column >=0)
(this is bad written pseudo-code, sorry)
It works fine when I enter numbers that aren't in the top or bottom row, but in the cases that they are located there my program stops.
What you have is basically good pseudocode. My first thought was that you should be using &&'s instead of ||'s when determining if the location is out of bounds or not.
You also need some sort of way to exit early in case they give a bad location. Below is some code I wrote out quickly, and seems to work at a quick glance - I loop over every possible starting location including ones that are out of bounds.
#include <iostream>
const int N = 3;
const int M = 4;
int matrix[N][M] = {
{ 0, 1, 2, 3 },
{ 4, 5, 6, 7 },
{ 8, 9, 10, 11 }
};
int directional_sum(int row, int column, int row_inc, int column_inc)
{
int sum = 0;
if (row < 0 || column < 0 || row >= N || column >= M)
return sum;
int temp_row = row + row_inc;
int temp_column = column + column_inc;
while (temp_row >= 0 && temp_column >= 0 && temp_row < N && temp_column < M)
{
sum += matrix[temp_row][temp_column];
temp_row += row_inc;
temp_column += column_inc;
}
return sum;
}
int diagonal_sum(int row, int column)
{
int sum = 0;
sum += directional_sum(row, column, 1, 1);
sum += directional_sum(row, column, 1, -1);
sum += directional_sum(row, column, -1, 1);
sum += directional_sum(row, column, -1, -1);
return sum;
}
int main()
{
for (int i = -1; i <= N; i++)
{
for (int j = -1; j <= M; j++)
{
std::cout << "Sum for [" << i << ", " << j << "]: " << diagonal_sum(i, j) << std::endl;
}
}
return 0;
}