Challenge different aspects of recursion, pathfinding, dynamic programming, and optimization techniques

Deepak Ranolia
5 min read5 days ago

--

Here’s how you can approach each of them:

Here’s how you can approach each of them:

1. Sum Path Problem: Modify the Pyramid Descent to find paths whose sum equals a target value instead of the product.

Scenario:

You are given a pyramid of integers, and your goal is to find a path from top to bottom where the sum of all the numbers along the path equals a given target. Each step must either go left or right, and you must sum the values at each step.

Example:

Pyramid:

1
2 3
4 1 1

Target Sum = 5

Solution: The path “LR” (starting from 1, then going left to 2, then right to 1) results in a sum of 1 + 2 + 1 = 4, which doesn't meet the target. The correct path is "LL" (starting from 1, going left to 2, then left again to 4), which gives a sum of 1 + 2 + 4 = 7, meeting the target.

Goal:

  • Write a function to find any path whose sum equals the target, or return null if no such path exists.
function pyramidSumPath(pyramid, target) {
function findPath(row, col, currentSum, path) {
if (row === pyramid.length - 1) {
currentSum += pyramid[row][col];
return currentSum === target ? path : null;
}
currentSum += pyramid[row][col];
let leftPath = findPath(row + 1, col, currentSum, path + 'L');
if (leftPath) return leftPath;
let rightPath = findPath(row + 1, col + 1, currentSum, path + 'R');
if (rightPath) return rightPath;
return null;
}
return findPath(0, 0, 0, '');
}

2. Memoization: Add memoization to the recursive solution to avoid recomputing the same paths multiple times.

Scenario:

For large pyramids, you want to avoid recalculating the same paths over and over again. Memoization allows you to store the results of subproblems so that when you encounter the same subproblem again, you can reuse the result, improving efficiency.

Example:

Pyramid:

2
4 3
3 2 6
2 9 5 2
10 5 2 15 5

You want to find the sum path to a target of 20. Without memoization, the function might need to calculate the same row and column combinations repeatedly.

Solution:

Use memoization to store the intermediate results for each row, column, and current sum combination.

function pyramidSumPathMemo(pyramid, target) {
const memo = {};
function findPath(row, col, currentSum, path) {
if (row === pyramid.length - 1) {
currentSum += pyramid[row][col];
return currentSum === target ? path : null;
}
const key = `${row}-${col}-${currentSum}`;
if (key in memo) return memo[key];
currentSum += pyramid[row][col];
let leftPath = findPath(row + 1, col, currentSum, path + 'L');
if (leftPath) return (memo[key] = leftPath);
let rightPath = findPath(row + 1, col + 1, currentSum, path + 'R');
if (rightPath) return (memo[key] = rightPath);
return (memo[key] = null);
}
return findPath(0, 0, 0, '');
}

Goal:

  • Implement a solution using memoization to reduce the number of redundant calculations.

3. Shortest Path Problem: Modify the solution to return the shortest valid path if multiple paths result in the target product.

Scenario:

There could be multiple paths that lead to the target product. In this case, the goal is to find the shortest valid path. That is, the path with the least number of steps that still reaches the target product.

Example:

Pyramid:

2
4 3
6 1 2

Target Product = 24

Possible paths are:

  • “LL”: 2 * 4 * 6 = 48 (too large)
  • “LR”: 2 * 4 * 1 = 8 (too small)
  • “RL”: 2 * 3 * 1 = 6 (too small)
  • “RR”: 2 * 3 * 2 = 12 (too small)

In this case, we can adjust this example to show a target of 48, and if multiple valid paths were possible, you’d return the shortest one.

function shortestProductPath(pyramid, target) {
function findPath(row, col, currentProduct, path) {
if (row === pyramid.length - 1) {
currentProduct *= pyramid[row][col];
return currentProduct === target ? path : null;
}
currentProduct *= pyramid[row][col];
let leftPath = findPath(row + 1, col, currentProduct, path + 'L');
let rightPath = findPath(row + 1, col + 1, currentProduct, path + 'R');
if (leftPath && rightPath) {
return leftPath.length < rightPath.length ? leftPath : rightPath;
}
return leftPath || rightPath;
}
return findPath(0, 0, 1, '');
}

Goal:

  • Modify the algorithm to return the shortest path when multiple valid paths exist.

4. Max Product Path: Instead of finding a path that results in a specific product, find the path with the maximum product.

Scenario:

You are tasked with finding the path that produces the maximum product from top to bottom of the pyramid, rather than a specific target product. Each path could produce a different result, and you must find the one with the highest value.

Example:

Pyramid:

1
2 3
4 1 2

You want to find the path with the maximum product. In this case, the path “LR” (1 * 2 * 2 = 4) produces the maximum product.

Solution:

Modify the function to track and return the path with the maximum product.

function maxProductPath(pyramid) {
function findMaxPath(row, col, currentProduct, path) {
if (row === pyramid.length - 1) {
currentProduct *= pyramid[row][col];
return { path, product: currentProduct };
}
currentProduct *= pyramid[row][col];
let leftPath = findMaxPath(row + 1, col, currentProduct, path + 'L');
let rightPath = findMaxPath(row + 1, col + 1, currentProduct, path + 'R');
return leftPath.product > rightPath.product ? leftPath : rightPath;
}
return findMaxPath(0, 0, 1, '').path;
}

Goal:

  • Implement a recursive function that finds the path with the maximum product, and return that path.

Challenges to Enhance Your Recursive Knowledge:

  1. Test Larger Pyramids: Try pyramids with more rows to observe how your recursive solutions handle deeper levels.
  2. Compare Memoized vs Non-Memoized Performance: Test your memoized and non-memoized versions on larger datasets to observe the efficiency improvements.
  3. Experiment with Different Targets: Change the target sums/products in the test cases and ensure your solutions adapt correctly.
  4. Visualize Paths: Add logging to your functions to print the paths being explored, which can give you insights into how recursion works.

By solving these scenarios, you’ll strengthen your understanding of recursion, pathfinding, dynamic programming, and optimization techniques in JavaScript!

--

--

Deepak Ranolia
Deepak Ranolia

Written by Deepak Ranolia

Strong technical skills, such as Coding, Software Engineering, Product Management & Finance. Talk about finance, technology & life https://rb.gy/9tod91

No responses yet