C++ count if function - c++

The following returns the number 7. My problem is that im not exactly sure why 7 is the number returned. I tried running in in debug mode to break it down but
unfortunately that did not help.
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
bool even_first( int x, int y ){
if( (x % 2 == 0) && (y % 2 != 0) ) return true;
if( (x % 2 != 0) && (y % 2 == 0) ) return false;
return x < y;
}
struct BeforeValue {
int bound;
BeforeValue( int b ) : bound( b ) { }
bool operator()( int value ) { return even_first( value, bound ); }
};
int main(){
list<int> my_list = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int count = count_if( my_list.begin( ), my_list.end( ), BeforeValue( 5) );
cout << count << "\n";
}

To function even_first you pass 2 parameters: first parameter x is equal to successive values from my_list and the second parameter y is always 5.
And in the even_first function we have 3 conditions:
if( (x % 2 == 0) && (y % 2 != 0) ) return true;
y is equal to 5 so y % 2 != 0 is always true
x % 2 == 0 is true for: 0, 2, 4, 6, 8
if( (x % 2 != 0) && (y % 2 == 0) ) return false;
It is always false because y = 5 so y % 2 == 0 is false. We go to point 3
return x < y;
To this statement we go only with values: 1, 3, 5, 7, 9
and it is true for: 1 and 3
So finally the even_first returns true for: 0, 1, 2, 3, 4, 6, 8. And the size of this set is 7

Related

Linear index for a diagonal run of an upper triangular matrix

Given a NxN matrix, I would like to linearly index into its upper right triangle,
following a diagonal by diagonal pattern, starting after the main diagonal.
For example, given a 4x4 matrix
X 0 3 5
X X 1 4
X X X 2
X X X X
I'm looking for a non recursive (closed form) function mapping linear indices from 0 to 5 to (x,y) achieving
f(0) = (0, 1)
f(1) = (1, 2)
f(2) = (2, 3)
f(3) = (0, 2)
f(4) = (1, 3)
f(5) = (0, 3)
Related for row by row runs:
Linear index upper triangular matrix
algorithm for index numbers of triangular matrix coefficients
Thanks to #loopy-walt's observation, we have an answer!
Using the result from Linear index upper triangular matrix, a transformation of the result
(i, j) |-> (j-i-1, j)
Gives the expected outcome.
Here is a C++ implementation.
#include<tuple>
#include<cmath>
// Linear indexing of the upper triangle, row by row
std::tuple<size_t, size_t> k2ij(size_t n, size_t k){
size_t i = n - 2 - (size_t)std::floor(std::sqrt(4*n*(n-1) - (8*k) -7)/2.0 - 0.5);
size_t j = k + i + 1 - n*(n-1)/2 + (n-i)*((n-i)-1)/2;
return {i,j};
}
// Linear indexing of the upper triangle, diagonal by diagonal
std::tuple<size_t, size_t> d2ij(size_t n, size_t d){
const auto [i, j] = k2ij(n, d);
return {j-i-1, j}; // Conversion from row by row to diag by diag
}
#include<iostream>
#include<set>
int main(int argc, char** argv) {
size_t n = 4;
size_t top = n*(n-1)/2;
for(size_t d=0; d<top; ++d){
const auto [i,j] = d2ij(n, d);
std::cout << "d2ij(" << n << ", " << d << ") = (" << i << ", " << j << ")" << std::endl;
}
return 0;
}
Producing
d2ij(4, 0) = (0, 1)
d2ij(4, 1) = (1, 2)
d2ij(4, 2) = (2, 3)
d2ij(4, 3) = (0, 2)
d2ij(4, 4) = (1, 3)
d2ij(4, 5) = (0, 3)
Note: if someone wishes the form f(d) instead, a lambda can be used to capture the dimension 'n'
auto f = [n](size_t d){return d2ij(n, d);};
const auto [i,j] = f(5);
Thanks to everybody that took the time to read and help!
I created a custom method for the array and value you gave.
int a[4][4] ={{-1, 0, 3, 5}, {-1, -1, 1, 4}, {-1, -1, -1, 2}, {-1, -1, -1, -1}};
The code is exactly like this. You give the array And whatever you give to the second value in the Func method, the indexes of the value in the upper diagonal will reach you.
#include <iostream>
using namespace std;
int b[2] ={-1,-1};
int Func(int a[4][4],int n)
{
for(int i =0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(a[i][j]==n)
{
if(i<j)
{
b[0]=i;
b[1]=j;
return 0;
}
}
}
}
}
int main()
{
int a[4][4] ={{-1, 0, 3, 5}, {-1, -1, 1, 4}, {-1, -1, -1, 2}, {-1, -1, -1, -1}};
Func(a,5);
for(int i=0;i<2;i++)
{
cout<<b[i]<<" ";
}
return 0;
}
thank you USEFUL for feedback if it worked for you
Maybe someone can come up with a math formula that doesn't require a loop, but until then I've come up with a O(N) solution:
#include <utility>
constexpr std::pair<int, int> f(int n, int idx)
{
int group_size = n - 1;
int rest = idx + 1;
while (rest > group_size)
{
rest = rest - group_size;
--group_size;
}
return {(rest - 1) % group_size,
n - group_size + (rest - 1) % group_size};
}
/* 3x3
X 0 2
X X 1
X X X
*/
static_assert(f(3, 0) == std::pair{0, 1});
static_assert(f(3, 1) == std::pair{1, 2});
static_assert(f(3, 2) == std::pair{0, 2});
// 4x4
static_assert(f(4, 0) == std::pair{0, 1});
static_assert(f(4, 1) == std::pair{1, 2});
static_assert(f(4, 2) == std::pair{2, 3});
static_assert(f(4, 3) == std::pair{0, 2});
static_assert(f(4, 4) == std::pair{1, 3});
static_assert(f(4, 5) == std::pair{0, 3});
/* 5x5
X 0 4 7 9
X X 1 5 8
X X X 2 6
X X X X 3
X X X X X
*/
static_assert(f(5, 0) == std::pair{0, 1});
static_assert(f(5, 1) == std::pair{1, 2});
static_assert(f(5, 2) == std::pair{2, 3});
static_assert(f(5, 3) == std::pair{3, 4});
static_assert(f(5, 4) == std::pair{0, 2});
static_assert(f(5, 5) == std::pair{1, 3});
static_assert(f(5, 6) == std::pair{2, 4});
static_assert(f(5, 7) == std::pair{0, 3});
static_assert(f(5, 8) == std::pair{1, 4});
static_assert(f(5, 9) == std::pair{0, 4});
So you want the inverse of the following function
Zero-based indexing form of element [i,j] for a n×n upper triangular matrix including the diagonal
index = i*n-i*(i+1)/2+j
i=0..4, j=0..4, index=
| 0 | 1 | 2 | 3 | 4 |
| X | 5 | 6 | 7 | 8 |
| X | X | 9 | 10 | 11 |
| X | X | X | 12 | 13 |
| X | X | X | X | 14 |
The easiest algorithm I can think of is to loop for all rows i and see if there is a match for the column j such that:
i <= j
j>=0
j<n
Here is a sample code given index and n
for(i=0; i<n; i++)
{
j = index - i*n + i*(i+1)/2
if( j>=0 && j<n && j>= i)
{
break;
}
}
And example with n=7 and [i,j]=[1,5] produces index=11. Now the coordinates of this index are
i
j
i<=j && j>=0 && j<7
0
11
1
5
valid
2
0
3
-4
4
-7
5
-9
6
-10
If you want strictly the upper triangular elements, excluding the diagonal then
Zero-based indexing form of element [i,j] for a n×n upper triangular matrix excluding the diagonal
index = i*n-i*(i+3)/2+j-1
i=0..3, j=0..4, index=
| X | 0 | 1 | 2 | 3 |
| X | X | 4 | 5 | 6 |
| X | X | X | 7 | 8 |
| X | X | X | X | 9 |
| X | X | X | X | X |
The algorithm now is to loop for all rows i and see if there is a match for the column j such that:
i < j
j>0
j<n
Here is a sample code given index and n
for(i=0; i<n; i++)
{
j = index - i*n + i*(i+3)/2 + 1
if( j>0 && j<n && j>i)
{
break;
}
}
And example with n=7 and [i,j]=[1,5] produces index=9. Now the coordinates of this index are
i
j
i<j && j>0 && j<7
0
10
1
5
valid
2
1
3
-2
4
-4
5
-5

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.

How to count connected cells in a grid?

I'm trying to solve the Hackerrank problem "Connected Cells in a Grid". The task is to find the largest region (connected cells consisting of ones) in the grid.
My approach was to add the number of ones I find only if the element hasn't been visited yet, then I take the maximum of several paths. It doesn't seem to be working for the following test case:
5
5
1 1 0 0 0
0 1 1 0 0
0 0 1 0 1
1 0 0 0 1
0 1 0 1 1
Is there something wrong with my approach?
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 10
bool visited[MAX][MAX];
int maxRegion(vector<vector<int>> const& mat, int i, int j) {
int result;
if ((i == 0 && j == 0) || visited[i][j]) {
result = 0;
}
else if (i == 0) {
result = mat[i][j-1] + maxRegion(mat, i, j-1);
}
else if (j == 0) {
result = mat[i-1][j] + maxRegion(mat, i-1, j);
}
else {
result = mat[i-1][j-1] +
max({maxRegion(mat, i-1, j),
maxRegion(mat, i, j-1),
maxRegion(mat, i-1, j-1)});
}
visited[i][j] = true;
return result;
}
I think it's very natural to formulate this program as a connected components problem. Specifically, I've used boost::graph for this.
The idea is to build a graph whose each entry in the matrix is a node, and there are edges between horizontal and vertical 1 entries. Once such a graph is built, all that is needed is to run the connected components algorithm, and find the biggest component.
The following code does so:
#include <iostream>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
using namespace std;
using namespace boost;
int main()
{
vector<vector<int>> v{{1, 1, 0, 0, 0}, {0, 1, 1, 0, 0}, {0, 0, 1, 0, 1}, {1, 0, 0, 0, 1}, {0, 1, 0, 1, 1}};
typedef adjacency_list <vecS, vecS, undirectedS> graph;
graph g(v.size() * v.size());
// Populate the graph edges
for(size_t i = 0; i < v.size() - 1; ++i)
for(size_t j = 0; j < v[i].size() - 1; ++j)
{
if(v[i][j] == 1 && v[i + 1][j] == 1)
add_edge(i * v.size() + j, (i + 1) * v.size() + j, g);
else if(v[i][j] == 1 && v[i][j + 1] == 1)
add_edge(i * v.size() + j, i * v.size() + j + 1, g);
}
// Run the connected-components algorithm.
vector<int> component(num_vertices(g));
int num = connected_components(g, &component[0]);
// Print out the results.
std::vector<int>::size_type i;
for(i = 0; i != component.size(); ++i)
cout << "Vertex (" << i / v.size() << ", " << i % v.size() << ") is in component " << component[i] << endl;
cout << endl;
}
The output is
Vertex (0, 0) is in component 0
Vertex (0, 1) is in component 0
Vertex (0, 2) is in component 1
Vertex (0, 3) is in component 2
Vertex (0, 4) is in component 3
Vertex (1, 0) is in component 4
Vertex (1, 1) is in component 0
Vertex (1, 2) is in component 0
Vertex (1, 3) is in component 5
Vertex (1, 4) is in component 6
Vertex (2, 0) is in component 7
Vertex (2, 1) is in component 8
Vertex (2, 2) is in component 0
Vertex (2, 3) is in component 9
Vertex (2, 4) is in component 10
Vertex (3, 0) is in component 11
Vertex (3, 1) is in component 12
Vertex (3, 2) is in component 13
Vertex (3, 3) is in component 14
Vertex (3, 4) is in component 15
Vertex (4, 0) is in component 16
Vertex (4, 1) is in component 17
Vertex (4, 2) is in component 18
Vertex (4, 3) is in component 19
Vertex (4, 4) is in component 20
Note that the program encodes i, j (for the case where the dimension is 5) by 5 i + j. This is easily invertible.
You can represent the matrix as an undirected graph and use DFS or BFS to find the connected component with the most nodes: every cell containing 1 can become a node, and there is an edge between two nodes if the corresponding cells are adjacent.
If you still need some guidance with the solution, here is mine in Python - passed all tests :) (visit my github to see other challenges that I've solved there in C++ as well)
def getBiggestRegion(grid, n, m):
max_region = 0
region_size = 0
for i in xrange(n):
for j in xrange(m):
if grid[i][j] == 1:
region_size = mark_region(grid, i, j, n, m)
#region_size += 1
if region_size > max_region:
max_region = region_size
return max_region
def push_if_valid(stack, i, j, n, m):
if 0 <= i < n and 0 <= j < m:
stack.append((i, j))
dirs = [[1,0], [0,1], [-1,0], [0,-1], [-1,-1], [-1, 1], [1,1], [1, -1]]
def mark_region(grid, i, j, n, m):
stack = []
stack.append((i, j))
region_size = 0
while stack:
curr = stack.pop()
ci = curr[0]
cj = curr[1]
if grid[ci][cj] == 1:
grid[ci][cj] = 2
region_size += 1
#this for loop is for going in all the directions
#North, South, East, West, NW, SW, SE, NE
#in my C++ Pacman sol, I have the actual lines instead
for dir in dirs:
push_if_valid(stack, ci + dir[0], cj + dir[1], n, m)
return region_size
n = int(raw_input().strip())
m = int(raw_input().strip())
grid = []
for grid_i in xrange(n):
grid_t = list(map(int, raw_input().strip().split(' ')))
grid.append(grid_t)
print(getBiggestRegion(grid, n, m))

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!

Recursively determine minimum moves to all fields on gameboard

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.