From d790a3f8bd515b2e7546ea4e83154e9e2e8ce60b Mon Sep 17 00:00:00 2001 From: alex_p Date: Mon, 31 Oct 2022 11:56:18 +0300 Subject: [PATCH 1/2] algorithm: add UniquePaths2 algo and a test for it --- Dynamic-Programming/UniquePaths2.js | 80 +++++++++++++++++++ .../tests/UniquePaths2.test.js | 19 +++++ 2 files changed, 99 insertions(+) create mode 100644 Dynamic-Programming/UniquePaths2.js create mode 100644 Dynamic-Programming/tests/UniquePaths2.test.js diff --git a/Dynamic-Programming/UniquePaths2.js b/Dynamic-Programming/UniquePaths2.js new file mode 100644 index 0000000000..7fc5ef3f36 --- /dev/null +++ b/Dynamic-Programming/UniquePaths2.js @@ -0,0 +1,80 @@ +/* + * 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 {Object []} + */ +const generateMatrix = (rows, columns, filler = 0) => { + const matrix = [] + for (let i = 0; i < rows; i += 1) { + const submatrix = [] + for (let k = 0; k < columns; k += 1) { + submatrix[k] = filler + } + matrix[i] = submatrix + } + return matrix +} + +/** + * @description Return number of unique paths + * @param {Object []} obstacles Obstacles grid + * @returns {Number} + */ +const uniquePaths2 = (obstacles) => { + if (!(obstacles instanceof Object)) { + 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 += 1) { + // If robot encounters an obstacle in these cells, + // he cannot continue movind in that direction + if (obstacles[i][0]) { + break + } + grid[i][0] = 1 + } + for (let j = 0; j < columns; j += 1) { + 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 += 1) { + for (let j = 1; j < columns; j += 1) { + if (obstacles[i][j]) { + grid[i][j] = 0 + } else { + grid[i][j] = 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..c35b1facee --- /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('Case 1: 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('Case 2: 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('Case 3: there are wrong type of input data', () => { + expect(() => uniquePaths2('wrong input')).toThrow() + expect(() => uniquePaths2(100)).toThrow() + }) +}) From ae50228fc50ebacef429f90d5320fb4fa2243e3e Mon Sep 17 00:00:00 2001 From: alex_p Date: Mon, 31 Oct 2022 12:12:15 +0300 Subject: [PATCH 2/2] fix: fix inaccuracies and spelling errors --- Dynamic-Programming/UniquePaths2.js | 26 ++++++++----------- .../tests/UniquePaths2.test.js | 6 ++--- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Dynamic-Programming/UniquePaths2.js b/Dynamic-Programming/UniquePaths2.js index 7fc5ef3f36..52bf9d08b2 100644 --- a/Dynamic-Programming/UniquePaths2.js +++ b/Dynamic-Programming/UniquePaths2.js @@ -19,13 +19,13 @@ * @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 {Object []} + * @returns {Array [][]} */ const generateMatrix = (rows, columns, filler = 0) => { const matrix = [] - for (let i = 0; i < rows; i += 1) { + for (let i = 0; i < rows; i++) { const submatrix = [] - for (let k = 0; k < columns; k += 1) { + for (let k = 0; k < columns; k++) { submatrix[k] = filler } matrix[i] = submatrix @@ -35,11 +35,11 @@ const generateMatrix = (rows, columns, filler = 0) => { /** * @description Return number of unique paths - * @param {Object []} obstacles Obstacles grid + * @param {Array [][]} obstacles Obstacles grid * @returns {Number} */ const uniquePaths2 = (obstacles) => { - if (!(obstacles instanceof Object)) { + if (!Array.isArray(obstacles)) { throw new Error('Input data must be type of Array') } // Create grid for calculating number of unique ways @@ -48,15 +48,15 @@ const uniquePaths2 = (obstacles) => { 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 += 1) { + for (let i = 0; i < rows; i++) { // If robot encounters an obstacle in these cells, - // he cannot continue movind in that direction + // he cannot continue moving in that direction if (obstacles[i][0]) { break } grid[i][0] = 1 } - for (let j = 0; j < columns; j += 1) { + for (let j = 0; j < columns; j++) { if (obstacles[0][j]) { break } @@ -65,13 +65,9 @@ const uniquePaths2 = (obstacles) => { // 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 += 1) { - for (let j = 1; j < columns; j += 1) { - if (obstacles[i][j]) { - grid[i][j] = 0 - } else { - grid[i][j] = grid[i - 1][j] + grid[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] diff --git a/Dynamic-Programming/tests/UniquePaths2.test.js b/Dynamic-Programming/tests/UniquePaths2.test.js index c35b1facee..e34b9a3303 100644 --- a/Dynamic-Programming/tests/UniquePaths2.test.js +++ b/Dynamic-Programming/tests/UniquePaths2.test.js @@ -2,17 +2,17 @@ import { uniquePaths2 } from '../UniquePaths2' describe('Unique Paths2', () => { // Should return number of ways, taken into account the obstacles - test('Case 1: there are obstacles in the way', () => { + 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('Case 2: there are no obstacles in the way', () => { + 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('Case 3: there are wrong type of input data', () => { + test('There are wrong type of input data', () => { expect(() => uniquePaths2('wrong input')).toThrow() expect(() => uniquePaths2(100)).toThrow() }) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy