This commit is contained in:
Daniel Ledda
2021-06-02 08:50:52 +02:00
parent 3d7df31097
commit e7b8ae6120
50 changed files with 4609 additions and 2272 deletions

View File

@@ -96,4 +96,18 @@ export default class SomaSolution {
clone.solutionSpaces = this.solutionSpaces.slice();
return clone;
}
getDims() {
return [this.dim, this.dim, this.dim];
}
forEachCell(cb: (val: number, x: number, y: number, z: number) => any) {
loopStart: for (let x = 0; x < this.dim; x++) {
for (let y = 0; y < this.dim; y++) {
for (let z = 0; z < this.dim; z++) {
cb(this.at(x, y, z), x, y, z);
}
}
}
}
}

View File

@@ -14,7 +14,7 @@ export default class SomaSolver {
this.solutionCube = new VoxelSpace(0, [dimension, dimension, dimension], Array(dimension**3).fill(0));
}
solve(polycubes: VoxelSpace[]) {
async solve(polycubes: VoxelSpace[]) {
if (polycubes.length === 0) {
throw new Error("You must pass at least one polycube to solve the puzzle.");
}
@@ -22,11 +22,15 @@ export default class SomaSolver {
if (cumulativeSize !== this.dim**3) {
throw new Error(`The polycubes passed do not add up to exactly enough units to form a cube of dimension ${this.dim}! Got: ${cumulativeSize}, need: ${this.dim**3}`);
}
const combosWithRots = polycubes.slice(1).map(polycube => polycube.getUniqueRotations().map(rot => rot.getAllPositionsInCube(this.dim)).flat());
this.solutions = [];
const combosWithRots = polycubes.slice(1).map(polycube => polycube.getUniqueRotations().map((rot: VoxelSpace) => rot.getAllPositionsInCube(this.dim)).flat());
const combos = [polycubes[0].getAllPositionsInCube(this.dim), ...combosWithRots];
this.backtrackSolve(this.solutionCube, combos, new SomaSolution(this.dim));
this.solutions = SomaSolution.filterUnique(this.solutions);
this.solutions.forEach(sol => sol.print());
}
getSolutions() {
return this.solutions.slice();
}
private backtrackSolve(workingSolution: VoxelSpace, polycubes: VoxelSpace[][], currentSoln: SomaSolution, depth = 0) {

View File

@@ -37,7 +37,7 @@ export default class VoxelSpace {
return this.space.toString(2);
}
private cullEmptySpace() {
getExtrema() {
const extrema = {
xMax: -Infinity,
xMin: Infinity,
@@ -46,7 +46,6 @@ export default class VoxelSpace {
zMax: -Infinity,
zMin: Infinity,
};
let newSpace = 0n;
this.forEachCell((val, x, y, z) => {
if (val) {
extrema.xMax = Math.max(extrema.xMax, x);
@@ -57,7 +56,13 @@ export default class VoxelSpace {
extrema.zMin = Math.min(extrema.zMin, z);
}
});
return extrema;
}
private cullEmptySpace() {
const extrema = this.getExtrema();
let index = 0n;
let newSpace = 0n;
for (let x = extrema.xMin; x <= extrema.xMax; x++) {
for (let y = extrema.yMin; y <= extrema.yMax; y++) {
for (let z = extrema.zMin; z <= extrema.zMax; z++) {

View File

@@ -1,10 +0,0 @@
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;

View File

@@ -1,109 +1,12 @@
import SomaSolver from "./SomaSolver";
import VoxelSpace from "./VoxelSpace";
const tetromino1 = new VoxelSpace(1, [3, 3, 3], [
true, true, true,
false, true, false,
false, false, false,
type SolveStartMessageData = {polycubes: bigint[], dims: number};
false, false, false,
false, false, false,
false, false, false,
self.addEventListener('message', (event) => {
const {polycubes, dims} = event.data as SolveStartMessageData;
const solver = new SomaSolver(event.data.dims);
solver.solve(polycubes.map((cubeRep, i) => new VoxelSpace(i, [dims, dims, dims], cubeRep)));
(self as unknown as Worker).postMessage(solver.getSolutions());
});
false, false, false,
false, false, false,
false, false, false,
], true);
const tetromino2 = new VoxelSpace(2, [3, 3, 3], [
false, false, false,
false, false, false,
false, true, false,
false, true, false,
false, true, false,
false, true, false,
false, false, false,
false, false, false,
false, false, false,
], true);
const tetromino3 = new VoxelSpace(3, [3, 3, 3], [
true, false, false,
true, true, false,
false, true, false,
false, false, false,
false, false, false,
false, false, false,
false, false, false,
false, false, false,
false, false, false,
], true);
const tetromino4 = new VoxelSpace(4, [3, 3, 3], [
true, true, false,
false, false, false,
false, false, false,
true, false, false,
true, false, false,
false, false, false,
false, false, false,
false, false, false,
false, false, false,
], true);
const tetromino5 = new VoxelSpace(5, [3, 3, 3], [
true, true, false,
false, false, false,
false, false, false,
false, true, false,
false, true, false,
false, false, false,
false, false, false,
false, false, false,
false, false, false,
], true);
const tetromino6 = new VoxelSpace(6, [3, 3, 3], [
false, false, false,
false, false, false,
false, true, false,
false, false, false,
false, true, false,
false, true, true,
false, false, false,
false, false, false,
false, false, false,
], true);
const triomino1 = new VoxelSpace(7, [3, 3, 3], [
false, false, false,
false, false, false,
false, true, false,
false, false, false,
false, true, false,
false, true, false,
false, false, false,
false, false, false,
false, false, false,
], true);
// const cube = new VoxelSpace([3, 3, 3], Array(3**3).fill(0));
// cube.plus(triomino1)?.plus(tetromino2, {x: 1, y: 0, z: 1})?.print();
const solver = new SomaSolver(3);
console.log("solving");
solver.solve([triomino1, tetromino2, tetromino3, tetromino1, tetromino4, tetromino5, tetromino6]);