From b0add42b7f66be7ee2d79488dbb275126800577b Mon Sep 17 00:00:00 2001 From: mohanadft Date: Thu, 7 Sep 2023 19:15:07 +0300 Subject: [PATCH 1/5] :memo: Fix docs --- src/fibonacci/docs/PROBLEM.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fibonacci/docs/PROBLEM.md b/src/fibonacci/docs/PROBLEM.md index 1a10d1a..68d598c 100644 --- a/src/fibonacci/docs/PROBLEM.md +++ b/src/fibonacci/docs/PROBLEM.md @@ -12,5 +12,5 @@ Given n, calculate F(n). ## Solutions -* Tabulation: A ‘bottom-up’ approach where we start from the base case and reach the final answer that we want. -* Memoization: A top-down approach where we cache the results of function calls and return the cached result if the function is called again with the same inputs. +- Tabulation: A ‘bottom-up’ approach where we start from the base case and reach the final answer that we want. +- Memoization: A top-down approach where we cache the results of function calls and return the cached result if the function is called again with the same inputs and the same result. From e7c6268b18ac6e45f79e077fc03bb0baa8329037 Mon Sep 17 00:00:00 2001 From: mohanadft Date: Thu, 7 Sep 2023 19:15:33 +0300 Subject: [PATCH 2/5] :memo: Add documentation for the problem --- src/frog-jump/docs/PROBLEM.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/frog-jump/docs/PROBLEM.md diff --git a/src/frog-jump/docs/PROBLEM.md b/src/frog-jump/docs/PROBLEM.md new file mode 100644 index 0000000..cf16fb3 --- /dev/null +++ b/src/frog-jump/docs/PROBLEM.md @@ -0,0 +1,10 @@ +# Frog Jump 🐸 + +There is a frog on the '1st' step of an 'N' stairs long staircase. The frog wants to reach the 'Nth' stair. 'HEIGHT[i]' is the height of the '(i+1)th' stair.If Frog jumps from 'ith' to 'jth' stair, the energy lost in the jump is given by absolute value of ( HEIGHT[i-1] - HEIGHT[j-1] ). If the Frog is on 'ith' staircase, he can jump either to '(i+1)th' stair or to '(i+2)th' stair. Your task is to find the minimum total energy used by the frog to reach from '1st' stair to 'Nth' stair. + +[CodeNinja](https://www.codingninjas.com/studio/problems/frog-jump_3621012) + +## Solutions + +- Tabulation: A ‘bottom-up’ approach where we start from the base case and reach the final answer that we want. +- Memoization: A top-down approach where we cache the results of function calls and return the cached result if the function is called again with the same inputs and the same result. From 7fe17dd4ecc7bd1b6b02c675b63d853f3c38c61c Mon Sep 17 00:00:00 2001 From: mohanadft Date: Thu, 7 Sep 2023 19:22:42 +0300 Subject: [PATCH 3/5] :sparkles: Add a memo first solution --- src/frog-jump/solutions/memoization.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/frog-jump/solutions/memoization.ts diff --git a/src/frog-jump/solutions/memoization.ts b/src/frog-jump/solutions/memoization.ts new file mode 100644 index 0000000..1174cab --- /dev/null +++ b/src/frog-jump/solutions/memoization.ts @@ -0,0 +1,22 @@ +/** + * + * @param {number} n + * @param {number[]} heights + * @returns {number} + */ + +const solution = (n: number, heights: number[]): number => { + if (n === 0) { + return 0; + } + + let jumpOne = + solution(n - 1, heights) + Math.abs(heights[n] - heights[n - 1]); + let jumpTwo = Infinity; + + if (n > 1) { + jumpTwo = solution(n - 2, heights) + Math.abs(heights[n] - heights[n - 2]); + } + + return Math.min(jumpOne, jumpTwo); +}; From a83af48d2f8203771993800fdc273b7a817d7762 Mon Sep 17 00:00:00 2001 From: mohanadft Date: Thu, 7 Sep 2023 19:28:38 +0300 Subject: [PATCH 4/5] :recycle: Modify all function names, to avoid global names confusion --- src/climbing-stairs/solutions/memoization.ts | 20 +++++++++----------- src/climbing-stairs/solutions/tabulation.ts | 6 +++--- src/fibonacci/solutions/memoization.ts | 12 ++++++------ src/fibonacci/solutions/tabulation.ts | 6 +++--- src/frog-jump/solutions/memoization.ts | 6 +++--- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/climbing-stairs/solutions/memoization.ts b/src/climbing-stairs/solutions/memoization.ts index 4ff4bab..1a8e752 100644 --- a/src/climbing-stairs/solutions/memoization.ts +++ b/src/climbing-stairs/solutions/memoization.ts @@ -1,10 +1,5 @@ import { MemoObjectType } from '../../@types/types'; -/** - - - */ - /** * * @param {number} n @@ -12,7 +7,7 @@ import { MemoObjectType } from '../../@types/types'; */ // Solution 1 -const solution = (n: number): number => { +const climbingStairs1 = (n: number): number => { let m: MemoObjectType = {}; const backtrack = (n: number) => { if (n <= 1) return 1; @@ -35,12 +30,12 @@ const solution = (n: number): number => { // Solution 2 (Having a default hash, // no need to declare it in scope of the function) -const solution2 = (n: number, m: MemoObjectType = {}): number => { +const climbingStairs2 = (n: number, m: MemoObjectType = {}): number => { if (n <= 1) return 1; if (m[n]) return m[n]; - m[n] = solution2(n - 1, m) + solution2(n - 2, m); + m[n] = climbingStairs2(n - 1, m) + climbingStairs2(n - 2, m); return m[n]; }; @@ -52,12 +47,15 @@ const solution2 = (n: number, m: MemoObjectType = {}): number => { */ // Solution 3 (Having a default array, no need to declare it in scope of the function) -const solution3 = (n: number, m: number[] = Array(n + 1).fill(-1)): number => { +const climbingStairs3 = ( + n: number, + m: number[] = Array(n + 1).fill(-1) +): number => { if (n <= 1) return 1; if (m[n] != -1) return m[n]; - m[n] = solution3(n - 1, m) + solution3(n - 2, m); + m[n] = climbingStairs3(n - 1, m) + climbingStairs3(n - 2, m); return m[n]; }; @@ -68,7 +66,7 @@ const solution3 = (n: number, m: number[] = Array(n + 1).fill(-1)): number => { */ // Solution 4 (Using array for memoization) -const solution4 = (n: number): number => { +const climbingStairs4 = (n: number): number => { let m = Array(n + 1).fill(-1); const backtrack = (n: number) => { if (n <= 1) return 1; diff --git a/src/climbing-stairs/solutions/tabulation.ts b/src/climbing-stairs/solutions/tabulation.ts index b8b5bbd..8375e8f 100644 --- a/src/climbing-stairs/solutions/tabulation.ts +++ b/src/climbing-stairs/solutions/tabulation.ts @@ -12,7 +12,7 @@ * of memoization) */ -const solutionOne = (n: number): number => { +const climbingStairs1 = (n: number): number => { function* fibGenerator() { let arr = [1, 1]; @@ -43,7 +43,7 @@ const solutionOne = (n: number): number => { * @returns {number} */ -const solutionTwo = (n: number): number => { +const climbingStairs2 = (n: number): number => { let dp = [1, 1]; for (let i = 2; i <= n; i++) { @@ -65,7 +65,7 @@ const solutionTwo = (n: number): number => { * @returns {number} */ -const soultionThree = (n: number): number => { +const climbingStairs3 = (n: number): number => { let prev1 = 1; let prev2 = 1; diff --git a/src/fibonacci/solutions/memoization.ts b/src/fibonacci/solutions/memoization.ts index f60c461..c596b1e 100644 --- a/src/fibonacci/solutions/memoization.ts +++ b/src/fibonacci/solutions/memoization.ts @@ -7,7 +7,7 @@ import { MemoObjectType } from '../../@types/types'; */ // Solution 1 -const solution = (n: number): number => { +const fib1 = (n: number): number => { let m: MemoObjectType = {}; const backtrack = (n: number) => { if (n <= 1) return n; @@ -30,12 +30,12 @@ const solution = (n: number): number => { // Solution 2 (Having a default hash, // no need to declare it in scope of the function) -const solution2 = (n: number, m: MemoObjectType = {}): number => { +const fib2 = (n: number, m: MemoObjectType = {}): number => { if (n <= 1) return n; if (m[n]) return m[n]; - m[n] = solution2(n - 1, m) + solution2(n - 2, m); + m[n] = fib2(n - 1, m) + fib2(n - 2, m); return m[n]; }; @@ -47,12 +47,12 @@ const solution2 = (n: number, m: MemoObjectType = {}): number => { */ // Solution 3 (Having a default array, no need to declare it in scope of the function) -const solution3 = (n: number, m: number[] = Array(n + 1).fill(-1)): number => { +const fib3 = (n: number, m: number[] = Array(n + 1).fill(-1)): number => { if (n <= 1) return n; if (m[n] != -1) return m[n]; - m[n] = solution3(n - 1, m) + solution3(n - 2, m); + m[n] = fib3(n - 1, m) + fib3(n - 2, m); return m[n]; }; @@ -63,7 +63,7 @@ const solution3 = (n: number, m: number[] = Array(n + 1).fill(-1)): number => { */ // Solution 4 (Using array for memoization) -const solution4 = (n: number): number => { +const fib4 = (n: number): number => { let m = Array(n + 1).fill(-1); const backtrack = (n: number) => { if (n <= 1) return n; diff --git a/src/fibonacci/solutions/tabulation.ts b/src/fibonacci/solutions/tabulation.ts index 3825bd6..87c9ca0 100644 --- a/src/fibonacci/solutions/tabulation.ts +++ b/src/fibonacci/solutions/tabulation.ts @@ -12,7 +12,7 @@ * of memoization) */ -const solution1 = (n: number): number => { +const fib1 = (n: number): number => { function* fibGenerator() { let arr = [0, 1]; @@ -43,7 +43,7 @@ const solution1 = (n: number): number => { * @returns {number} */ -const solution2 = (n: number): number => { +const fib2 = (n: number): number => { let dp = [0, 1]; for (let i = 2; i <= n; i++) { @@ -65,7 +65,7 @@ const solution2 = (n: number): number => { * @returns {number} */ -const soultion3 = (n: number): number => { +const fib3 = (n: number): number => { let prev1 = 0; let prev2 = 1; diff --git a/src/frog-jump/solutions/memoization.ts b/src/frog-jump/solutions/memoization.ts index 1174cab..cb4f1b2 100644 --- a/src/frog-jump/solutions/memoization.ts +++ b/src/frog-jump/solutions/memoization.ts @@ -5,17 +5,17 @@ * @returns {number} */ -const solution = (n: number, heights: number[]): number => { +const fragJump1 = (n: number, heights: number[]): number => { if (n === 0) { return 0; } let jumpOne = - solution(n - 1, heights) + Math.abs(heights[n] - heights[n - 1]); + fragJump1(n - 1, heights) + Math.abs(heights[n] - heights[n - 1]); let jumpTwo = Infinity; if (n > 1) { - jumpTwo = solution(n - 2, heights) + Math.abs(heights[n] - heights[n - 2]); + jumpTwo = fragJump1(n - 2, heights) + Math.abs(heights[n] - heights[n - 2]); } return Math.min(jumpOne, jumpTwo); From 3410749d8b08d54381799591ec30ae3c67d30c8c Mon Sep 17 00:00:00 2001 From: mohanadft Date: Fri, 8 Sep 2023 01:04:42 +0300 Subject: [PATCH 5/5] :sparkles: Add the 2nd solution, an enhancement of the before one --- src/frog-jump/solutions/memoization.ts | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/frog-jump/solutions/memoization.ts b/src/frog-jump/solutions/memoization.ts index cb4f1b2..6ae8ba2 100644 --- a/src/frog-jump/solutions/memoization.ts +++ b/src/frog-jump/solutions/memoization.ts @@ -20,3 +20,36 @@ const fragJump1 = (n: number, heights: number[]): number => { return Math.min(jumpOne, jumpTwo); }; + +/** + * An Optimized Solution of the above. + * + * @param {number} n + * @param {number[]} heights + * @param {number[]} dp + * @returns {number} + */ + +const fragJump2 = ( + n: number, + heights: number[], + dp: number[] = Array(n + 1).fill(-1) +): number => { + if (n === 0) { + return 0; + } + + if (dp[n] !== -1) return dp[n]; + + let jumpOne = + fragJump2(n - 1, heights, dp) + Math.abs(heights[n] - heights[n - 1]); + let jumpTwo = Infinity; + + if (n > 1) { + jumpTwo = + fragJump2(n - 2, heights, dp) + Math.abs(heights[n] - heights[n - 2]); + } + + dp[n] = Math.min(jumpOne, jumpTwo); + return dp[n]; +};