🚀 improve clean layer
This commit is contained in:
59
packages/compute/cleanLayer-monobranch.ts
Normal file
59
packages/compute/cleanLayer-monobranch.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* clean layer is too expensive with solution branching
|
||||||
|
* do not branch for faster result ( at the cost of finding a minimal step number )
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { copyGrid, setColorEmpty } from "@snk/types/grid";
|
||||||
|
import { getHeadX, getHeadY } from "@snk/types/snake";
|
||||||
|
import { getAvailableRoutes } from "./getAvailableRoutes";
|
||||||
|
import type { Snake } from "@snk/types/snake";
|
||||||
|
import type { Grid } from "@snk/types/grid";
|
||||||
|
import type { Point } from "@snk/types/point";
|
||||||
|
|
||||||
|
export const getAvailableWhiteListedRoute = (
|
||||||
|
grid: Grid,
|
||||||
|
snake: Snake,
|
||||||
|
whiteList: Point[]
|
||||||
|
) => {
|
||||||
|
let solution: Snake[] | null;
|
||||||
|
|
||||||
|
getAvailableRoutes(grid, snake, (chain) => {
|
||||||
|
const hx = getHeadX(chain[0]);
|
||||||
|
const hy = getHeadY(chain[0]);
|
||||||
|
|
||||||
|
if (!whiteList.some(({ x, y }) => hx === x && hy === y)) return false;
|
||||||
|
|
||||||
|
solution = chain;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return solution;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
||||||
|
const chunk = chunk0.slice();
|
||||||
|
const grid = copyGrid(grid0);
|
||||||
|
let snake = snake0;
|
||||||
|
const chain: Snake[] = [];
|
||||||
|
|
||||||
|
while (chunk.length) {
|
||||||
|
const chainN = getAvailableWhiteListedRoute(grid, snake, chunk);
|
||||||
|
|
||||||
|
if (!chainN) throw new Error("some cells are unreachable");
|
||||||
|
|
||||||
|
chain.unshift(...chainN);
|
||||||
|
snake = chain[0];
|
||||||
|
|
||||||
|
const x = getHeadX(snake);
|
||||||
|
const y = getHeadY(snake);
|
||||||
|
|
||||||
|
setColorEmpty(grid, x, y);
|
||||||
|
|
||||||
|
const i = chunk.findIndex((c) => c.x === x && c.y === y);
|
||||||
|
chunk.splice(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chain;
|
||||||
|
};
|
||||||
@@ -30,28 +30,6 @@ const createGetHeuristic = (grid: Grid, chunk0: Point[]) => {
|
|||||||
return (chunk: any[]) => chunk.length * k;
|
return (chunk: any[]) => chunk.length * k;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAvailableWhiteListedRoutes = (
|
|
||||||
grid: Grid,
|
|
||||||
snake: Snake,
|
|
||||||
whiteList: Point[]
|
|
||||||
) => {
|
|
||||||
let solution: Snake[] | null;
|
|
||||||
|
|
||||||
getAvailableRoutes(grid, snake, (chain) => {
|
|
||||||
const hx = getHeadX(chain[0]);
|
|
||||||
const hy = getHeadY(chain[0]);
|
|
||||||
|
|
||||||
if (!whiteList.some(({ x, y }) => hx === x && hy === y)) return false;
|
|
||||||
|
|
||||||
solution = chain;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
return solution;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
||||||
const getH = createGetHeuristic(grid0, chunk0);
|
const getH = createGetHeuristic(grid0, chunk0);
|
||||||
|
|
||||||
@@ -74,9 +52,9 @@ export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
|||||||
|
|
||||||
if (o.chunk.length === 0) return unwrap(o).slice(0, -1);
|
if (o.chunk.length === 0) return unwrap(o).slice(0, -1);
|
||||||
|
|
||||||
const chain = getAvailableWhiteListedRoutes(o.grid, o.snake, o.chunk);
|
const chains = getAvailableWhiteListedRoutes(o.grid, o.snake, o.chunk);
|
||||||
|
|
||||||
if (chain) {
|
for (const chain of chains) {
|
||||||
const snake = chain[0];
|
const snake = chain[0];
|
||||||
const x = getHeadX(snake);
|
const x = getHeadX(snake);
|
||||||
const y = getHeadY(snake);
|
const y = getHeadY(snake);
|
||||||
@@ -101,32 +79,34 @@ export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new Error("some cells are unreachable");
|
||||||
};
|
};
|
||||||
|
|
||||||
// export const getAvailableWhiteListedRoutes = (
|
export const getAvailableWhiteListedRoutes = (
|
||||||
// grid: Grid,
|
grid: Grid,
|
||||||
// snake: Snake,
|
snake: Snake,
|
||||||
// whiteList0: Point[],
|
whiteList0: Point[],
|
||||||
// n = 3
|
n = 3
|
||||||
// ) => {
|
) => {
|
||||||
// const whiteList = whiteList0.slice();
|
const whiteList = whiteList0.slice();
|
||||||
// const solutions: Snake[][] = [];
|
const solutions: Snake[][] = [];
|
||||||
|
|
||||||
// getAvailableRoutes(grid, snake, (chain) => {
|
getAvailableRoutes(grid, snake, (chain) => {
|
||||||
// const hx = getHeadX(chain[0]);
|
const hx = getHeadX(chain[0]);
|
||||||
// const hy = getHeadY(chain[0]);
|
const hy = getHeadY(chain[0]);
|
||||||
|
|
||||||
// const i = whiteList.findIndex(({ x, y }) => hx === x && hy === y);
|
const i = whiteList.findIndex(({ x, y }) => hx === x && hy === y);
|
||||||
|
|
||||||
// if (i >= 0) {
|
if (i >= 0) {
|
||||||
// whiteList.splice(i, 1);
|
whiteList.splice(i, 1);
|
||||||
// solutions.push(chain);
|
solutions.push(chain);
|
||||||
|
|
||||||
// if (solutions.length >= n || whiteList.length === 0) return true;
|
if (solutions.length >= n || whiteList.length === 0) return true;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return false;
|
return false;
|
||||||
// });
|
});
|
||||||
|
|
||||||
// return solutions;
|
return solutions;
|
||||||
// };
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { copyGrid, isEmpty } from "@snk/types/grid";
|
import { copyGrid, isEmpty } from "@snk/types/grid";
|
||||||
import { pruneLayer } from "./pruneLayer";
|
import { pruneLayer } from "./pruneLayer";
|
||||||
import { cleanLayer } from "./cleanLayer";
|
import { cleanLayer } from "./cleanLayer-monobranch";
|
||||||
import type { Snake } from "@snk/types/snake";
|
import type { Snake } from "@snk/types/snake";
|
||||||
import type { Color, Grid } from "@snk/types/grid";
|
import type { Color, Grid } from "@snk/types/grid";
|
||||||
|
|
||||||
@@ -15,8 +15,7 @@ export const getBestRoute = (grid0: Grid, snake0: Snake) => {
|
|||||||
const gridN = copyGrid(grid);
|
const gridN = copyGrid(grid);
|
||||||
const chunk = pruneLayer(grid, color, snakeN);
|
const chunk = pruneLayer(grid, color, snakeN);
|
||||||
const c = cleanLayer(gridN, chain[0], chunk);
|
const c = cleanLayer(gridN, chain[0], chunk);
|
||||||
if (c) chain.unshift(...c);
|
chain.unshift(...c);
|
||||||
else throw new Error("some cells are unreachable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chain.reverse().slice(1);
|
return chain.reverse().slice(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user