iddfs
Version:
iterative deepening depth-first search (IDDFS) for JavaScript
73 lines (67 loc) • 1.84 kB
JavaScript
// @flow
import assert from "assert";
import { describe, it } from "mocha";
import isEqual from "lodash/isEqual";
import iddfs from "../src/index";
type Node = string;
const swap = (str, from, to) => {
const min = Math.min(from, to);
const max = Math.max(from, to);
return (
str.substr(0, min) +
str[max] +
str.substring(min + 1, max) +
str[min] +
str.substr(max + 1)
);
};
describe("8 puzzle (with branch and bound)", async () => {
const edges = [
[ ],
[ ],
[ ],
[ ],
[ ],
[ ],
[ ],
[ ],
[ ]
];
const distances = [
[ ],
[ ],
[ ],
[ ],
[ ],
[ ],
[ ],
[ ],
[ ]
];
const goal: Node = "123456780";
const init: Node = "867254301";
const COST = 31;
// http://www.geocities.jp/m_hiroi/func/ocaml20.html
it("can solve with shortest cost", async () => {
const found = await iddfs({
initialNode: init,
isGoal: (node: Node) => isEqual(node, goal),
expand: (node: Node) => {
const emptyIndex = node.indexOf("0");
return edges[emptyIndex].map(moveIndex =>
swap(node, emptyIndex, moveIndex)
);
},
extractId: (node: Node) => node,
shouldContinue: (node: Node, depth: number, depthLimit: number) => {
let cost = 0;
for (let i = 0; i < node.length; i++) {
cost += distances[Number(node[i])][i];
}
return cost <= depthLimit - depth;
},
maxDepth: COST
});
assert.equal(found, goal);
}).timeout(30000); // Very slow in Node.js@4
});