From df17e29fb7c48ab9c223d3c759eca88fa375d354 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Tue, 10 Jul 2018 07:15:36 +0300 Subject: [PATCH] Add backtracking solution to JumpGame. --- .../jump-game/__test__/btJumpGame.test.js | 17 ++++++++ .../jump-game/__test__/grdJumpGame.test.js | 1 + .../uncategorized/jump-game/btJumpGame.js | 42 +++++++++++++++++++ .../uncategorized/jump-game/grdJumpGame.js | 1 + 4 files changed, 61 insertions(+) create mode 100644 src/algorithms/uncategorized/jump-game/__test__/btJumpGame.test.js create mode 100644 src/algorithms/uncategorized/jump-game/btJumpGame.js diff --git a/src/algorithms/uncategorized/jump-game/__test__/btJumpGame.test.js b/src/algorithms/uncategorized/jump-game/__test__/btJumpGame.test.js new file mode 100644 index 00000000..3a91e481 --- /dev/null +++ b/src/algorithms/uncategorized/jump-game/__test__/btJumpGame.test.js @@ -0,0 +1,17 @@ +import btJumpGame from '../btJumpGame'; + +describe('btJumpGame', () => { + it('should solve Jump Game problem in backtracking manner', () => { + expect(btJumpGame([1, 0])).toBeTruthy(); + expect(btJumpGame([100, 0])).toBeTruthy(); + expect(btJumpGame([2, 3, 1, 1, 4])).toBeTruthy(); + expect(btJumpGame([1, 1, 1, 1, 1])).toBeTruthy(); + expect(btJumpGame([1, 1, 1, 10, 1])).toBeTruthy(); + expect(btJumpGame([1, 5, 2, 1, 0, 2, 0])).toBeTruthy(); + + expect(btJumpGame([1, 0, 1])).toBeFalsy(); + expect(btJumpGame([3, 2, 1, 0, 4])).toBeFalsy(); + expect(btJumpGame([0, 0, 0, 0, 0])).toBeFalsy(); + expect(btJumpGame([5, 4, 3, 2, 1, 0, 0])).toBeFalsy(); + }); +}); diff --git a/src/algorithms/uncategorized/jump-game/__test__/grdJumpGame.test.js b/src/algorithms/uncategorized/jump-game/__test__/grdJumpGame.test.js index f9339f68..530d3641 100644 --- a/src/algorithms/uncategorized/jump-game/__test__/grdJumpGame.test.js +++ b/src/algorithms/uncategorized/jump-game/__test__/grdJumpGame.test.js @@ -6,6 +6,7 @@ describe('grdJumpGame', () => { expect(grdJumpGame([100, 0])).toBeTruthy(); expect(grdJumpGame([2, 3, 1, 1, 4])).toBeTruthy(); expect(grdJumpGame([1, 1, 1, 1, 1])).toBeTruthy(); + expect(grdJumpGame([1, 1, 1, 10, 1])).toBeTruthy(); expect(grdJumpGame([1, 5, 2, 1, 0, 2, 0])).toBeTruthy(); expect(grdJumpGame([1, 0, 1])).toBeFalsy(); diff --git a/src/algorithms/uncategorized/jump-game/btJumpGame.js b/src/algorithms/uncategorized/jump-game/btJumpGame.js new file mode 100644 index 00000000..6f791da1 --- /dev/null +++ b/src/algorithms/uncategorized/jump-game/btJumpGame.js @@ -0,0 +1,42 @@ +/** + * BACKTRACKING approach of solving Jump Game. + * + * @param {number[]} numbers - array of possible jump length. + * @param {number} startIndex - index from where we start jumping. + * @param {number[]} currentJumps - current jumps path. + * @return {boolean} + */ +export default function btJumpGame(numbers, startIndex = 0, currentJumps = []) { + if (startIndex === numbers.length - 1) { + // We've jumped directly to last cell. This situation is a solution. + return true; + } + + // Check what the longest jump we could make from current position. + // We don't need to jump beyond the array. + const maxJumpLength = Math.min( + numbers[startIndex], // Jump is within array. + numbers.length - 1 - startIndex, // Jump goes beyond array. + ); + + // Let's start jumping from startIndex and see whether any + // jump is successful and has reached the end of the array. + for (let jumpLength = maxJumpLength; jumpLength > 0; jumpLength -= 1) { + // Try next jump. + const nextIndex = startIndex + jumpLength; + currentJumps.push(nextIndex); + + const isJumpSuccessful = btJumpGame(numbers, nextIndex, currentJumps); + + // Check if current jump was successful. + if (isJumpSuccessful) { + return true; + } + + // BACKTRACKING. + // If previous jump wasn't successful then retreat and try the next one. + currentJumps.pop(); + } + + return false; +} diff --git a/src/algorithms/uncategorized/jump-game/grdJumpGame.js b/src/algorithms/uncategorized/jump-game/grdJumpGame.js index 5cba2e85..1b14eb91 100644 --- a/src/algorithms/uncategorized/jump-game/grdJumpGame.js +++ b/src/algorithms/uncategorized/jump-game/grdJumpGame.js @@ -2,6 +2,7 @@ * GREEDY approach of solving Jump Game. * * @param {number[]} numbers - array of possible jump length. + * @return {boolean} */ export default function grdJumpGame(numbers) { // The "good" cell is a cell from which we may jump to the last cell of the numbers array.