From f8222ed397df15524fb75e14cf03d7cbd321a725 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Mon, 14 May 2018 11:28:56 +0300 Subject: [PATCH] Add Tower of Hanoi. --- .../hanoi-tower/__test__/hanoiTower.test.js | 56 +++++++++++++------ .../uncategorized/hanoi-tower/hanoiTower.js | 36 +++++------- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/algorithms/uncategorized/hanoi-tower/__test__/hanoiTower.test.js b/src/algorithms/uncategorized/hanoi-tower/__test__/hanoiTower.test.js index c7ef66c4..d720d183 100644 --- a/src/algorithms/uncategorized/hanoi-tower/__test__/hanoiTower.test.js +++ b/src/algorithms/uncategorized/hanoi-tower/__test__/hanoiTower.test.js @@ -1,42 +1,62 @@ import hanoiTower from '../hanoiTower'; +import Stack from '../../../../data-structures/stack/Stack'; describe('hanoiTower', () => { it('should solve tower of hanoi puzzle with 2 discs', () => { - const moveCallbackMock = jest.fn(); + const moveCallback = jest.fn(); const numberOfDiscs = 2; - hanoiTower(numberOfDiscs, moveCallbackMock); + const fromPole = new Stack(); + const withPole = new Stack(); + const toPole = new Stack(); - expect(moveCallbackMock).toHaveBeenCalledTimes((2 ** numberOfDiscs) - 1); + hanoiTower({ + numberOfDiscs, + moveCallback, + fromPole, + withPole, + toPole, + }); - expect(moveCallbackMock.mock.calls[0][0]).toBe(1); - expect(moveCallbackMock.mock.calls[0][1]).toEqual([1, 2]); - expect(moveCallbackMock.mock.calls[0][2]).toEqual([]); + expect(moveCallback).toHaveBeenCalledTimes((2 ** numberOfDiscs) - 1); - expect(moveCallbackMock.mock.calls[1][0]).toBe(2); - expect(moveCallbackMock.mock.calls[1][1]).toEqual([2]); - expect(moveCallbackMock.mock.calls[1][2]).toEqual([]); + expect(fromPole.toArray()).toEqual([]); + expect(toPole.toArray()).toEqual([1, 2]); - expect(moveCallbackMock.mock.calls[2][0]).toBe(1); - expect(moveCallbackMock.mock.calls[2][1]).toEqual([1]); - expect(moveCallbackMock.mock.calls[2][2]).toEqual([2]); + expect(moveCallback.mock.calls[0][0]).toBe(1); + expect(moveCallback.mock.calls[0][1]).toEqual([1, 2]); + expect(moveCallback.mock.calls[0][2]).toEqual([]); + + expect(moveCallback.mock.calls[1][0]).toBe(2); + expect(moveCallback.mock.calls[1][1]).toEqual([2]); + expect(moveCallback.mock.calls[1][2]).toEqual([]); + + expect(moveCallback.mock.calls[2][0]).toBe(1); + expect(moveCallback.mock.calls[2][1]).toEqual([1]); + expect(moveCallback.mock.calls[2][2]).toEqual([2]); }); it('should solve tower of hanoi puzzle with 3 discs', () => { - const moveCallbackMock = jest.fn(); + const moveCallback = jest.fn(); const numberOfDiscs = 3; - hanoiTower(numberOfDiscs, moveCallbackMock); + hanoiTower({ + numberOfDiscs, + moveCallback, + }); - expect(moveCallbackMock).toHaveBeenCalledTimes((2 ** numberOfDiscs) - 1); + expect(moveCallback).toHaveBeenCalledTimes((2 ** numberOfDiscs) - 1); }); it('should solve tower of hanoi puzzle with 6 discs', () => { - const moveCallbackMock = jest.fn(); + const moveCallback = jest.fn(); const numberOfDiscs = 6; - hanoiTower(numberOfDiscs, moveCallbackMock); + hanoiTower({ + numberOfDiscs, + moveCallback, + }); - expect(moveCallbackMock).toHaveBeenCalledTimes((2 ** numberOfDiscs) - 1); + expect(moveCallback).toHaveBeenCalledTimes((2 ** numberOfDiscs) - 1); }); }); diff --git a/src/algorithms/uncategorized/hanoi-tower/hanoiTower.js b/src/algorithms/uncategorized/hanoi-tower/hanoiTower.js index 8406bf29..86d78880 100644 --- a/src/algorithms/uncategorized/hanoi-tower/hanoiTower.js +++ b/src/algorithms/uncategorized/hanoi-tower/hanoiTower.js @@ -1,17 +1,5 @@ import Stack from '../../../data-structures/stack/Stack'; -/** - * @param {Stack} fromPole - * @param {Stack} toPole - * @param {function(disc: number, fromPole: number[], toPole: number[])} moveCallback - */ -function moveDisc(fromPole, toPole, moveCallback) { - moveCallback(fromPole.peek(), fromPole.toArray(), toPole.toArray()); - - const disc = fromPole.pop(); - toPole.push(disc); -} - /** * @param {number} numberOfDiscs * @param {Stack} fromPole @@ -28,7 +16,9 @@ function hanoiTowerRecursive({ }) { if (numberOfDiscs === 1) { // Base case with just one disc. - moveDisc(fromPole, toPole, moveCallback); + moveCallback(fromPole.peek(), fromPole.toArray(), toPole.toArray()); + const disc = fromPole.pop(); + toPole.push(disc); } else { // In case if there are more discs then move them recursively. @@ -64,21 +54,21 @@ function hanoiTowerRecursive({ /** * @param {number} numberOfDiscs * @param {function(disc: number, fromPole: number[], toPole: number[])} moveCallback + * @param {Stack} [fromPole] + * @param {Stack} [withPole] + * @param {Stack} [toPole] */ -export default function hanoiTower(numberOfDiscs, moveCallback) { +export default function hanoiTower({ + numberOfDiscs, + moveCallback, + fromPole = new Stack(), + withPole = new Stack(), + toPole = new Stack(), +}) { // Each of three poles of Tower of Hanoi puzzle is represented as a stack // that might contain elements (discs). Each disc is represented as a number. // Larger discs have bigger number equivalent. - // The pole from where the discs should be moved. - const fromPole = new Stack(); - - // The middle pole that should be used as a helper. - const withPole = new Stack(); - - // The destination pole where all discs need to be moved. - const toPole = new Stack(); - // Let's create the discs and put them to the fromPole. for (let discSize = numberOfDiscs; discSize > 0; discSize -= 1) { fromPole.push(discSize);