From 781a7cff23db6e39251996abcf42ddf3d4231b4c Mon Sep 17 00:00:00 2001 From: Jaiharishan Date: Mon, 3 Oct 2022 18:35:03 +0530 Subject: [PATCH 1/6] Contribute: Added algorithm for Unique Paths problem --- Dynamic-Programming/UniquePaths.js | 26 +++++++++++++++++++ Dynamic-Programming/tests/UniquePaths.test.js | 19 ++++++++++++++ package-lock.json | 18 +++++-------- 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 Dynamic-Programming/UniquePaths.js create mode 100644 Dynamic-Programming/tests/UniquePaths.test.js diff --git a/Dynamic-Programming/UniquePaths.js b/Dynamic-Programming/UniquePaths.js new file mode 100644 index 0000000000..5bd63beec2 --- /dev/null +++ b/Dynamic-Programming/UniquePaths.js @@ -0,0 +1,26 @@ +/** + * A Dynamic Programming based solution for calculating the number ways to travel from Top-Left of the matrix to Bottom-Right of the matrix + * https://leetcode.com/problems/unique-paths/ + */ + +// Return the number of unique paths, given the dimensions of rows and columns + +const uniquePaths = (rows, cols) => { + let dp = new Array(cols).fill(1) + + for (let i = 1; i < rows; i++) { + const tmp = [] + + for (let j = 0; j < cols; j++) { + if (j === 0) { + tmp[j] = dp[j] + } else { + tmp[j] = tmp[j - 1] + dp[j] + } + } + dp = tmp + } + return dp.pop() +} + +export { uniquePaths } diff --git a/Dynamic-Programming/tests/UniquePaths.test.js b/Dynamic-Programming/tests/UniquePaths.test.js new file mode 100644 index 0000000000..e89a33cdd0 --- /dev/null +++ b/Dynamic-Programming/tests/UniquePaths.test.js @@ -0,0 +1,19 @@ +import { uniquePaths } from '../UniquePaths' + +test('Base Case 1', () => { + const rows = 3 + const cols = 7 + expect(uniquePaths(rows, cols)).toBe(28) +}) + +test('Base Case 2', () => { + const rows = 3 + const cols = 2 + expect(uniquePaths(rows, cols)).toBe(3) +}) + +test('Base Case 3', () => { + const rows = 8 + const cols = 14 + expect(uniquePaths(rows, cols)).toBe(77520) +}) diff --git a/package-lock.json b/package-lock.json index d7cb0da2ee..98b9220873 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13049,8 +13049,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "7.2.0", @@ -14140,15 +14139,13 @@ "version": "16.0.3", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "requires": {} + "dev": true }, "eslint-config-standard-jsx": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-10.0.0.tgz", "integrity": "sha512-hLeA2f5e06W1xyr/93/QJulN/rLbUVUmqTlexv9PRKHFwEC9ffJcH2LvJhMoEqYQBEYafedgGZXH2W8NUpt5lA==", - "dev": true, - "requires": {} + "dev": true }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -14441,8 +14438,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", - "dev": true, - "requires": {} + "dev": true }, "eslint-plugin-react": { "version": "7.25.3", @@ -16240,8 +16236,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "26.0.0", @@ -19434,8 +19429,7 @@ "ws": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", - "requires": {} + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" }, "xdg-basedir": { "version": "4.0.0", From cb8b0e1f73e3c8c6633f8f27da30aa3b5a7987f4 Mon Sep 17 00:00:00 2001 From: Jaiharishan Date: Mon, 3 Oct 2022 20:19:44 +0530 Subject: [PATCH 2/6] Fix: Fixed Package conflicts --- package-lock.json | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98b9220873..d7cb0da2ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13049,7 +13049,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -14139,13 +14140,15 @@ "version": "16.0.3", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true + "dev": true, + "requires": {} }, "eslint-config-standard-jsx": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-10.0.0.tgz", "integrity": "sha512-hLeA2f5e06W1xyr/93/QJulN/rLbUVUmqTlexv9PRKHFwEC9ffJcH2LvJhMoEqYQBEYafedgGZXH2W8NUpt5lA==", - "dev": true + "dev": true, + "requires": {} }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -14438,7 +14441,8 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-react": { "version": "7.25.3", @@ -16236,7 +16240,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "26.0.0", @@ -19429,7 +19434,8 @@ "ws": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "requires": {} }, "xdg-basedir": { "version": "4.0.0", From 0496b332cf197f553a4cd89f53370eb4c7076e17 Mon Sep 17 00:00:00 2001 From: Jaiharishan Date: Mon, 3 Oct 2022 20:51:15 +0530 Subject: [PATCH 3/6] Fix: Names for test cases are changed --- Dynamic-Programming/tests/UniquePaths.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dynamic-Programming/tests/UniquePaths.test.js b/Dynamic-Programming/tests/UniquePaths.test.js index e89a33cdd0..e0a91f1fe4 100644 --- a/Dynamic-Programming/tests/UniquePaths.test.js +++ b/Dynamic-Programming/tests/UniquePaths.test.js @@ -1,18 +1,18 @@ import { uniquePaths } from '../UniquePaths' -test('Base Case 1', () => { +test('Test case with rows=3 and cols=7', () => { const rows = 3 const cols = 7 expect(uniquePaths(rows, cols)).toBe(28) }) -test('Base Case 2', () => { +test('Test case with rows=3 and cols=2', () => { const rows = 3 const cols = 2 expect(uniquePaths(rows, cols)).toBe(3) }) -test('Base Case 3', () => { +test('Test case with rows=8 and cols=14', () => { const rows = 8 const cols = 14 expect(uniquePaths(rows, cols)).toBe(77520) From b721d48beb1206abbd4146c4cf8aa7e771b21414 Mon Sep 17 00:00:00 2001 From: Jaiharishan Date: Mon, 3 Oct 2022 21:16:02 +0530 Subject: [PATCH 4/6] Fix: Made all test cases to go under single block --- Dynamic-Programming/tests/UniquePaths.test.js | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/Dynamic-Programming/tests/UniquePaths.test.js b/Dynamic-Programming/tests/UniquePaths.test.js index e0a91f1fe4..c5fe2e7673 100644 --- a/Dynamic-Programming/tests/UniquePaths.test.js +++ b/Dynamic-Programming/tests/UniquePaths.test.js @@ -1,19 +1,15 @@ import { uniquePaths } from '../UniquePaths' -test('Test case with rows=3 and cols=7', () => { - const rows = 3 - const cols = 7 - expect(uniquePaths(rows, cols)).toBe(28) -}) +describe('UniquePaths', () => { + it('uniquePaths for rows=3 and cols=7', () => { + expect(uniquePaths(3, 7)).toBe(28) + }) -test('Test case with rows=3 and cols=2', () => { - const rows = 3 - const cols = 2 - expect(uniquePaths(rows, cols)).toBe(3) -}) + it('uniquePaths for rows=3 and cols=2', () => { + expect(climbStairs(3, 2)).toBe(3) + }) -test('Test case with rows=8 and cols=14', () => { - const rows = 8 - const cols = 14 - expect(uniquePaths(rows, cols)).toBe(77520) + it('uniquePaths for rows=8 and cols=14', () => { + expect(climbStairs(8, 14)).toBe(77520) + }) }) From e1c8bd1582c3980d790dd62b2d4238f3a11f8bbc Mon Sep 17 00:00:00 2001 From: Jaiharishan Date: Mon, 3 Oct 2022 21:41:48 +0530 Subject: [PATCH 5/6] Fix: Made the test cases to come under single Test block --- Dynamic-Programming/tests/UniquePaths.test.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Dynamic-Programming/tests/UniquePaths.test.js b/Dynamic-Programming/tests/UniquePaths.test.js index c5fe2e7673..7efd1af08f 100644 --- a/Dynamic-Programming/tests/UniquePaths.test.js +++ b/Dynamic-Programming/tests/UniquePaths.test.js @@ -1,15 +1,7 @@ import { uniquePaths } from '../UniquePaths' -describe('UniquePaths', () => { - it('uniquePaths for rows=3 and cols=7', () => { - expect(uniquePaths(3, 7)).toBe(28) - }) - - it('uniquePaths for rows=3 and cols=2', () => { - expect(climbStairs(3, 2)).toBe(3) - }) - - it('uniquePaths for rows=8 and cols=14', () => { - expect(climbStairs(8, 14)).toBe(77520) - }) +test('Test case for UniquePaths', () => { + expect(uniquePaths(3, 7)).toBe(28) + expect(uniquePaths(3, 2)).toBe(3) + expect(uniquePaths(8, 14)).toBe(77520) }) From 3dac5aafc826584ec9890731e2987210b88c4c5f Mon Sep 17 00:00:00 2001 From: Jaiharishan Date: Tue, 4 Oct 2022 09:25:27 +0530 Subject: [PATCH 6/6] Improve: More comments added for better understanding --- Dynamic-Programming/UniquePaths.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Dynamic-Programming/UniquePaths.js b/Dynamic-Programming/UniquePaths.js index 5bd63beec2..5ed4461348 100644 --- a/Dynamic-Programming/UniquePaths.js +++ b/Dynamic-Programming/UniquePaths.js @@ -1,6 +1,19 @@ -/** +/* * A Dynamic Programming based solution for calculating the number ways to travel from Top-Left of the matrix to Bottom-Right of the matrix * https://leetcode.com/problems/unique-paths/ + * Problem Statement: + * There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e., grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot can only move either down or right at any point in time. + * Given the two integers m and n, return the number of possible unique paths that the robot can take to reach the bottom-right corner. + * Approach: + * As the given problem can be reduced to smaller and overlapping sub problems, we can use dynamic programming and memoization to solve this problem. + * Time complexity: O(M * N) (M->ROWS | N->COLS) + * Space complexity: O(M * N) (M->ROWS | N->COLS) + */ + +/** + * @param {number} rows + * @param {number} cols + * @return {number} */ // Return the number of unique paths, given the dimensions of rows and columns