@cubingcenter/scrambler 0.6.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/dist/core/api.d.ts.map +1 -1
- package/dist/core/api.js +10 -2
- package/dist/puzzles/cube2/solver/browser-loader.d.ts +4 -7
- package/dist/puzzles/cube2/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/browser-loader.js +42 -14
- package/dist/puzzles/cube2/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/generated-assets.js +8 -3
- package/dist/puzzles/cube2/solver/search.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/search.js +3 -3
- package/dist/puzzles/cube2/solver/tables.d.ts +6 -0
- package/dist/puzzles/cube2/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/tables.js +16 -2
- package/dist/puzzles/cube3/index.d.ts +1 -0
- package/dist/puzzles/cube3/index.d.ts.map +1 -1
- package/dist/puzzles/cube3/moves.d.ts.map +1 -1
- package/dist/puzzles/cube3/moves.js +104 -18
- package/dist/puzzles/cube3/scrambler.d.ts +16 -1
- package/dist/puzzles/cube3/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube3/scrambler.js +1 -1
- package/dist/puzzles/cube3/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/browser-loader.js +48 -22
- package/dist/puzzles/cube3/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/generated-assets.js +9 -3
- package/dist/puzzles/cube3/solver/index.d.ts +5 -3
- package/dist/puzzles/cube3/solver/index.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/index.js +2 -1
- package/dist/puzzles/cube3/solver/node-loader.js +9 -2
- package/dist/puzzles/cube3/solver/phase1.d.ts +37 -0
- package/dist/puzzles/cube3/solver/phase1.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/phase1.js +156 -15
- package/dist/puzzles/cube3/solver/phase2.d.ts +75 -0
- package/dist/puzzles/cube3/solver/phase2.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/phase2.js +279 -68
- package/dist/puzzles/cube3/solver/search-utils.d.ts +1 -1
- package/dist/puzzles/cube3/solver/search-utils.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/symmetry.d.ts +24 -0
- package/dist/puzzles/cube3/solver/symmetry.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/symmetry.js +74 -0
- package/dist/puzzles/cube3/solver/tables.d.ts +6 -1
- package/dist/puzzles/cube3/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/tables.js +14 -12
- package/dist/puzzles/cube3/validation.d.ts.map +1 -1
- package/dist/puzzles/cube3/validation.js +15 -7
- package/dist/puzzles/cube4/browser-worker-pool.d.ts +82 -0
- package/dist/puzzles/cube4/browser-worker-pool.d.ts.map +1 -0
- package/dist/puzzles/cube4/browser-worker-pool.js +205 -0
- package/dist/puzzles/cube4/browser-worker.d.ts +2 -0
- package/dist/puzzles/cube4/browser-worker.d.ts.map +1 -0
- package/dist/puzzles/cube4/browser-worker.js +31 -0
- package/dist/puzzles/cube4/index.d.ts +10 -2
- package/dist/puzzles/cube4/index.d.ts.map +1 -1
- package/dist/puzzles/cube4/index.js +6 -2
- package/dist/puzzles/cube4/moves.d.ts +5 -0
- package/dist/puzzles/cube4/moves.d.ts.map +1 -1
- package/dist/puzzles/cube4/moves.js +212 -11
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts +29 -1
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/browser-loader.js +227 -32
- package/dist/puzzles/cube4/reduction/center2.d.ts +44 -3
- package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/center2.js +152 -10
- package/dist/puzzles/cube4/reduction/edge3.d.ts +4 -0
- package/dist/puzzles/cube4/reduction/edge3.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/edge3.js +23 -3
- package/dist/puzzles/cube4/reduction/finish3.d.ts +53 -0
- package/dist/puzzles/cube4/reduction/finish3.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/finish3.js +393 -0
- package/dist/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
- package/dist/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/hc-manifest.json +44 -0
- package/dist/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.d.ts +52 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.js +220 -0
- package/dist/puzzles/cube4/reduction/node-loader.d.ts +15 -1
- package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/node-loader.js +199 -25
- package/dist/puzzles/cube4/reduction/pair-transversal.d.ts +28 -0
- package/dist/puzzles/cube4/reduction/pair-transversal.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/pair-transversal.js +107 -0
- package/dist/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts +116 -7
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/phase3-search.js +458 -32
- package/dist/puzzles/cube4/reduction/rotation-fix.d.ts +28 -0
- package/dist/puzzles/cube4/reduction/rotation-fix.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/rotation-fix.js +212 -0
- package/dist/puzzles/cube4/reduction/solve.d.ts +172 -2
- package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/solve.js +1201 -180
- package/dist/puzzles/cube4/scramble-cache.d.ts +93 -0
- package/dist/puzzles/cube4/scramble-cache.d.ts.map +1 -0
- package/dist/puzzles/cube4/scramble-cache.js +150 -0
- package/dist/puzzles/cube4/scrambler.d.ts +201 -6
- package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube4/scrambler.js +414 -176
- package/dist/puzzles/cube4/state.d.ts.map +1 -1
- package/dist/puzzles/cube4/state.js +4 -1
- package/dist/puzzles/cube4/worker-pool.d.ts +139 -0
- package/dist/puzzles/cube4/worker-pool.d.ts.map +1 -0
- package/dist/puzzles/cube4/worker-pool.js +405 -0
- package/dist/puzzles/cube4/worker-protocol.d.ts +58 -0
- package/dist/puzzles/cube4/worker-protocol.d.ts.map +1 -0
- package/dist/puzzles/cube4/worker-protocol.js +58 -0
- package/dist/puzzles/cube4/worker.d.ts +26 -0
- package/dist/puzzles/cube4/worker.d.ts.map +1 -0
- package/dist/puzzles/cube4/worker.js +49 -0
- package/dist/puzzles/pyraminx/solver/browser-loader.d.ts +4 -8
- package/dist/puzzles/pyraminx/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/browser-loader.js +44 -15
- package/dist/puzzles/pyraminx/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/generated-assets.js +8 -3
- package/dist/puzzles/pyraminx/solver/search.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/search.js +3 -6
- package/dist/puzzles/pyraminx/solver/tables.d.ts +6 -0
- package/dist/puzzles/pyraminx/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/tables.js +17 -0
- package/dist/puzzles/shared/compressed-fetch.d.ts +37 -1
- package/dist/puzzles/shared/compressed-fetch.d.ts.map +1 -1
- package/dist/puzzles/shared/compressed-fetch.js +226 -31
- package/dist/puzzles/shared/load-once.d.ts +16 -0
- package/dist/puzzles/shared/load-once.d.ts.map +1 -0
- package/dist/puzzles/shared/load-once.js +11 -0
- package/dist/puzzles/skewb/solver/browser-loader.d.ts +4 -11
- package/dist/puzzles/skewb/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/skewb/solver/browser-loader.js +44 -16
- package/dist/puzzles/skewb/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/skewb/solver/generated-assets.js +8 -3
- package/dist/puzzles/skewb/solver/search.js +3 -3
- package/dist/puzzles/skewb/solver/tables.d.ts +6 -0
- package/dist/puzzles/skewb/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/skewb/solver/tables.js +17 -0
- package/dist/puzzles/sq1/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/sq1/solver/browser-loader.js +58 -26
- package/dist-cjs/core/api.js +10 -2
- package/dist-cjs/puzzles/cube2/solver/browser-loader.js +42 -14
- package/dist-cjs/puzzles/cube2/solver/generated-assets.js +8 -3
- package/dist-cjs/puzzles/cube2/solver/search.js +2 -2
- package/dist-cjs/puzzles/cube2/solver/tables.js +17 -3
- package/dist-cjs/puzzles/cube3/moves.js +104 -18
- package/dist-cjs/puzzles/cube3/scrambler.js +1 -1
- package/dist-cjs/puzzles/cube3/solver/browser-loader.js +48 -22
- package/dist-cjs/puzzles/cube3/solver/generated-assets.js +9 -3
- package/dist-cjs/puzzles/cube3/solver/index.js +8 -1
- package/dist-cjs/puzzles/cube3/solver/node-loader.js +9 -2
- package/dist-cjs/puzzles/cube3/solver/phase1.js +157 -15
- package/dist-cjs/puzzles/cube3/solver/phase2.js +276 -65
- package/dist-cjs/puzzles/cube3/solver/symmetry.js +80 -0
- package/dist-cjs/puzzles/cube3/solver/tables.js +14 -12
- package/dist-cjs/puzzles/cube3/validation.js +15 -7
- package/dist-cjs/puzzles/cube4/browser-worker-pool.js +211 -0
- package/dist-cjs/puzzles/cube4/index.js +23 -1
- package/dist-cjs/puzzles/cube4/moves.js +213 -11
- package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +227 -32
- package/dist-cjs/puzzles/cube4/reduction/center2.js +155 -10
- package/dist-cjs/puzzles/cube4/reduction/edge3.js +24 -3
- package/dist-cjs/puzzles/cube4/reduction/finish3.js +398 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-manifest.json +44 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/hc-pdb.js +232 -0
- package/dist-cjs/puzzles/cube4/reduction/node-loader.js +200 -25
- package/dist-cjs/puzzles/cube4/reduction/pair-transversal.js +112 -0
- package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
- package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +460 -33
- package/dist-cjs/puzzles/cube4/reduction/rotation-fix.js +216 -0
- package/dist-cjs/puzzles/cube4/reduction/solve.js +1203 -172
- package/dist-cjs/puzzles/cube4/scramble-cache.js +156 -0
- package/dist-cjs/puzzles/cube4/scrambler.js +416 -174
- package/dist-cjs/puzzles/cube4/state.js +4 -1
- package/dist-cjs/puzzles/cube4/worker-pool.js +447 -0
- package/dist-cjs/puzzles/cube4/worker-protocol.js +62 -0
- package/dist-cjs/puzzles/pyraminx/solver/browser-loader.js +44 -15
- package/dist-cjs/puzzles/pyraminx/solver/generated-assets.js +8 -3
- package/dist-cjs/puzzles/pyraminx/solver/search.js +2 -5
- package/dist-cjs/puzzles/pyraminx/solver/tables.js +18 -1
- package/dist-cjs/puzzles/shared/compressed-fetch.js +229 -31
- package/dist-cjs/puzzles/shared/load-once.js +14 -0
- package/dist-cjs/puzzles/skewb/solver/browser-loader.js +44 -16
- package/dist-cjs/puzzles/skewb/solver/generated-assets.js +8 -3
- package/dist-cjs/puzzles/skewb/solver/search.js +2 -2
- package/dist-cjs/puzzles/skewb/solver/tables.js +18 -1
- package/dist-cjs/puzzles/sq1/solver/browser-loader.js +58 -26
- package/docs/development.md +19 -7
- package/package.json +17 -7
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase-2 wing-transversal pruning (two-pair PDB).
|
|
3
|
+
*
|
|
4
|
+
* A phase-2 goal is only usable when the wings are "transversal": every
|
|
5
|
+
* pair has exactly one wing in the second-half positions
|
|
6
|
+
* (`PAIRING_SECOND_HALVES`). Only ~0.1-0.25% of center goals pass, so the
|
|
7
|
+
* phase-2 search used to enumerate millions of center goals to find the
|
|
8
|
+
* transversal ones. This table bounds how many phase-2 moves two given pairs
|
|
9
|
+
* need to become transversal, so the search can prune branches that cannot
|
|
10
|
+
* end transversal within the remaining depth.
|
|
11
|
+
*
|
|
12
|
+
* State: the unordered positions of the two wings of pair X and of pair Y
|
|
13
|
+
* (276 × 276 index; overlapping positions are unreachable). The predicate
|
|
14
|
+
* only depends on positions, so ONE table serves every pair-of-pairs.
|
|
15
|
+
* Exact BFS distances under the given phase-2 move prefix (the search set),
|
|
16
|
+
* hence admissible; generated at runtime (76,176 bytes, a few ms).
|
|
17
|
+
*/
|
|
18
|
+
import { CENTER2_MOVES, getWingMoveMaps } from "./center2.js";
|
|
19
|
+
import { PAIRING_SECOND_HALVES } from "./pairing-coordinate.js";
|
|
20
|
+
export const PAIR_STATES = 276;
|
|
21
|
+
/** Unordered position pair (a != b) → 0..275, as a flat 24×24 table. */
|
|
22
|
+
export const PAIR_INDEX = (() => {
|
|
23
|
+
const index = new Uint16Array(24 * 24).fill(0xffff);
|
|
24
|
+
let k = 0;
|
|
25
|
+
for (let a = 0; a < 24; a++) {
|
|
26
|
+
for (let b = a + 1; b < 24; b++) {
|
|
27
|
+
index[a * 24 + b] = k;
|
|
28
|
+
index[b * 24 + a] = k;
|
|
29
|
+
k++;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return index;
|
|
33
|
+
})();
|
|
34
|
+
const PAIR_A = new Uint8Array(PAIR_STATES);
|
|
35
|
+
const PAIR_B = new Uint8Array(PAIR_STATES);
|
|
36
|
+
for (let a = 0; a < 24; a++) {
|
|
37
|
+
for (let b = a + 1; b < 24; b++) {
|
|
38
|
+
const k = PAIR_INDEX[a * 24 + b];
|
|
39
|
+
PAIR_A[k] = a;
|
|
40
|
+
PAIR_B[k] = b;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const IS_SECOND = new Uint8Array(24);
|
|
44
|
+
for (const p of PAIRING_SECOND_HALVES)
|
|
45
|
+
IS_SECOND[p] = 1;
|
|
46
|
+
/**
|
|
47
|
+
* Wing position maps: `posMove[m * 24 + p]` = where the wing at position p
|
|
48
|
+
* goes under CENTER2_MOVES[m] (inverse of the `wp` gather maps).
|
|
49
|
+
*/
|
|
50
|
+
export function getWingPositionMoves() {
|
|
51
|
+
if (cachedPosMove)
|
|
52
|
+
return cachedPosMove;
|
|
53
|
+
const gather = getWingMoveMaps();
|
|
54
|
+
const posMove = new Uint8Array(CENTER2_MOVES.length * 24);
|
|
55
|
+
for (let m = 0; m < CENTER2_MOVES.length; m++) {
|
|
56
|
+
for (let i = 0; i < 24; i++)
|
|
57
|
+
posMove[m * 24 + gather[m * 24 + i]] = i;
|
|
58
|
+
}
|
|
59
|
+
cachedPosMove = posMove;
|
|
60
|
+
return posMove;
|
|
61
|
+
}
|
|
62
|
+
let cachedPosMove;
|
|
63
|
+
const cache = new Map();
|
|
64
|
+
/** Two-pair transversal distances under the first `moveCount` CENTER2_MOVES. */
|
|
65
|
+
export function getTransversalPairPdb(moveCount) {
|
|
66
|
+
const hit = cache.get(moveCount);
|
|
67
|
+
if (hit)
|
|
68
|
+
return hit;
|
|
69
|
+
const posMove = getWingPositionMoves();
|
|
70
|
+
const n = PAIR_STATES * PAIR_STATES;
|
|
71
|
+
const dist = new Uint8Array(n).fill(0xff);
|
|
72
|
+
const queue = new Int32Array(n);
|
|
73
|
+
let tail = 0;
|
|
74
|
+
for (let x = 0; x < PAIR_STATES; x++) {
|
|
75
|
+
if (IS_SECOND[PAIR_A[x]] === IS_SECOND[PAIR_B[x]])
|
|
76
|
+
continue;
|
|
77
|
+
for (let y = 0; y < PAIR_STATES; y++) {
|
|
78
|
+
if (IS_SECOND[PAIR_A[y]] === IS_SECOND[PAIR_B[y]])
|
|
79
|
+
continue;
|
|
80
|
+
const ya = PAIR_A[y];
|
|
81
|
+
const yb = PAIR_B[y];
|
|
82
|
+
if (ya === PAIR_A[x] || ya === PAIR_B[x] || yb === PAIR_A[x] || yb === PAIR_B[x])
|
|
83
|
+
continue;
|
|
84
|
+
const s = x * PAIR_STATES + y;
|
|
85
|
+
dist[s] = 0;
|
|
86
|
+
queue[tail++] = s;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (let head = 0; head < tail; head++) {
|
|
90
|
+
const s = queue[head];
|
|
91
|
+
const x = (s / PAIR_STATES) | 0;
|
|
92
|
+
const y = s - x * PAIR_STATES;
|
|
93
|
+
const d = dist[s] + 1;
|
|
94
|
+
for (let m = 0; m < moveCount; m++) {
|
|
95
|
+
const row = m * 24;
|
|
96
|
+
const nx = PAIR_INDEX[posMove[row + PAIR_A[x]] * 24 + posMove[row + PAIR_B[x]]];
|
|
97
|
+
const ny = PAIR_INDEX[posMove[row + PAIR_A[y]] * 24 + posMove[row + PAIR_B[y]]];
|
|
98
|
+
const t = nx * PAIR_STATES + ny;
|
|
99
|
+
if (dist[t] === 0xff) {
|
|
100
|
+
dist[t] = d;
|
|
101
|
+
queue[tail++] = t;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
cache.set(moveCount, dist);
|
|
106
|
+
return dist;
|
|
107
|
+
}
|
|
@@ -103,12 +103,12 @@ export function applyPairingMoveToArray(arr24, move) {
|
|
|
103
103
|
* and preserved by the phase-3 move set (verified).
|
|
104
104
|
*/
|
|
105
105
|
export function hasPairingTransversal(wp) {
|
|
106
|
-
|
|
107
|
-
for (
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
106
|
+
let mask = 0;
|
|
107
|
+
for (let i = 0; i < 12; i++) {
|
|
108
|
+
const bit = 1 << (wp[PAIRING_SECOND_HALVES[i]] >> 1);
|
|
109
|
+
if ((mask & bit) !== 0)
|
|
110
110
|
return false;
|
|
111
|
-
|
|
111
|
+
mask |= bit;
|
|
112
112
|
}
|
|
113
113
|
return true;
|
|
114
114
|
}
|
|
@@ -8,6 +8,7 @@ import type { Cube4Move } from "../types.js";
|
|
|
8
8
|
import { type Center3Tables } from "./center3.js";
|
|
9
9
|
import { type Edge3Tables } from "./edge3.js";
|
|
10
10
|
import type { Phase3Start } from "./phase3.js";
|
|
11
|
+
import { type HcDenseTables } from "./hc-pdb.js";
|
|
11
12
|
/** The 17 exploration moves (the reference's m < 17 bound). */
|
|
12
13
|
export declare const SEARCH_MOVES: readonly Cube4Move[];
|
|
13
14
|
export declare const ckmv3: boolean[][];
|
|
@@ -18,25 +19,133 @@ export interface Phase3Result {
|
|
|
18
19
|
edge: Uint8Array;
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
+
* Goal enumeration control for the phase-3 search. The classic search
|
|
23
|
+
* returns the FIRST goal-reaching sequence, which for some states is
|
|
24
|
+
* systematically unusable downstream (e.g. uniform-but-nonstandard
|
|
25
|
+
* centers). With a validator, the search keeps enumerating goal sequences
|
|
26
|
+
* — within the same node budget — until one passes or `limit` goals have
|
|
27
|
+
* been examined.
|
|
22
28
|
*/
|
|
29
|
+
export interface Phase3SolutionValidator {
|
|
30
|
+
/** Max goal states to examine per call (bounds the extra cost). */
|
|
31
|
+
limit: number;
|
|
32
|
+
/** Goals examined so far (reset per call). */
|
|
33
|
+
examined: number;
|
|
34
|
+
/**
|
|
35
|
+
* Inspect a goal-reaching move sequence. Return true to accept it (stops
|
|
36
|
+
* the whole search); false keeps searching until `limit` goals examined.
|
|
37
|
+
*/
|
|
38
|
+
validate: (moves: Cube4Move[]) => boolean;
|
|
39
|
+
}
|
|
23
40
|
export declare class FastPhase3Solver {
|
|
24
41
|
private readonly tempep;
|
|
25
42
|
private readonly moveLog;
|
|
26
43
|
private readonly sym;
|
|
44
|
+
/** Transposition Table size: 2^20 = 1,048,576 entries (12 MiB per solve).
|
|
45
|
+
* The previous 2M table used 24 MiB per process, plus a separate 8 MiB
|
|
46
|
+
* generation array. The compact 1M table leaves room for concurrent
|
|
47
|
+
* solvers under the 150 MiB reduction-table budget. */
|
|
48
|
+
private static readonly TT_SIZE;
|
|
49
|
+
private static readonly TT_MASK;
|
|
50
|
+
private readonly tt;
|
|
51
|
+
private static readonly CALL_ID_LIMIT;
|
|
52
|
+
private callSeq;
|
|
53
|
+
private callId;
|
|
54
|
+
private contextCenter3;
|
|
55
|
+
private contextEdge3;
|
|
56
|
+
/** Reset this solver's cumulative node counter (legacy method name). */
|
|
57
|
+
resetEpochNodes(): void;
|
|
58
|
+
clearTranspositionTable(): void;
|
|
59
|
+
private setTableContext;
|
|
60
|
+
/** Fresh per-call id for TT-generation tagging. */
|
|
61
|
+
private nextCallId;
|
|
27
62
|
constructor();
|
|
28
|
-
private
|
|
63
|
+
private ensureDepth;
|
|
64
|
+
private nodeCount;
|
|
65
|
+
/** Cumulative nodes across calls (reset per solve generation). */
|
|
66
|
+
epochNodes: number;
|
|
67
|
+
/**
|
|
68
|
+
* Proof bookkeeping for IDA* threshold propagation (reset per exact-length
|
|
69
|
+
* call). When a length-L search exhausts its tree WITHOUT hitting any of
|
|
70
|
+
* these flags, no (center, edge) solution exists at any length below
|
|
71
|
+
* `minExcess`, so the caller may skip straight to it:
|
|
72
|
+
* - `capped`: the node budget aborted the search (bounds unknown).
|
|
73
|
+
* - `limitHit`: goal enumeration hit its cap (tree not exhausted).
|
|
74
|
+
* - `sawGoal`: a goal was reached (even if the validator rejected it —
|
|
75
|
+
* a nearby length may still validate, so only step L+1).
|
|
76
|
+
* - `ttTouched`: a transposition-table hit from ANOTHER exact-length call
|
|
77
|
+
* skipped a subtree, and the hit was not certified goal-free across
|
|
78
|
+
* candidate validators.
|
|
79
|
+
* Bound-based axis skips need no flag: the skipped siblings are
|
|
80
|
+
* same-face turns, so noteExcess records their triangle-inequality bound.
|
|
81
|
+
*/
|
|
82
|
+
private capped;
|
|
83
|
+
private limitHit;
|
|
84
|
+
private sawGoal;
|
|
85
|
+
private ttTouched;
|
|
86
|
+
private minExcess;
|
|
87
|
+
/**
|
|
88
|
+
* Root-length coverage of the tightest TT hit this call (depth +
|
|
89
|
+
* storedDepth): the pruned subtree proves no goal at or below that root
|
|
90
|
+
* length under the call's predicate. `Number.MAX_SAFE_INTEGER` when no hit
|
|
91
|
+
* pruned anything. Feeds `validatedThrough`.
|
|
92
|
+
*/
|
|
93
|
+
private ttCoverage;
|
|
94
|
+
/**
|
|
95
|
+
* Recursive IDA* worker on table transitions with Transposition Table pruning.
|
|
96
|
+
*/
|
|
97
|
+
search(eplast: Uint8Array, ct: number, prun: number, maxl: number, lm: number, depth: number, center3Tables: Center3Tables, edge3Distances: Uint8Array, maxNodes?: number, collect?: Phase3SolutionValidator, hc?: HcDenseTables, hcCoord?: number, c3PairDist?: Uint8Array): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Record an IDA* bound prune (inlined at the four gate sites): the child at
|
|
100
|
+
* `depth + 1` needs at least `childBound` more moves, so no solution exists
|
|
101
|
+
* through this branch below root threshold `depth + 1 + childBound`. When a
|
|
102
|
+
* bound-based axis skip also fires, the skipped siblings are same-face turns
|
|
103
|
+
* (verified: every non-empty skipAxis3 run under m < 14 is a same-base
|
|
104
|
+
* triple), hence at most 1 legal move apart — their bound is at least
|
|
105
|
+
* `childBound - 1` by the triangle inequality on the exact PDBs, so the
|
|
106
|
+
* recorded excess `depth + childBound` stays a true lower bound.
|
|
107
|
+
*/
|
|
108
|
+
/**
|
|
109
|
+
* Search for a phase-3 solution with exact target length (first found).
|
|
110
|
+
*/
|
|
111
|
+
solveLength(edge: Uint8Array, ct3: number, edist: number, length3: number, center3Tables: Center3Tables, edge3Distances: Uint8Array, maxNodes?: number, hc?: HcDenseTables, hcCoord?: number, c3PairDist?: Uint8Array): Cube4Move[] | null;
|
|
29
112
|
/**
|
|
30
|
-
*
|
|
113
|
+
* Search for a phase-3 solution with exact target length, accepting the
|
|
114
|
+
* first goal sequence that passes `validate` (up to `limit` examined,
|
|
115
|
+
* sharing `maxNodes`). With a validator that enforces the downstream
|
|
116
|
+
* requirements (reduction + standard orientation + 3x3 conversion), hard
|
|
117
|
+
* states whose first-found solutions are unusable get more draws from
|
|
118
|
+
* the same budget instead of an immediate miss.
|
|
31
119
|
*/
|
|
32
|
-
|
|
120
|
+
solveLengthValid(edge: Uint8Array, ct3: number, edist: number, length3: number, center3Tables: Center3Tables, edge3Distances: Uint8Array, maxNodes: number | undefined, limit: number | undefined, validate: (moves: Cube4Move[]) => boolean, hc?: HcDenseTables, hcCoord?: number, c3PairDist?: Uint8Array): Cube4Move[] | null;
|
|
33
121
|
/**
|
|
34
|
-
*
|
|
122
|
+
* Exact-length validated search that also reports what the call proved.
|
|
123
|
+
* `provenThrough` is the greatest length with provably no (center, edge)
|
|
124
|
+
* solution: set only when the tree was exhaustively explored with no goal
|
|
125
|
+
* reached, no node-cap abort, no TT hit, and complete excess info — the
|
|
126
|
+
* caller may then skip every shorter length for this candidate. Otherwise
|
|
127
|
+
* it is `length3 - 1` at most (only the attempted length is settled).
|
|
35
128
|
*/
|
|
36
|
-
|
|
129
|
+
solveLengthProven(edge: Uint8Array, ct3: number, edist: number, length3: number, center3Tables: Center3Tables, edge3Distances: Uint8Array, maxNodes: number | undefined, limit: number | undefined, validate: (moves: Cube4Move[]) => boolean, hc?: HcDenseTables, hcCoord?: number, c3PairDist?: Uint8Array): {
|
|
130
|
+
moves: Cube4Move[] | null;
|
|
131
|
+
provenThrough: number;
|
|
132
|
+
validatedThrough: number;
|
|
133
|
+
nodesUsed: number;
|
|
134
|
+
};
|
|
37
135
|
}
|
|
136
|
+
/** Temporary instrumentation for proof-statistics (CUBE4_PROOF_STATS=1). */
|
|
137
|
+
export declare const proofStats: {
|
|
138
|
+
total: number;
|
|
139
|
+
capped: number;
|
|
140
|
+
limitHit: number;
|
|
141
|
+
sawGoal: number;
|
|
142
|
+
ttTouched: number;
|
|
143
|
+
clean: number;
|
|
144
|
+
jumpSum: number;
|
|
145
|
+
};
|
|
146
|
+
export declare function resetProofStats(): void;
|
|
38
147
|
/**
|
|
39
148
|
* Solve Phase 3 with iterative deepening on a single Phase3Start.
|
|
40
149
|
*/
|
|
41
|
-
export declare function solvePhase3(start: Phase3Start, center3Tables: Center3Tables, edge3Tables: Edge3Tables, maxLength?: number): Promise<Phase3Result | null>;
|
|
150
|
+
export declare function solvePhase3(start: Phase3Start, center3Tables: Center3Tables, edge3Tables: Edge3Tables, maxLength?: number, maxNodes?: number): Promise<Phase3Result | null>;
|
|
42
151
|
//# sourceMappingURL=phase3-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phase3-search.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/cube4/reduction/phase3-search.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAIL,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/
|
|
1
|
+
{"version":3,"file":"phase3-search.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/cube4/reduction/phase3-search.ts"],"names":[],"mappings":"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"}
|