🚀 refactor algorithm
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
import { realistic as grid } from "@snk/types/__fixtures__/grid";
|
||||
import { snake3 } from "@snk/types/__fixtures__/snake";
|
||||
import { performance } from "perf_hooks";
|
||||
import { getAvailableRoutes } from "../getAvailableRoutes";
|
||||
import { getBestRoute } from "../getBestRoute";
|
||||
|
||||
{
|
||||
const m = 100;
|
||||
const s = performance.now();
|
||||
for (let k = m; k--; ) {
|
||||
const solutions = [];
|
||||
|
||||
getAvailableRoutes(grid, snake3, (snakes) => {
|
||||
solutions.push(snakes);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
console.log("getAvailableRoutes", (performance.now() - s) / m, "ms");
|
||||
}
|
||||
|
||||
{
|
||||
const m = 10;
|
||||
const s = performance.now();
|
||||
for (let k = m; k--; ) {
|
||||
getBestRoute(grid, snake3);
|
||||
}
|
||||
|
||||
console.log("getBestRoute", (performance.now() - s) / m, "ms");
|
||||
}
|
||||
@@ -1,21 +1,25 @@
|
||||
import { getBestRoute } from "../getBestRoute";
|
||||
import { Color, createEmptyGrid } from "@snk/types/grid";
|
||||
import { snake3 } from "@snk/types/__fixtures__/snake";
|
||||
import { randomlyFillGrid } from "@snk/types/randomlyFillGrid";
|
||||
import ParkMiller from "park-miller";
|
||||
import {
|
||||
getHeadX,
|
||||
getHeadY,
|
||||
Snake,
|
||||
snakeWillSelfCollide,
|
||||
} from "@snk/types/snake";
|
||||
import { createFromSeed } from "@snk/types/__fixtures__/createFromSeed";
|
||||
|
||||
const n = 1000;
|
||||
const width = 5;
|
||||
const height = 5;
|
||||
it(`should find solution for ${n} ${width}x${height} generated grids`, () => {
|
||||
const results = Array.from({ length: n }, (_, seed) => {
|
||||
const grid = createEmptyGrid(width, height);
|
||||
const pm = new ParkMiller(seed);
|
||||
const random = pm.integerInRange.bind(pm);
|
||||
randomlyFillGrid(grid, { colors: [1, 2] as Color[], emptyP: 2 }, random);
|
||||
const grid = createFromSeed(seed, width, height);
|
||||
|
||||
try {
|
||||
getBestRoute(grid, snake3);
|
||||
const chain = getBestRoute(grid, snake3);
|
||||
|
||||
assertValidPath(chain);
|
||||
|
||||
return { seed };
|
||||
} catch (error) {
|
||||
return { seed, error };
|
||||
@@ -24,3 +28,15 @@ it(`should find solution for ${n} ${width}x${height} generated grids`, () => {
|
||||
|
||||
expect(results.filter((x) => x.error)).toEqual([]);
|
||||
});
|
||||
|
||||
const assertValidPath = (chain: Snake[]) => {
|
||||
for (let i = 0; i < chain.length - 1; i++) {
|
||||
const dx = getHeadX(chain[i + 1]) - getHeadX(chain[i]);
|
||||
const dy = getHeadY(chain[i + 1]) - getHeadY(chain[i]);
|
||||
|
||||
if (!((Math.abs(dx) === 1 && dy == 0) || (Math.abs(dy) === 1 && dx == 0)))
|
||||
throw new Error(`unexpected direction ${dx},${dy}`);
|
||||
|
||||
if (snakeWillSelfCollide(chain[i], dx, dy)) throw new Error(`self collide`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ it("should find best route", () => {
|
||||
|
||||
const chain = getBestRoute(grid, createSnakeFromCells(snk0))!;
|
||||
|
||||
expect(snakeToCells(chain[0])[1]).toEqual({ x: 0, y: 0 });
|
||||
expect(snakeToCells(chain[1])[1]).toEqual({ x: 0, y: 0 });
|
||||
|
||||
expect(snakeToCells(chain[chain.length - 1])[0]).toEqual({ x: 3, y: 3 });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user