题目地址:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html
function Puzzle(dimension){
this.array = new Array();
this.moves;
this.manhattan;
this.priority;
this.spacePos;
}
Puzzle.prototype = {
construstor : Puzzle,
init : function (dimension) {
// this.array = [8, 1, 3, 4, 0, 2, 7, 6, 5]
this.array[0] = 8;
this.array[1] = 1;
this.array[2] = 3;
this.array[3] = 4;
this.array[4] = 0;
this.array[5] = 2;
this.array[6] = 7;
this.array[7] = 6;
this.array[8] = 5;
this.moves = 0;
this.manhattan = 0;
for (var i = 0; i < dimension*dimension; i++){
if (this.array[i])
this.manhattan = this.manhattan + Math.floor(Math.abs(this.array[i]-i-1)/dimension) + Math.abs(this.array[i]-i-1)%dimension;
else this.spacePos = i;
}
this.priority = this.moves + this.manhattan;
},
manhattanFn : function (dimension) {
this.manhattan = 0;
for (var i = 0; i < dimension*dimension; i++){
if (this.array[i])
this.manhattan = this.manhattan + Math.floor(Math.abs(this.array[i]-i-1)/dimension) + Math.abs(this.array[i]-i-1)%dimension;
else this.spacePos = i;
}
this.priority = this.moves + this.manhattan;
},
swap : function (a, b){
var tmp = this.array[a];
this.array[a] = this.array[b];
this.array[b] = tmp;
},
clone : function () {
var copy = new Puzzle();
copy.moves = this.moves;
copy.manhattan = this.manhattan;
copy.priority = this.priority;
copy.spacePos = this.spacePos;
for (var i = 0; i < this.array.length; ++i){
copy.array[i] = this.array[i];
}
return copy;
}
}
function PriorityQueue(){
this.cnt;
this.array = new Array();
}
PriorityQueue.prototype = {
constructor : PriorityQueue,
init: function () {
this.cnt = 0;
},
swap : function (a, b){
var tmp = this.array[a];
this.array[a] = this.array[b];
this.array[b] = tmp;
},
push : function (node) {
var curIdx = this.cnt = this.cnt +1;
this.array[curIdx] = node;
//console.log(this);
while (Math.floor(curIdx/2)){
//console.log(Math.floor(curIdx/2));
if (this.array[curIdx].priority < this.array[Math.floor(curIdx/2)].priority){
this.swap(curIdx, Math.floor(curIdx/2));
// var tmp = node.clone();
// this.array[curIdx] = this.array[Math.floor(curIdx/2)].clone();
// this.array[Math.floor(curIdx/2)] = tmp;
}
curIdx = Math.floor(curIdx/2);
}
},
pop : function () {
var minNode = this.array[1];
this.swap(1, this.cnt);
this.cnt = this.cnt - 1;
var curIdx = 1;
//console.log(this);
while (2*curIdx<=this.cnt){
var left = 2*curIdx;
var right = 2*curIdx + 1;
var small = curIdx;
if (this.array[left].priority < this.array[curIdx].priority) small = left;
if (right <= this.cnt && this.array[right].priority < this.array[small].priority) small = right;
this.swap(curIdx, small);
curIdx = 2*curIdx;
}
return minNode;
}
}
var dimension = 3;
var moves = 0;
var puzzle = new Puzzle(dimension);
puzzle.init(dimension);
//console.log(puzzle);
var pq = new PriorityQueue();
pq.init();
pq.push(puzzle);
//console.log(pq);
while(pq.cnt){
moves = moves + 1;
var minNode = pq.pop();
//console.log(pq);
if (minNode.spacePos-dimension >= 0){
var tmp = minNode.clone();
tmp.swap(tmp.spacePos, tmp.spacePos-dimension);
tmp.moves = moves;
tmp.manhattanFn(dimension);
if (tmp.manhattan == 0) return console.log(tmp.moves);
if (tmp.manhattan < minNode.manhattan)
pq.push(tmp);
}
//console.log(minNode.spacePos);
//console.log(tmp.spacePos);
if (minNode.spacePos+dimension < dimension*dimension){
var tmp = minNode.clone();
tmp.swap(tmp.spacePos, tmp.spacePos+dimension);
tmp.moves = moves;
tmp.manhattanFn(dimension);
if (tmp.manhattan == 0) return console.log(tmp.moves);
if (tmp.manhattan < minNode.manhattan)
pq.push(tmp);
}
if (Math.floor(minNode.spacePos/dimension) == Math.floor((minNode.spacePos+1)/dimension)){
var tmp = minNode.clone();
tmp.swap(tmp.spacePos, tmp.spacePos+1);
tmp.moves = moves;
tmp.manhattanFn(dimension);
if (tmp.manhattan == 0) return console.log(tmp.moves);
if (tmp.manhattan < minNode.manhattan)
pq.push(tmp);
}
if (Math.floor(minNode.spacePos/dimension) == Math.floor((minNode.spacePos-1)/dimension)){
var tmp = minNode.clone();
tmp.swap(tmp.spacePos, tmp.spacePos-1);
tmp.moves = moves;
tmp.manhattanFn(dimension);
if (tmp.manhattan == 0) return console.log(tmp.moves);
if (tmp.manhattan < minNode.manhattan)
pq.push(tmp);
}
//console.log(pq);
}
console.log('no wey');