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))
Related
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
As a homework, I have a problem which sounds like this:
We have a n*n square matrix. It is called 'subdiagonal'
if all the elements above the main diagonal are null.
a) Copy the useful elements (the ones which are not null, so basically all the elements
from the main diagonal and below) to an array. (I've done that)
b) Write an algorithm which takes two subdiagonal matrix A, B as an input.
Those are transformed into arrays V_a and V_b with the algorithm from a),
then they calculate C = A*B only using only V_a and V_b
e.g.
Let's say A =
1 0 0 0 0
2 3 0 0 0
4 1 3 0 0
1 9 0 2 0
1 0 1 2 2
B =
2 0 0 0 0
1 1 0 0 0
0 1 2 0 0
1 1 2 3 0
2 0 0 1 2
after this input, V_a = 1,2,3,4,1,3,1,9,0,2,1,0,1,2,2; V_b = 2,1,1,0,1,2,1,1,2,3,2,0,0,1,2
and the product V_c will be 2,7,3,9,4,6,13,11,4,6,8,3,6,8,4
so the matrix will look like
2 0 0 0 0
7 3 0 0 0
9 4 6 0 0
13 11 4 6 0
8 3 6 8 4
Here's the code that I've been working on for a while:
#include <iostream>
#include <algorithm>
void read(int& a, int**& matrix)
{
std::cin >> a;
matrix = new int*[a];
for (int i = 0; i < a; i++)
{
for (int j = 0; j < a; j++)
{
matrix[i] = new int[a];
}
}
for (int i = 0; i < a; i++)
{
for (int j = 0; j < a; j++)
{
std::cin >> matrix[i][j];
}
}
}
void showMatrix(int a, int** matrix)
{
for (int i = 0; i < a; i++)
{
for (int j = 0; j < a; j++)
{
std::cout << matrix[i][j] << " ";
}
std::cout << std::endl;
}
}
void showArray(int a, int* array)
{
for (int i = 0; i < a; i++)
{
std::cout << array[i] << " ";
}
}
void createArray(int a, int& arrayLength, int** matrix, int*& array)
{
int nrDeElemente = a*a - (a * (a - 1)) / 2;
array = new int[nrDeElemente+1];
arrayLength = 0;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < i+1; j++)
{
array[arrayLength++] = matrix[i][j];
}
}
}
int* multiplyArrays(int a, int arrayLength, int* array1, int* array2)
{
int* array3 = new int[arrayLength + 1];
for (int i = 0; i < a; i++)
{
array3[i] = 0;
}
int t = 1;
for (int i = 0; i < arrayLength; ++i)
{
for (int j = 0; j < t; ++j)
{
for (int p = j; p < a; p++)
{
array3[i] += array1[j] * array2[p];
}
}
++t;
}
return array3;
}
int main()
{
int **matrix1, **matrix2;
int *array1, *array2, *multiplyResult;
int a, arrayLength;
read(a, matrix1);
read(a, matrix2);
createArray(a, arrayLength, matrix1, array1);
createArray(a, arrayLength, matrix2, array2);
multiplyResult = multiplyArrays(a, arrayLength, array1, array2);
showArray(arrayLength, multiplyResult);
}
I've done a), but I don't know how to do b)
I think I understood it (after many hours of trials) conceptually, but I don't really know how to implement it.
I need 3 for loops, as such:
->the most outer one has to be responsible for the position we calculate on the new array
->the next one has to choose which elements from the second array will be multiplied. (choose the multiplier) That's one of
the loops I don't know how to implement. It somehow has to stop when the line (from the matrix) ended and start where it stopped + 1 element.
->the most inner one has to choose the second term of the multiplication (the multiplicand).
I also don't know how I should implement this one. It should choose as many elements as there multipliers are and also, the looping is quite strange (because I need to select all the elements from the same row every time).
Can anybody help me solve point b and also explain their thinking?
I struggled a lot and I really feel like I need help.
BTW the 3 for loops from multiplyArrays make no sense, you can just write something else instead of them. Those 3 for loops are basically the only things that my program needs (I think).
Thanks :)
Matrix multiplication C = A*B is defined by C(i,j) = sum_k A(i,k)*B(k,j). The matrix A has structural nonzeros where i >= k, and B, where k >= j. Thus it suffices to iterate
(outer loop) i from 0 to n-1
(middle) j from 0 to i
(inner) k from j to i.
The other piece is turning coordinates (i,j) into an offset with respect to the 1D storage format. The number of structural nonzeros in the first i rows is given by the ith triangular number, (i+1)*i/2. Hence the jth element in this row is at (zero-based) index (i+1)*i/2 + j. You or your compiler can strength-reduce the multiplication.
To multiply matrices requires to find where a row start in array, for example row[2] starts at index 3 in array as highlighted below,
1 0 0 0 0
2 3 0 0 0
4 1 3 0 0 => row[2]
1 9 0 2 0
1 0 1 2 2
[1, 2, 3, 4, 1, 3, 1, 9, 0, 2, 1, 0, 1, 2, 2]
Any row can be found if we know how may elements are present before it, like in above example if we know that three elements are present before row[2] then we can locate row[2] easily.
To find number of elements presents before each row requires to calculated an auxiliary array of size equals to number of rows, but to do that let's first see matrix again,
As you can see each row contains element equal to the index + 1 of row,
1 element count = index + 1 = 0 + 1 = 1
2 3 = 1 + 1 = 2
4 1 3 = 2 + 1 = 3
1 9 0 2 ..
1 0 1 2 2 ..
It means our auxiliary array would be,
auxiliary array = [0, 1, 2, 3, 4] but how ?
As we know there are no element before row[0] that's why auxiliaryArray[0] = 0 then elements before row[1] is only one element which can be found by index of previous row that is previous row index + 1 => 0 + 1 as showed above auxiliaryArray[1] = 1 and similar for all rows,
But it is not done! current state of auxiliary array is only having information about number of elements present in immediate previous row but not in all previous rows, and to do so we have to calculate sum of all previous rows and that is called partial sum and it will be done as follows,
row[0] = row[0]
row[1] = row[0] + row[1]
row[2] = row[1] + row[2]
..
..
and final result,
auxiliary array = [0, 1, 3, 6, 10]
So as you can see number of elements before row[2] = auxiliaryArray[2] = 3
By using above auxiliary array you can locate any row and if you get first element of row you can find all col elements.
Next point to understand is how many elements you have to multiply in each row and that is again number of elements to multiply = index + 1 as you see above in matrix row[0] only have one element to multiple index + 1 => 0 + 1 and same rule apply for each row.
Last point to consider is, when row is multiplied with col of other matrix it doesn't start always with row[0] of other matrix as you can see below otherMatrix[0][1] is outside of left diagonal of other matrix,
2 0 0 0 0
1 1 0 0 0
0 1 2 0 0
1 1 2 3 0
2 0 0 1 2
Finally we are done!
#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
using std::cout;
void printMatrixArray(std::size_t rowSize, const std::vector<int>& matArray){
std::size_t elementCount = 1;
std::vector<int>::const_iterator it = matArray.cbegin();
for(std::size_t row = 0; row < rowSize; ++row){
std::copy(it, it + elementCount, std::ostream_iterator<int>(cout, "\t"));
cout<< '\n';
it += elementCount;
++elementCount;
}
}
std::vector<int> leftDiagonalBottomMatrix(const std::vector<std::vector<int>>& mat){
std::vector<int> res;
res.reserve(((1 + mat.size()) * mat.size()) / 2);
std::vector<int>::size_type elementCount = 1;
for(const std::vector<int>& row : mat){
for(std::vector<int>::const_iterator it = row.cbegin(), endIt = row.cbegin() + elementCount; endIt != it; ++it){
res.push_back(*it);
}
++elementCount;
}
return res;
}
std::vector<int> multiplyMatrixArrays(const std::vector<int>& mat1Arr, const std::vector<int>& mat2Arr,
std::vector<int>::size_type rowSize){
std::vector<int> auxiliaryArray(rowSize);
auxiliaryArray.front() = 0;
std::iota(auxiliaryArray.begin() + 1, auxiliaryArray.end(), 1);
std::partial_sum(auxiliaryArray.cbegin(), auxiliaryArray.cend(), auxiliaryArray.begin());
std::vector<int> res;
res.reserve(mat1Arr.size());
for(std::vector<int>::size_type row = 0; row < rowSize; ++row){
for(std::vector<int>::size_type col = 0; col <= row; ++col){
int val = 0;
for(std::vector<int>::size_type ele = col, elementCount = row + 1; ele < elementCount; ++ele){
val += mat1Arr[auxiliaryArray[row] + ele] * mat2Arr[auxiliaryArray[ele] + col];
}
res.push_back(val);
}
}
return res;
}
std::vector<int> matrixMultiply(const std::vector<std::vector<int>>& mat1, const std::vector<std::vector<int>>& mat2){
return multiplyMatrixArrays(leftDiagonalBottomMatrix(mat1), leftDiagonalBottomMatrix(mat2), mat1.size());
}
int main(){
std::vector<std::vector<int>> mat1{{1, 0, 0, 0, 0}, {2, 3, 0, 0, 0}, {4, 1, 3, 0, 0}, {1, 9, 0, 2, 0},
{1, 0, 1, 2, 2}};
std::vector<std::vector<int>> mat2{{2, 0, 0, 0, 0}, {1, 1, 0, 0, 0}, {0, 1, 2, 0, 0}, {1, 1, 2, 3, 0},
{2, 0, 0, 1, 2}};
printMatrixArray(mat1.size(), matrixMultiply(mat1, mat2));
}
Output:
2
7 3
9 4 6
13 11 4 6
8 3 6 8 4
Output does not print elements above the left diagonal of matrix!
In this code I am looping over all indices in a 3D domain, and printing the "diagonal" part as
for (i, j, k) in {0..9, 0..9, 0..9}
{
if i == j == k // (1)
//if (i == j) && (j == k) // (2) -> gives expected result
{
writeln((i, j, k));
}
}
My expected result is something like
(0, 0, 0)
(1, 1, 1)
(2, 2, 2)
(3, 3, 3)
(4, 4, 4)
(5, 5, 5)
(6, 6, 6)
(7, 7, 7)
(8, 8, 8)
(9, 9, 9)
which is obtained with Line (2) above. But if I use Line (1), it gives an unexpected result like
(0, 0, 1)
(0, 1, 0)
(0, 2, 0)
...
(9, 7, 0)
(9, 8, 0)
(9, 9, 1)
So I am wondering if I am erroneously using i == j == k?
(FYI, the above code is motivated by some Python code like
for i in range(10):
for j in range(10):
for k in range(10):
if i == j == k:
print( i, j, k )
which gives (0, 0, 0), (1, 1, 1), ...)
Right on, #Someprogrammerdude.
== is a binary operator, it is left-associative. The documentation is here:
https://chapel-lang.org/docs/language/spec/expressions.html#precedence-and-associativity
When comparing the boolean (i==j) with the integer k (in the context of i==j==k), the boolean is implicitly converted to an integer and an integer equality check is performed.
FWIW, these are results that I got from other languages (but my usage of each language may be wrong, so please take it as such...).
C++
#include <iostream>
using namespace std;
int main() {
int i = 2, j = 2, k = 2;
cout << (i == j == k) << endl;
}
// => 0 (false), probably by interpreting it as (i == j) == k
Chapel
var i, j, k = 2;
writeln( i == j == k );
// => false (same as C++)
D
import std.stdio;
void main() {
int i = 2, j = 2, k = 2;
writeln( i == j == k );
}
// => Error: found == when expecting ) (and some related messages)
Rust
fn main() {
let i = 2;
let j = 2;
let k = 2;
println!( "{:?}", i == j == k );
}
// => Error
error: chained comparison operators require parentheses
--> test.rs:6:25
|
6 | println!( "{:?}", i == j == k );
| ^^^^^^^^^
error[E0308]: mismatched types
--> test.rs:6:33
|
6 | println!( "{:?}", i == j == k );
| ^ expected bool, found integer
|
Scala (here ">" is REPL)
> var i = 2
> var j = 2
> var k = 2
> i == j == k
^
warning: comparing values of types Boolean and Int
using `==` will always yield false
res0: Boolean = false
Kotlin
> var i = 2
> var j = 2
> var k = 2
> i == j == k
error: operator '==' cannot be applied to 'Boolean' and 'Int'
i == j == k
Nim
var i = 2
var j = 2
var k = 2
echo( i == j == k )
=> Error: type mismatch: got <bool, int>
but expected one of:
proc `==`(x, y: bool): bool
first type mismatch at position: 2
required type for y: bool
but expression 'k' is of type: int
expression: i == j == k
Python
> i = 2
> j = 2
> k = 2
> i == j == k
True
Julia
> i = 2
> j = 2
> k = 2
> i == j == k
true
So, apart from Python and Julia (which are dynamically typed so might be a bit different thing), it seems that more lately developed statically typed languages tend to give a warning (or even an error) against the use of i == j == k. So, if Python users may be likely to use Chapel, I guess it might be helpful (for the user) to give some warning (or even an error?) message.
Given a non-negative array, find the number of subsequences having a product smaller than K.
Examples:
Input : [1, 2, 3, 4]
k = 10
Output :11
Input : [4, 8, 7, 2]
k = 50
Output : 9
So, We want to count the number of subsequences whose product is less than K.
There are sub-problems, and it can be solved using Dynamic Programming
However, I tried to write down the recursive code for better understanding.
Note: I am getting an answer as 6, which is wrong.
Can someone help me, How to foresee the correct Logic?
#include <bits/stdc++.h>
using namespace std;
vector<int> A{1, 2, 3, 4};
int countSubsequence(int i, int prod, int K)
{
if(prod > 1 && prod <= K)
return 1;
if(i >= A.size() || prod > K)
return 0;
return countSubsequence(i + 1, prod, K) + countSubsequence(i + 1, prod*A[i], K);
}
int main()
{
int K = 10;
cout << countSubsequence(0, 1, K);
return 0;
}
The condition
if(prod > 1 && prod <= K)
return 1;
will have it return from the function (for example) when [1, 2] is selected from [1, 2, 3, 4] and prevent it from searching for [1, 2, 3].
Also:
The condition prod <= K is wrong becasue you want the product smaller than K, not K or smaller.
You cannot distinguish "nothing is multiplied" and "only the number 1 is multiplied" when you use 1 as the initial value.
Try this:
#include <bits/stdc++.h>
using namespace std;
vector<int> A{1, 2, 3, 4};
int countSubsequence(int i, int prod, int K)
{
if(i >= A.size() && 0 <= prod && prod < K)
return 1;
if(i >= A.size() || prod >= K)
return 0;
return countSubsequence(i + 1, prod, K) + countSubsequence(i + 1, prod < 0 ? A[i] : prod*A[i], K);
}
int main()
{
int K = 10;
cout << countSubsequence(0, -1, K);
return 0;
}
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