diff --git a/Dynamic-Programming/UniquePaths2.js b/Dynamic-Programming/UniquePaths2.js new file mode 100644 index 0000000000..52bf9d08b2 --- /dev/null +++ b/Dynamic-Programming/UniquePaths2.js @@ -0,0 +1,76 @@ +/* + * Unique Paths 2 + * + * There is a robot on an `m x n` grid. + * The robot is initially located at the top-left corner + * The robot tries to move to the bottom-right corner. + * The robot can only move either down or right at any point in time. + * + * Given grid with obstacles + * An obstacle and space are marked as 1 or 0 respectively in grid. + * A path that the robot takes cannot include any square that is an obstacle. + * Return the number of possible unique paths that the robot can take to reach the bottom-right corner. + * + * More info: https://leetcode.com/problems/unique-paths-ii/ + */ + +/** + * @description Return 'rows x columns' grid with cells filled by 'filler' + * @param {Number} rows Number of rows in the grid + * @param {Number} columns Number of columns in the grid + * @param {String | Number | Boolean} filler The value to fill cells + * @returns {Array [][]} + */ +const generateMatrix = (rows, columns, filler = 0) => { + const matrix = [] + for (let i = 0; i < rows; i++) { + const submatrix = [] + for (let k = 0; k < columns; k++) { + submatrix[k] = filler + } + matrix[i] = submatrix + } + return matrix +} + +/** + * @description Return number of unique paths + * @param {Array [][]} obstacles Obstacles grid + * @returns {Number} + */ +const uniquePaths2 = (obstacles) => { + if (!Array.isArray(obstacles)) { + throw new Error('Input data must be type of Array') + } + // Create grid for calculating number of unique ways + const rows = obstacles.length + const columns = obstacles[0].length + const grid = generateMatrix(rows, columns) + // Fill the outermost cell with 1 b/c it has + // the only way to reach neighbor + for (let i = 0; i < rows; i++) { + // If robot encounters an obstacle in these cells, + // he cannot continue moving in that direction + if (obstacles[i][0]) { + break + } + grid[i][0] = 1 + } + for (let j = 0; j < columns; j++) { + if (obstacles[0][j]) { + break + } + grid[0][j] = 1 + } + // Fill the rest of grid by dynamic programming + // using following reccurent formula: + // K[i][j] = K[i - 1][j] + K[i][j - 1] + for (let i = 1; i < rows; i++) { + for (let j = 1; j < columns; j++) { + grid[i][j] = obstacles[i][j] ? 0 : grid[i - 1][j] + grid[i][j - 1] + } + } + return grid[rows - 1][columns - 1] +} + +export { uniquePaths2 } diff --git a/Dynamic-Programming/tests/UniquePaths2.test.js b/Dynamic-Programming/tests/UniquePaths2.test.js new file mode 100644 index 0000000000..e34b9a3303 --- /dev/null +++ b/Dynamic-Programming/tests/UniquePaths2.test.js @@ -0,0 +1,19 @@ +import { uniquePaths2 } from '../UniquePaths2' + +describe('Unique Paths2', () => { + // Should return number of ways, taken into account the obstacles + test('There are obstacles in the way', () => { + expect(uniquePaths2([[0, 0, 0], [0, 1, 0], [0, 0, 0]])).toEqual(2) + expect(uniquePaths2([[0, 0, 0], [0, 1, 0], [0, 0, 0], [1, 0, 0]])).toEqual(3) + }) + // Should return number of all possible ways to reach right-bottom corner + test('There are no obstacles in the way', () => { + expect(uniquePaths2([[0, 0, 0], [0, 0, 0], [0, 0, 0]])).toEqual(6) + expect(uniquePaths2([[0, 0, 0], [0, 0, 0]])).toEqual(3) + }) + // Should throw an exception b/c input data has wrong type + test('There are wrong type of input data', () => { + expect(() => uniquePaths2('wrong input')).toThrow() + expect(() => uniquePaths2(100)).toThrow() + }) +})
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: