Skip to content

Commit 9618fa0

Browse files
committed
feat(games-hanoi): implement towers of hanoi & references to Prolog solution
1 parent cb9d7a0 commit 9618fa0

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ More information about hashign on [wikipedia](https://en.wikipedia.org/wiki/Hash
3939
* ./interview-io/word-break.test.js
4040
* ./interview-io/shortest-continuous-subarray.test.js
4141

42+
### Games
43+
* ./games/tower-of-hanoi.test.js
44+
4245
### Sources
4346
* https://leetcode.com
4447
* http://www.crackingthecodinginterview.com

games/tower-of-hanoi.test.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Game - https://www.mathsisfun.com/games/towerofhanoi.html
3+
* Prolog - https://www.cpp.edu/~jrfisher/www/prolog_tutorial/2_3.html
4+
* Prolog (github) - https://github.com/dvberkel/prolog-hanoi
5+
*/
6+
7+
import test from 'ava'
8+
import { clone, id } from '../helpers'
9+
10+
let count = 0
11+
12+
const countMoves = (t) => {
13+
count += 1
14+
}
15+
16+
test.beforeEach(t => {
17+
count = 0
18+
})
19+
20+
test('tower of hanoi - 1', t => {
21+
t.deepEqual(
22+
solve([
23+
clone([1]), [], [] ],
24+
countMoves
25+
),
26+
[ [], [], clone([1]) ]
27+
)
28+
t.is(count, 1)
29+
})
30+
31+
test('tower of hanoi - 2', t => {
32+
t.deepEqual(
33+
solve(
34+
[ clone([1, 2]), [], [] ],
35+
countMoves
36+
),
37+
[ [], [], clone([1, 2]) ]
38+
)
39+
t.is(count, 3)
40+
})
41+
42+
test('tower of hanoi - 3', t => {
43+
const towerOf3 = [1, 2, 3]
44+
t.deepEqual(
45+
solve(
46+
[ clone(towerOf3), [], [] ],
47+
countMoves
48+
),
49+
[ [], [], clone(towerOf3) ]
50+
)
51+
t.is(count, 7)
52+
})
53+
54+
test('tower of hanoi - 5', t => {
55+
const towerOf5 = [1, 2, 3, 4, 5]
56+
t.deepEqual(
57+
solve(
58+
[ clone(towerOf5), [], [] ],
59+
countMoves
60+
),
61+
[ [], [], clone(towerOf5) ]
62+
)
63+
t.is(count, 31)
64+
})
65+
66+
const left = (tower) => tower[0]
67+
const center = (tower) => tower[1]
68+
const right = (tower) => tower[2]
69+
70+
const solve = (tower, onMove = id) => {
71+
const [first] = tower
72+
const levels = first.length
73+
move(levels - 1, left, right, center, tower, onMove)
74+
return tower
75+
}
76+
77+
/* manual solution
78+
79+
* one (moves: 1)
80+
* [1], [], []
81+
*
82+
* [], [], [1]
83+
*
84+
* two (moves: 3)
85+
* [1, 2], [], []
86+
87+
* [2], [1], []
88+
* [], [1], [2]
89+
* [], [], [1, 2]
90+
91+
* three (moves: 7)
92+
* [1, 2, 3], [], []
93+
94+
* [2, 3], [], [1]
95+
* [3], [2], [1]
96+
* [3], [1, 2], []
97+
* [], [1, 2], [3]
98+
* [1], [2], [3]
99+
* [1], [], [2, 3]
100+
* [], [], [1, 2, 3]
101+
102+
*/
103+
104+
const move = (index, left, right, center, tower, onMove) => {
105+
if (index === 0) {
106+
const item = left(tower).pop()
107+
right(tower).push(item)
108+
onMove()
109+
return
110+
}
111+
112+
move(index - 1, left, center, right, tower, onMove)
113+
move(0, left, right, center, tower, onMove)
114+
move(index - 1, center, right, left, tower, onMove)
115+
}

0 commit comments

Comments
 (0)