Skip to content

Commit 83fb13f

Browse files
Merge pull request #58 from LONECODER1/feature/pascalTriangle
pascal triangle added
2 parents 06c5914 + 793dc22 commit 83fb13f

File tree

4 files changed

+455
-2
lines changed

4 files changed

+455
-2
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// src/algorithms/dynamic-programming/pascalTriangleAlgo.js
2+
3+
// Top-Down (Recursive with Memoization)
4+
export function pascalTriangleTopDown(n) {
5+
const memo = Array.from({ length: n + 1 }, () => new Array(n + 1).fill(null));
6+
const steps = [];
7+
8+
function solve(row, col) {
9+
steps.push({
10+
type: "call",
11+
row,
12+
col,
13+
memo: memo.map(r => [...r]),
14+
message: `Calling pascal(${row}, ${col}).`
15+
});
16+
17+
// Base case: edges of the triangle are always 1
18+
if (col === 0 || col === row) {
19+
memo[row][col] = 1;
20+
steps.push({
21+
type: "base_case",
22+
row,
23+
col,
24+
value: 1,
25+
memo: memo.map(r => [...r]),
26+
message: `Base case: pascal(${row}, ${col}) = 1.`
27+
});
28+
return 1;
29+
}
30+
31+
// Memoization hit
32+
if (memo[row][col] !== null) {
33+
steps.push({
34+
type: "memo_hit",
35+
row,
36+
col,
37+
value: memo[row][col],
38+
memo: memo.map(r => [...r]),
39+
message: `Memoization hit: pascal(${row}, ${col}) = ${memo[row][col]}.`
40+
});
41+
return memo[row][col];
42+
}
43+
44+
// Recursive relation: pascal(r, c) = pascal(r-1, c-1) + pascal(r-1, c)
45+
const val = solve(row - 1, col - 1) + solve(row - 1, col);
46+
memo[row][col] = val;
47+
48+
steps.push({
49+
type: "store",
50+
row,
51+
col,
52+
value: val,
53+
memo: memo.map(r => [...r]),
54+
message: `Computed pascal(${row}, ${col}) = pascal(${row - 1}, ${col - 1}) + pascal(${row - 1}, ${col}) = ${val}. Stored in memo.`
55+
});
56+
57+
return val;
58+
}
59+
60+
// Build the entire triangle
61+
for (let i = 0; i <= n; i++) {
62+
for (let j = 0; j <= i; j++) {
63+
solve(i, j);
64+
}
65+
}
66+
67+
const triangle = memo.map(row => row.filter(x => x !== null));
68+
69+
const visualSteps = steps.map(step => ({
70+
array: step.memo,
71+
currentPosition: { row: step.row, col: step.col },
72+
message: step.message,
73+
value: step.value
74+
}));
75+
76+
return { steps: visualSteps, result: triangle };
77+
}
78+
79+
80+
// Bottom-Up (Iterative DP)
81+
export function pascalTriangleBottomUp(n) {
82+
const dp = Array.from({ length: n + 1 }, () => new Array(n + 1).fill(0));
83+
const steps = [];
84+
85+
for (let i = 0; i <= n; i++) {
86+
for (let j = 0; j <= i; j++) {
87+
if (j === 0 || j === i) {
88+
dp[i][j] = 1;
89+
steps.push({
90+
type: "base_case",
91+
row: i,
92+
col: j,
93+
value: 1,
94+
dp: dp.map(r => [...r]),
95+
message: `Base case: dp[${i}][${j}] = 1 (edges of triangle).`
96+
});
97+
} else {
98+
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
99+
steps.push({
100+
type: "compute",
101+
row: i,
102+
col: j,
103+
value: dp[i][j],
104+
dp: dp.map(r => [...r]),
105+
message: `Computing dp[${i}][${j}] = dp[${i - 1}][${j - 1}] + dp[${i - 1}][${j}] = ${dp[i - 1][j - 1]} + ${dp[i - 1][j]} = ${dp[i][j]}.`
106+
});
107+
}
108+
}
109+
}
110+
111+
const triangle = dp.map(row => row.filter(x => x !== 0));
112+
113+
const visualSteps = steps.map(step => ({
114+
array: step.dp,
115+
currentPosition: { row: step.row, col: step.col },
116+
message: step.message,
117+
value: step.value
118+
}));
119+
120+
return { steps: visualSteps, result: triangle };
121+
}

0 commit comments

Comments
 (0)