Skip to content

Instantly share code, notes, and snippets.

@lynxor
Created March 28, 2014 21:24
Show Gist options
  • Select an option

  • Save lynxor/9843282 to your computer and use it in GitHub Desktop.

Select an option

Save lynxor/9843282 to your computer and use it in GitHub Desktop.
Towers of hanoi
var _ = require("underscore");
function hanoi(numPieces) {
var stacks = [ _.range(1, numPieces + 1).reverse(), [], [] ];
function findOtherStackNo(one, two) {
return _.without([0, 1, 2], one, two)[0];
}
function peek(stack) {
return _.last(stack);
}
function pieceAbove(piece, stack) {
var ind = _.indexOf(stack, piece);
return stack[ind + 1];
}
//on which stack is it?
function findPiece(piece) {
return _.find([0, 1, 2], function (stackNo) {
return _.contains(stacks[stackNo], piece);
})
}
function movePiece(piece, sourceNo, targetNo) {
sourceNo = sourceNo || findPiece(piece);
var source = stacks[sourceNo],
target = stacks[targetNo],
otherNo = findOtherStackNo(sourceNo, targetNo);
if (peek(source) !== piece) {
if( allAbove(piece, sourceNo).length < 3){
movePiece(pieceAbove(piece, source), sourceNo, otherNo);
} else{
moveAllAbove(piece, sourceNo, otherNo);
}
}
if( peek(target) < piece){
movePiece( peek(target), targetNo, otherNo);
}
target.push(source.pop());
printIt();
}
//all pieces above the specified piece on the specified stack
function allAbove(piece, sourceNo) {
var ind = _.indexOf( stacks[sourceNo], piece);
return _.rest( stacks[sourceNo], ind + 1);
}
function moveAllAbove(piece, sourceNo, targetNo) {
moveAll( allAbove(piece, sourceNo), targetNo);
}
function moveAll(pieces, targetNo) {
_.each(pieces, function (piece) {
movePiece(piece, null, targetNo);
});
}
function strPos(pos, stack) {
var value = stack[pos];
if (value) {
return _.map( _.range(value),function () { return "_";}).join("");
}
return "|";
}
function printIt() {
console.log();
_.each( _.range(numPieces).reverse(), function (pos) {
console.log(strPos(pos, stacks[0]) + "\t" + strPos(pos, stacks[1]) + "\t" + strPos(pos, stacks[2]));
});
console.log("\n================================\n");
}
//gogogo
(function () {
printIt();
moveAll(_.range(1, numPieces + 1).reverse(), 2);
})();
}
hanoi(5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment