C++ Pascal's triangle - c++

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

Related

Coursera DSA Algorithmic toolbox week 4 2nd question- Partitioning Souvenirs

Problem Statement-
You and two of your friends have just returned back home after visiting various countries. Now you would
like to evenly split all the souvenirs that all three of you bought.
Problem Description
Input Format- The first line contains an integer ... The second line contains integers v1, v2, . . . ,vn separated by spaces.
Constraints- 1 . .. . 20, 1 . .... . 30 for all ...
Output Format- Output 1, if it possible to partition š¯‘£1, š¯‘£2, . . . , š¯‘£š¯‘› into three subsets with equal sums, and
0 otherwise.
What's Wrong with this solution? I am getting wrong answer when I submit(#12/75) I am solving it using Knapsack without repetition taking SUm/3 as my Weight. I back track my solution to replace them with 0. Test cases run correctly on my PC.
Although I did it using OR logic, taking a boolean array but IDK whats wrong with this one??
Example- 11
17 59 34 57 17 23 67 1 18 2 59
(67 34 17)are replaced with 0s. So that they dont interfare in the next sum of elements (18 1 23 17 59). Coz both of them equal to 118(sum/3) Print 1.
#include <iostream>
#include <vector>
using namespace std;
int partition3(vector<int> &w, int W)
{
int N = w.size();
//using DP to find out the sum/3 that acts as the Weight for a Knapsack problem
vector<vector<int>> arr(N + 1, vector<int>(W + 1));
for (int k = 0; k <= 1; k++)
{
//This loop runs twice coz if 2x I get sum/3 then that ensures that left elements will make up sum/3 too
for (int i = 0; i < N + 1; i++)
{
for (int j = 0; j < W + 1; j++)
{
if (i == 0 || j == 0)
arr[i][j] = 0;
else if (w[i - 1] <= j)
{
arr[i][j] = ((arr[i - 1][j] > (arr[i - 1][j - w[i - 1]] + w[i - 1])) ? arr[i - 1][j] : (arr[i - 1][j - w[i - 1]] + w[i - 1]));
}
else
{
arr[i][j] = arr[i - 1][j];
}
}
}
if (arr[N][W] != W)
return 0;
else
{
//backtrack the elements that make the sum/3 and = them to 0 so that they don't contribute to the next //elements that make sum/3
int res = arr[N][W];
int wt = W;
for (int i = N; i > 0 && res > 0; i--)
{
if (res == arr[i - 1][wt])
continue;
else
{
std::cout << w[i - 1] << " ";
res = res - w[i - 1];
wt = wt - w[i - 1];
w[i - 1] = 0;
}
}
}
}
if (arr[N][W] == W)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int n;
std::cin >> n;
vector<int> A(n);
int sum = 0;
for (size_t i = 0; i < A.size(); ++i)
{
int k;
std::cin >> k;
A[i] = k;
sum += k;
}
if (sum % 3 == 0)
std::cout << partition3(A, sum / 3) << '\n';
else
std::cout << 0;
}
Sum/3 can be achieved by multiple ways!!!! So backtracking might remove a subset that has an element that should have been a part of some other subset
8 1 6 is 15 as well as 8 2 5 makes 15 so better is u check this
if(partition3(A, sum / 3) == sum / 3 && partition3(A, 2 * (sum / 3)) == 2 * sum / 3 && sum == partition3(A, sum))

Create A Number Pattern

I am trying to get this number pattern
Input: 7
Output:
1 1 1 1 1 1 1
1 2 2 2 2 2 1
1 2 3 3 3 2 1
1 2 3 4 3 2 1
1 2 3 3 3 2 1
1 2 2 2 2 2 1
1 1 1 1 1 1 1
But I can't figure out how to make it like that, any suggestion how to make that pattern??
My code so far :
int n, temp1, temp2,i,j;
cin >> n;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
temp1 = j;
temp2 = n-j+1;
if (temp1 < temp2) cout << temp1;
else cout << temp2;
}
cout << endl;
}
The output so far is
1 2 3 4 3 2 1
1 2 3 4 3 2 1
1 2 3 4 3 2 1
1 2 3 4 3 2 1
1 2 3 4 3 2 1
1 2 3 4 3 2 1
1 2 3 4 3 2 1
Thanks in advance.
I hope this code(working) might give you a better idea about the implementation.
int main() {
int n;
cin >> n;
int arr[n][n];
//Numbers in the grid vary from 1 - (n/2 + 1)
for(int i = 0; i <= n / 2; i++) {
//Start filling the array in squares
//Like fill the outer square with 1 first followed by 2...
for(int j = i; j < n - i; j++) {
arr[i][j] = i + 1;
arr[n - 1 - i][j] = i + 1;
arr[j][i] = i + 1;
arr[j][n - 1 - i] = i + 1;
}
}
The main thing that solves the problem is to divide this square into 4 quadrants:
---n-->
111|222 |
111|222 |
111|222 |
------- n
333|444 |
333|444 |
333|444 v
Each quadrant can be presented with limits:
1 - row <= (n + 1) / 2 && column <= (n + 1) / 2
2 - row <= (n + 1) / 2 && column > (n + 1) / 2
3 - row > (n + 1) / 2 && column <= (n + 1) / 2
4 - row > (n + 1) / 2 && column > (n + 1) / 2
Then every quadrant has to be divided into two slices
\ | /
\ | /
\|/
-------
/|\
/ | \
/ | \
These diagonals can be described using equations:
column_index = row_index
column_index = (n + 1) - row_index
Right now you just have to check if current 'cell' is under or above one of the diagonals, and use row or column index accordingly. Of course if row or column index is larger than (n + 1) / 2 then you have to adjust by subtracting it from n.
If you understand this, writing your own code shouldn't be a problem. It is good idea if you have to print everything immediately without storing it in some kind of array. If you can use array then #baymaxx solution is a lot cleaner.
It is my code if you would like to compare your implementation:
#include <iostream>
int main() {
int n;
std::cin >> n;
for (int row_index = 1; row_index <= n; row_index++) {
for (int column_index = 1; column_index <= n; column_index++) {
if (row_index <= (n + 1) / 2 && column_index <= (n + 1) / 2) {
if (column_index < row_index) {
std::cout << column_index << " ";
} else {
std::cout << row_index << " ";
}
} else if (row_index <= (n + 1) / 2 && column_index > (n + 1) / 2) {
if (column_index < (n + 1) - row_index) {
std::cout << row_index << " ";
} else {
std::cout << (n + 1) - column_index << " ";
}
} else if (row_index > (n + 1) / 2 && column_index <= (n + 1) / 2) {
if (column_index < (n + 1) - row_index) {
std::cout << column_index << " ";
} else {
std::cout << (n + 1) - row_index << " ";
}
} else {
if (column_index > row_index) {
std::cout << (n + 1) - column_index << " ";
} else {
std::cout << (n + 1) - row_index << " ";
}
}
}
std::cout << "\n";
}
}

Finding regional maximum elements by iterative method

Assumed that I'd find regional maximum elements in the following matrix. The regional maximum are 8-connected elements with the same value t, whose external boundary all have a value less than t. In this case, the results expected are one element that equals 8 and five elements that equal 9.
1 1 1 1 1 1 1 1 1 1
1 2 2 2 2 2 2 1 1 1
1 1 2 8 2 2 2 9 1 1
1 1 1 1 2 2 9 9 9 1
1 2 2 2 2 2 2 9 1 1
1 1 1 1 1 1 1 1 1 1
For the first situation, it is very easy to pick 8 from its 8-connected neighbors because 8 is the greatest among them. The pseudo code:
for (i = 0; i < 10; i++) {
for (j = 0; j < 6; j++) {
if element(i, j) > AllOfNeighbors(i, j)
RecordMaxElementIndex(i, j);
}
}
But for the second situation, I get confused. This time 9 is greater than some of its neighbors and equals to the other neighbors. The pseudo code would be:
for (i = 0; i < 10; i++) {
for (j = 0; j < 6; j++) {
// Start iteration
if element(i, j) > AllOfNeighbors(i, j)
RecordMaxElementIndex(i, j);
else if element(i, j) > SomeOfNeighbors(i, j) &&
element(i, j) == TheOtherNeighbors(i, j)
RecordTheOtherNeighborsIndex(i, j);
// Jump to the start now
}
}
For example, when (i, j) is (7, 2), elements at (6, 3), (7, 3) and (8, 3) will be recorded for the next iterative round. I'm not sure whether using iterative method is proper here but I think TheOtherNeighbors(ii, jj) could be treated as element(i, j) and repeat the same process to find the regional maximum. Moreover, (6, 3) cannot be compared to (7, 2), (7, 3) and (8, 3)again in case endless loop. So how to implement the iterative method? Any guide would be helpful.
As I understand, you may create the connected components using Disjoint-set_data_structure and mark component that are not maximal...
Pseudo code:
DisjointSet disjointSet[10][6]
// Init disjointSet
for (i = 0; i < 10; i++) {
for (j = 0; j < 6; j++) {
disjointSet[i][j].MakeSet({i, j});
disjointSet[i][j].MarkAsMaximal(); // extra flag for your case
}
}
// Create Connected component and mark as not maximal
for (i = 0; i < 10; i++) {
for (j = 0; j < 6; j++) {
for (auto neighborDisjointSet : NeighborsWithSameValue(i, j)) {
Union(disjointSet[i][j], neighborDisjointSet);
}
if (element(i, j) < AnyOfNeighbors(i, j)) {
disjointSet[i][j].MarkAsNotMaximal();
}
for (auto neighborDisjointSet : NeighborsWithSmallValue(i, j) {
neighborDisjointSet.MarkAsNotMaximal();
}
}
}
// Collect result.
std::set<DisjointSet> maximumRegions;
for (i = 0; i < 10; i++) {
for (j = 0; j < 6; j++) {
if (disjointSet[i][j].IsMarkAsMaximal) {
maximumRegions.insert(disjointSet[i][j]);
}
}
}

C++ summing multiples of 3 and 5

I just started C++ programming for three days now and I cannot figure out how to complete this exercise. Basically, I want to sum all multiples of 3 and 5 under 1000. Here is my code:
int sum3n5(int max){
int sum = 0;
for(int i = 1; i <= max; ++i){
if( i%3 == 0 && i%5 == 0 ) { sum += i;}
else if( i%3 == 0 || i%5 == 0 ) { sum +=i;}
return sum;
};
};
Sorry if it is a trivial mistake that I failed to realize.
I always get the result 0 after running this.
int sum3n5(int max){
int sum = 0;
for (int i = 1; i <= max; ++i){
if( i % 3 == 0 || i % 5 == 0 ){
sum += i;
}
}
return sum;
}
You only need the || (logical or) operator, not the && (and certainly not both!). And the return needs to be after the for loop so that the loop can complete before the function returns.
A version without loop:
int sum3n5(int max)
{
return 3 * (max / 3) * (max / 3 + 1) / 2
+ 5 * (max / 5) * (max / 5 + 1) / 2
- 15 * (max / 15) * (max / 15 + 1) / 2;
}
It uses the fact that 1 + 2 + .. + n == n * (n + 1) / 2

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.