@cubingcenter/scrambler 0.6.3 → 0.7.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 +2 -0
- 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.js +6 -2
- 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 +18 -0
- package/dist/puzzles/cube3/solver/phase1.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/phase1.js +132 -14
- package/dist/puzzles/cube3/solver/phase2.d.ts +47 -0
- package/dist/puzzles/cube3/solver/phase2.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/phase2.js +236 -66
- 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/validation.d.ts.map +1 -1
- package/dist/puzzles/cube3/validation.js +15 -7
- package/dist/puzzles/cube4/index.d.ts +3 -2
- package/dist/puzzles/cube4/index.d.ts.map +1 -1
- package/dist/puzzles/cube4/index.js +2 -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 +120 -11
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts +3 -0
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/browser-loader.js +34 -3
- package/dist/puzzles/cube4/reduction/center2.d.ts +20 -3
- package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/center2.js +53 -9
- 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/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 +38 -0
- package/dist/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.d.ts +50 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.js +202 -0
- package/dist/puzzles/cube4/reduction/node-loader.d.ts +5 -0
- package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/node-loader.js +48 -8
- package/dist/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts +111 -5
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/phase3-search.js +341 -22
- package/dist/puzzles/cube4/reduction/solve.d.ts +112 -1
- package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/solve.js +920 -181
- package/dist/puzzles/cube4/scrambler.d.ts +105 -4
- package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube4/scrambler.js +216 -166
- package/dist/puzzles/cube4/state.d.ts.map +1 -1
- package/dist/puzzles/cube4/state.js +4 -1
- 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/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-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 +6 -2
- 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 +133 -14
- package/dist-cjs/puzzles/cube3/solver/phase2.js +233 -63
- package/dist-cjs/puzzles/cube3/solver/symmetry.js +80 -0
- package/dist-cjs/puzzles/cube3/validation.js +15 -7
- package/dist-cjs/puzzles/cube4/index.js +3 -1
- package/dist-cjs/puzzles/cube4/moves.js +121 -11
- package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +34 -3
- package/dist-cjs/puzzles/cube4/reduction/center2.js +54 -9
- package/dist-cjs/puzzles/cube4/reduction/edge3.js +24 -3
- 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 +38 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/hc-pdb.js +213 -0
- package/dist-cjs/puzzles/cube4/reduction/node-loader.js +48 -8
- package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
- package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +343 -23
- package/dist-cjs/puzzles/cube4/reduction/solve.js +918 -173
- package/dist-cjs/puzzles/cube4/scrambler.js +214 -163
- package/dist-cjs/puzzles/cube4/state.js +4 -1
- package/dist-cjs/puzzles/pyraminx/solver/search.js +2 -5
- package/dist-cjs/puzzles/pyraminx/solver/tables.js +18 -1
- package/dist-cjs/puzzles/skewb/solver/search.js +2 -2
- package/dist-cjs/puzzles/skewb/solver/tables.js +18 -1
- package/package.json +14 -5
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"puzzle": "cube4",
|
|
4
|
+
"phase": "hc",
|
|
5
|
+
"moves": [
|
|
6
|
+
"U",
|
|
7
|
+
"U2",
|
|
8
|
+
"U'",
|
|
9
|
+
"R2",
|
|
10
|
+
"F",
|
|
11
|
+
"F2",
|
|
12
|
+
"F'",
|
|
13
|
+
"D",
|
|
14
|
+
"D2",
|
|
15
|
+
"D'",
|
|
16
|
+
"L2",
|
|
17
|
+
"B",
|
|
18
|
+
"B2",
|
|
19
|
+
"B'",
|
|
20
|
+
"Uw2",
|
|
21
|
+
"Rw2",
|
|
22
|
+
"Fw2"
|
|
23
|
+
],
|
|
24
|
+
"states": 2704156,
|
|
25
|
+
"reachableStates": 58800,
|
|
26
|
+
"reachableDense": 58800,
|
|
27
|
+
"maxDepth": 11,
|
|
28
|
+
"distances": {
|
|
29
|
+
"file": "hc-distances.bin",
|
|
30
|
+
"range": 2704156,
|
|
31
|
+
"checksum": "8720ec4a83eca33c3d56ae0ab8709c0b3d847c14d011b6dcc4413b28bd9dfa12"
|
|
32
|
+
},
|
|
33
|
+
"moveTable": {
|
|
34
|
+
"file": "hc-move.bin",
|
|
35
|
+
"range": 999600,
|
|
36
|
+
"checksum": "6bd1d8f36b77e0863425bced1dfb69df7a13dde4fb18ceeaeba00abf14519922"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Half-class exact PDB (Phase-3 center heuristic, Fase 1 pivot).
|
|
3
|
+
*
|
|
4
|
+
* PIVOT NOTE: the original Fase-1 spec (3 exact face-pair color PDBs,
|
|
5
|
+
* C(24,4)xC(20,4) = 51M states each) is unworkable — verified that outer
|
|
6
|
+
* face turns never move centers across faces (only wide doubles do), so
|
|
7
|
+
* the exact-color orbit under the 17 search moves holds ~70 states and
|
|
8
|
+
* the bound would read "unknown" almost everywhere. This table instead
|
|
9
|
+
* tracks the EXACT arrangement of half-class bits ((color/3)^1: 12 ones,
|
|
10
|
+
* 12 zeros), which moves under every search move:
|
|
11
|
+
*
|
|
12
|
+
* states = C(24,12) = 2,704,156, nibble-packed (~1.35 MB)
|
|
13
|
+
*
|
|
14
|
+
* Center3 (29,400 states) is a quotient of this coordinate (rank-7 pair
|
|
15
|
+
* + rl-index + parity), so this PDB dominates it by construction:
|
|
16
|
+
* bound = max(ct3, edge, hc). BFS from solved with the 17 search moves.
|
|
17
|
+
*/
|
|
18
|
+
export declare const HC_PDB_MOVES: readonly string[];
|
|
19
|
+
/** C(24,12) = 2,704,156. */
|
|
20
|
+
export declare const HC_PDB_STATES = 2704156;
|
|
21
|
+
/** C(24,12) rank of a 24-bit mask with popcount 12 (bit i = position i holds 1). */
|
|
22
|
+
export declare function hcRank(mask: number): number;
|
|
23
|
+
/** Inverse of hcRank: mask with popcount 12. */
|
|
24
|
+
export declare function hcUnrank(rank: number): number;
|
|
25
|
+
/** Encode center colors to the half-class coordinate. */
|
|
26
|
+
export declare function encodeHcPdb(centers: Uint8Array): number;
|
|
27
|
+
export declare function getHcPdbMoveMaps(): Int32Array;
|
|
28
|
+
/** Nibble-packed lookup (high nibble = odd index). */
|
|
29
|
+
export declare function hcPdbDistance(packed: Uint8Array, coordinate: number): number;
|
|
30
|
+
/**
|
|
31
|
+
* BFS from the solved half-class mask. Returns nibble-packed distances
|
|
32
|
+
* (0x0f = unreachable). ~2.7M states x 17 moves.
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateHcPdb(onProgress?: (done: number, total: number) => void): Uint8Array;
|
|
35
|
+
/** Number of reachable states (BFS orbit size). Fixed by the move set. */
|
|
36
|
+
export declare const HC_REACHABLE = 58800;
|
|
37
|
+
export interface HcDenseTables {
|
|
38
|
+
/** Full coordinate -> dense index, -1 if unreachable. */
|
|
39
|
+
index: Int32Array;
|
|
40
|
+
/** Dense moves: reachableCount x 17, dense indices. */
|
|
41
|
+
moves: Int32Array;
|
|
42
|
+
/** Dense distances (unpacked, 0x0f = unknown). */
|
|
43
|
+
distances: Uint8Array;
|
|
44
|
+
reachableCount: number;
|
|
45
|
+
}
|
|
46
|
+
/** Build the dense index + unpacked distances from nibble-packed BFS output. */
|
|
47
|
+
export declare function buildHcDense(packed: Uint8Array): HcDenseTables;
|
|
48
|
+
/** Dense transition table: for each reachable state and move, dense index (or -1). */
|
|
49
|
+
export declare function generateHcDenseMoves(dense: HcDenseTables): Int32Array;
|
|
50
|
+
//# sourceMappingURL=hc-pdb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hc-pdb.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/cube4/reduction/hc-pdb.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAA+B,CAAC;AAE1E,4BAA4B;AAC5B,eAAO,MAAM,aAAa,UAAU,CAAC;AAmBrC,oFAAoF;AACpF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU3C;AAED,gDAAgD;AAChD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc7C;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAMvD;AAoBD,wBAAgB,gBAAgB,IAAI,UAAU,CAG7C;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACjD,UAAU,CA+CZ;AAED,0EAA0E;AAC1E,eAAO,MAAM,YAAY,QAAQ,CAAC;AAElC,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,KAAK,EAAE,UAAU,CAAC;IAClB,uDAAuD;IACvD,KAAK,EAAE,UAAU,CAAC;IAClB,kDAAkD;IAClD,SAAS,EAAE,UAAU,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAY9D;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAiBrE"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Half-class exact PDB (Phase-3 center heuristic, Fase 1 pivot).
|
|
3
|
+
*
|
|
4
|
+
* PIVOT NOTE: the original Fase-1 spec (3 exact face-pair color PDBs,
|
|
5
|
+
* C(24,4)xC(20,4) = 51M states each) is unworkable — verified that outer
|
|
6
|
+
* face turns never move centers across faces (only wide doubles do), so
|
|
7
|
+
* the exact-color orbit under the 17 search moves holds ~70 states and
|
|
8
|
+
* the bound would read "unknown" almost everywhere. This table instead
|
|
9
|
+
* tracks the EXACT arrangement of half-class bits ((color/3)^1: 12 ones,
|
|
10
|
+
* 12 zeros), which moves under every search move:
|
|
11
|
+
*
|
|
12
|
+
* states = C(24,12) = 2,704,156, nibble-packed (~1.35 MB)
|
|
13
|
+
*
|
|
14
|
+
* Center3 (29,400 states) is a quotient of this coordinate (rank-7 pair
|
|
15
|
+
* + rl-index + parity), so this PDB dominates it by construction:
|
|
16
|
+
* bound = max(ct3, edge, hc). BFS from solved with the 17 search moves.
|
|
17
|
+
*/
|
|
18
|
+
import { CENTER3_MOVES } from "./center3.js";
|
|
19
|
+
import { FACE_MOVE_EFFECTS, parseMove } from "../moves.js";
|
|
20
|
+
export const HC_PDB_MOVES = CENTER3_MOVES.slice(0, 17);
|
|
21
|
+
/** C(24,12) = 2,704,156. */
|
|
22
|
+
export const HC_PDB_STATES = 2704156;
|
|
23
|
+
const CNK = (() => {
|
|
24
|
+
const table = [];
|
|
25
|
+
for (let n = 0; n <= 24; n++) {
|
|
26
|
+
table[n] = [];
|
|
27
|
+
for (let k = 0; k <= 12; k++) {
|
|
28
|
+
if (k === 0 || k === n)
|
|
29
|
+
table[n][k] = 1;
|
|
30
|
+
else if (k > n)
|
|
31
|
+
table[n][k] = 0;
|
|
32
|
+
else
|
|
33
|
+
table[n][k] = table[n - 1][k - 1] + table[n - 1][k];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return table;
|
|
37
|
+
})();
|
|
38
|
+
function halfClass(color) {
|
|
39
|
+
return (Math.floor(color / 3) ^ 1) & 1;
|
|
40
|
+
}
|
|
41
|
+
/** C(24,12) rank of a 24-bit mask with popcount 12 (bit i = position i holds 1). */
|
|
42
|
+
export function hcRank(mask) {
|
|
43
|
+
let rank = 0;
|
|
44
|
+
let k = 1;
|
|
45
|
+
for (let i = 0; i < 24; i++) {
|
|
46
|
+
if (mask & (1 << i)) {
|
|
47
|
+
rank += CNK[i][k];
|
|
48
|
+
k++;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return rank;
|
|
52
|
+
}
|
|
53
|
+
/** Inverse of hcRank: mask with popcount 12. */
|
|
54
|
+
export function hcUnrank(rank) {
|
|
55
|
+
let mask = 0;
|
|
56
|
+
let r = rank;
|
|
57
|
+
for (let k = 12; k >= 1; k--) {
|
|
58
|
+
for (let v = 23; v >= 0; v--) {
|
|
59
|
+
const c = CNK[v][k];
|
|
60
|
+
if (c <= r) {
|
|
61
|
+
mask |= 1 << v;
|
|
62
|
+
r -= c;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return mask;
|
|
68
|
+
}
|
|
69
|
+
/** Encode center colors to the half-class coordinate. */
|
|
70
|
+
export function encodeHcPdb(centers) {
|
|
71
|
+
let mask = 0;
|
|
72
|
+
for (let i = 0; i < 24; i++) {
|
|
73
|
+
if (halfClass(centers[i]) === 1)
|
|
74
|
+
mask |= 1 << i;
|
|
75
|
+
}
|
|
76
|
+
return hcRank(mask);
|
|
77
|
+
}
|
|
78
|
+
/** Position permutation maps for the 17 moves (next[i] = prev[map[i]]). */
|
|
79
|
+
function buildMovePositionMaps() {
|
|
80
|
+
const maps = new Int32Array(HC_PDB_MOVES.length * 24);
|
|
81
|
+
for (let m = 0; m < HC_PDB_MOVES.length; m++) {
|
|
82
|
+
const { face, turns } = parseMove(HC_PDB_MOVES[m]);
|
|
83
|
+
const effect = FACE_MOVE_EFFECTS[face];
|
|
84
|
+
let pos = Array.from({ length: 24 }, (_, i) => i);
|
|
85
|
+
for (let t = 0; t < turns; t++) {
|
|
86
|
+
const next = new Array(24);
|
|
87
|
+
for (let i = 0; i < 24; i++)
|
|
88
|
+
next[i] = pos[effect.ctperm[i]];
|
|
89
|
+
pos = next;
|
|
90
|
+
}
|
|
91
|
+
for (let i = 0; i < 24; i++)
|
|
92
|
+
maps[m * 24 + i] = pos[i];
|
|
93
|
+
}
|
|
94
|
+
return maps;
|
|
95
|
+
}
|
|
96
|
+
let cachedMoveMaps = null;
|
|
97
|
+
export function getHcPdbMoveMaps() {
|
|
98
|
+
if (!cachedMoveMaps)
|
|
99
|
+
cachedMoveMaps = buildMovePositionMaps();
|
|
100
|
+
return cachedMoveMaps;
|
|
101
|
+
}
|
|
102
|
+
/** Nibble-packed lookup (high nibble = odd index). */
|
|
103
|
+
export function hcPdbDistance(packed, coordinate) {
|
|
104
|
+
const byte = packed[coordinate >> 1];
|
|
105
|
+
return (coordinate & 1) === 0 ? byte & 0x0f : byte >> 4;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* BFS from the solved half-class mask. Returns nibble-packed distances
|
|
109
|
+
* (0x0f = unreachable). ~2.7M states x 17 moves.
|
|
110
|
+
*/
|
|
111
|
+
export function generateHcPdb(onProgress) {
|
|
112
|
+
const maps = getHcPdbMoveMaps();
|
|
113
|
+
const packed = new Uint8Array((HC_PDB_STATES + 1) >> 1).fill(0xff);
|
|
114
|
+
const get = (c) => {
|
|
115
|
+
const b = packed[c >> 1];
|
|
116
|
+
return (c & 1) === 0 ? b & 0x0f : b >> 4;
|
|
117
|
+
};
|
|
118
|
+
const set = (c, d) => {
|
|
119
|
+
const i = c >> 1;
|
|
120
|
+
if ((c & 1) === 0)
|
|
121
|
+
packed[i] = (packed[i] & 0xf0) | (d & 0x0f);
|
|
122
|
+
else
|
|
123
|
+
packed[i] = (packed[i] & 0x0f) | ((d & 0x0f) << 4);
|
|
124
|
+
};
|
|
125
|
+
// Solved mask: U/R/F faces hold half-class 1.
|
|
126
|
+
let solvedMask = 0;
|
|
127
|
+
for (const i of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
|
|
128
|
+
solvedMask |= 1 << i;
|
|
129
|
+
const solved = hcRank(solvedMask);
|
|
130
|
+
if (solved !== 0)
|
|
131
|
+
throw new Error(`solved rank != 0 (${solved})`);
|
|
132
|
+
const queue = new Int32Array(HC_PDB_STATES);
|
|
133
|
+
let head = 0;
|
|
134
|
+
let tail = 0;
|
|
135
|
+
set(0, 0);
|
|
136
|
+
queue[tail++] = 0;
|
|
137
|
+
while (head < tail) {
|
|
138
|
+
const coord = queue[head++];
|
|
139
|
+
const d = get(coord);
|
|
140
|
+
const nd = d + 1;
|
|
141
|
+
if (nd > 14)
|
|
142
|
+
continue; // nibble range; 0x0f stays "unknown" (admissible)
|
|
143
|
+
const mask = hcUnrank(coord);
|
|
144
|
+
for (let m = 0; m < HC_PDB_MOVES.length; m++) {
|
|
145
|
+
const base = m * 24;
|
|
146
|
+
let nmask = 0;
|
|
147
|
+
for (let i = 0; i < 24; i++) {
|
|
148
|
+
if (mask & (1 << maps[base + i]))
|
|
149
|
+
nmask |= 1 << i;
|
|
150
|
+
}
|
|
151
|
+
const next = hcRank(nmask);
|
|
152
|
+
if (get(next) === 0x0f) {
|
|
153
|
+
set(next, nd);
|
|
154
|
+
queue[tail++] = next;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (onProgress && (head & 0x7ffff) === 0)
|
|
158
|
+
onProgress(head, HC_PDB_STATES);
|
|
159
|
+
}
|
|
160
|
+
if (onProgress)
|
|
161
|
+
onProgress(tail, HC_PDB_STATES);
|
|
162
|
+
return packed;
|
|
163
|
+
}
|
|
164
|
+
/** Number of reachable states (BFS orbit size). Fixed by the move set. */
|
|
165
|
+
export const HC_REACHABLE = 58800;
|
|
166
|
+
/** Build the dense index + unpacked distances from nibble-packed BFS output. */
|
|
167
|
+
export function buildHcDense(packed) {
|
|
168
|
+
const index = new Int32Array(HC_PDB_STATES).fill(-1);
|
|
169
|
+
let count = 0;
|
|
170
|
+
for (let c = 0; c < HC_PDB_STATES; c++) {
|
|
171
|
+
if (hcPdbDistance(packed, c) !== 0x0f)
|
|
172
|
+
index[c] = count++;
|
|
173
|
+
}
|
|
174
|
+
const distances = new Uint8Array(count).fill(0x0f);
|
|
175
|
+
for (let c = 0; c < HC_PDB_STATES; c++) {
|
|
176
|
+
const di = index[c];
|
|
177
|
+
if (di >= 0)
|
|
178
|
+
distances[di] = hcPdbDistance(packed, c);
|
|
179
|
+
}
|
|
180
|
+
return { index, moves: new Int32Array(0), distances, reachableCount: count };
|
|
181
|
+
}
|
|
182
|
+
/** Dense transition table: for each reachable state and move, dense index (or -1). */
|
|
183
|
+
export function generateHcDenseMoves(dense) {
|
|
184
|
+
const maps = getHcPdbMoveMaps();
|
|
185
|
+
const moves = new Int32Array(dense.reachableCount * HC_PDB_MOVES.length).fill(-1);
|
|
186
|
+
for (let c = 0; c < HC_PDB_STATES; c++) {
|
|
187
|
+
const di = dense.index[c];
|
|
188
|
+
if (di < 0)
|
|
189
|
+
continue;
|
|
190
|
+
const mask = hcUnrank(c);
|
|
191
|
+
for (let m = 0; m < HC_PDB_MOVES.length; m++) {
|
|
192
|
+
const base = m * 24;
|
|
193
|
+
let nmask = 0;
|
|
194
|
+
for (let i = 0; i < 24; i++) {
|
|
195
|
+
if (mask & (1 << maps[base + i]))
|
|
196
|
+
nmask |= 1 << i;
|
|
197
|
+
}
|
|
198
|
+
moves[di * HC_PDB_MOVES.length + m] = dense.index[hcRank(nmask)];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return moves;
|
|
202
|
+
}
|
|
@@ -6,11 +6,16 @@ import type { Center1Tables } from "./center1.js";
|
|
|
6
6
|
import type { Center2Tables } from "./center2.js";
|
|
7
7
|
import type { Center3Tables } from "./center3.js";
|
|
8
8
|
import type { Edge3Tables } from "./edge3.js";
|
|
9
|
+
import { type HcDenseTables } from "./hc-pdb.js";
|
|
9
10
|
export interface Cube4ReductionTables {
|
|
10
11
|
center1: Center1Tables;
|
|
11
12
|
center2: Center2Tables;
|
|
12
13
|
center3: Center3Tables;
|
|
13
14
|
edge3: Edge3Tables;
|
|
15
|
+
/** Half-class exact PDB distances (optional; absent = bound disabled). */
|
|
16
|
+
hc?: HcDenseTables;
|
|
17
|
+
/** Joint Center3 x Single Pair PDB distances (optional). */
|
|
18
|
+
c3PairDist?: Uint8Array;
|
|
14
19
|
}
|
|
15
20
|
/** Load all cube4 reduction tables (throws if the generated assets are missing). */
|
|
16
21
|
export declare function loadCube4ReductionTables(): Cube4ReductionTables;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-loader.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/cube4/reduction/node-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"node-loader.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/cube4/reduction/node-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,0EAA0E;IAC1E,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AA2ID,oFAAoF;AACpF,wBAAgB,wBAAwB,IAAI,oBAAoB,CAgB/D"}
|
|
@@ -7,6 +7,7 @@ import { createRequire } from "node:module";
|
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { edge3DistanceLookup } from "./edge3.js";
|
|
10
|
+
import { buildHcDense } from "./hc-pdb.js";
|
|
10
11
|
const GENERATED_DIRECTORY = "puzzles/cube4/reduction/generated";
|
|
11
12
|
function resolveGeneratedAssetDirectory() {
|
|
12
13
|
const envDirectory = process.env.CUBINGCENTER_SCRAMBLER_TABLES_DIR;
|
|
@@ -59,17 +60,27 @@ function loadCenter1(assetDirectory) {
|
|
|
59
60
|
}
|
|
60
61
|
function loadCenter2(assetDirectory) {
|
|
61
62
|
const manifest = JSON.parse(readFileSync(path.join(assetDirectory, "center2-manifest.json"), "utf8"));
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
function unpackPruning(buffer) {
|
|
64
|
+
const pruning = new Uint8Array(450450);
|
|
65
|
+
for (let i = 0; i < 450450; i++) {
|
|
66
|
+
const byte = buffer[i >> 1];
|
|
67
|
+
pruning[i] = (i & 1) === 0 ? byte & 0x0f : byte >> 4;
|
|
68
|
+
}
|
|
69
|
+
return pruning;
|
|
67
70
|
}
|
|
68
|
-
|
|
71
|
+
const pruningBuffer = readChecked(path.join(assetDirectory, manifest.pruningTable.file), manifest.pruningTable.checksum);
|
|
72
|
+
const tables = {
|
|
69
73
|
ctMove: readInt32(readChecked(path.join(assetDirectory, manifest.ctMove.file), manifest.ctMove.checksum)),
|
|
70
74
|
rlMove: readInt32(readChecked(path.join(assetDirectory, manifest.rlMove.file), manifest.rlMove.checksum)),
|
|
71
|
-
pruning
|
|
75
|
+
pruning: unpackPruning(pruningBuffer)
|
|
72
76
|
};
|
|
77
|
+
// Tolerates older assets without the wide table (wide searches throw
|
|
78
|
+
// a clear error only when actually requested).
|
|
79
|
+
if (manifest.pruningWideTable) {
|
|
80
|
+
const wideBuffer = readChecked(path.join(assetDirectory, manifest.pruningWideTable.file), manifest.pruningWideTable.checksum);
|
|
81
|
+
tables.pruningWide = unpackPruning(wideBuffer);
|
|
82
|
+
}
|
|
83
|
+
return tables;
|
|
73
84
|
}
|
|
74
85
|
function loadCenter3(assetDirectory) {
|
|
75
86
|
const manifest = JSON.parse(readFileSync(path.join(assetDirectory, "center3-manifest.json"), "utf8"));
|
|
@@ -80,19 +91,48 @@ function loadCenter3(assetDirectory) {
|
|
|
80
91
|
}
|
|
81
92
|
function loadEdge3(assetDirectory) {
|
|
82
93
|
const manifest = JSON.parse(readFileSync(path.join(assetDirectory, "edge3-manifest.json"), "utf8"));
|
|
94
|
+
// Keep the nibble-packed distances as-is (15.5MB instead of 31MB): every
|
|
95
|
+
// reader (phase3 getPrun, solve.ts, edge3DistanceLookup) handles both
|
|
96
|
+
// formats, and the smaller working set halves edge-table DRAM traffic.
|
|
83
97
|
const distances = new Uint8Array(readChecked(path.join(assetDirectory, manifest.distances.file), manifest.distances.checksum));
|
|
84
98
|
return { distances, distanceOfEdge: edge3DistanceLookup(distances) };
|
|
85
99
|
}
|
|
100
|
+
function loadHc(assetDirectory) {
|
|
101
|
+
const manifestPath = path.join(assetDirectory, "hc-manifest.json");
|
|
102
|
+
if (!existsSync(manifestPath))
|
|
103
|
+
return undefined;
|
|
104
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
105
|
+
const packed = new Uint8Array(readChecked(path.join(assetDirectory, manifest.distances.file), manifest.distances.checksum));
|
|
106
|
+
const dense = buildHcDense(packed);
|
|
107
|
+
if (manifest.moveTable) {
|
|
108
|
+
const moveBuffer = readChecked(path.join(assetDirectory, manifest.moveTable.file), manifest.moveTable.checksum);
|
|
109
|
+
dense.moves = new Int32Array(moveBuffer.buffer.slice(moveBuffer.byteOffset, moveBuffer.byteOffset + moveBuffer.byteLength));
|
|
110
|
+
}
|
|
111
|
+
return dense;
|
|
112
|
+
}
|
|
113
|
+
function loadC3Pair(assetDirectory) {
|
|
114
|
+
const filePath = path.join(assetDirectory, "c3_pair_dist.bin");
|
|
115
|
+
if (!existsSync(filePath))
|
|
116
|
+
return undefined;
|
|
117
|
+
return new Uint8Array(readFileSync(filePath));
|
|
118
|
+
}
|
|
86
119
|
/** Load all cube4 reduction tables (throws if the generated assets are missing). */
|
|
87
120
|
export function loadCube4ReductionTables() {
|
|
88
121
|
const assetDirectory = resolveGeneratedAssetDirectory();
|
|
89
122
|
if (!existsSync(path.join(assetDirectory, "center1-manifest.json"))) {
|
|
90
123
|
throw new Error("Cube4 reduction tables not generated — run pnpm cube4:center1:tables etc.");
|
|
91
124
|
}
|
|
92
|
-
|
|
125
|
+
const tables = {
|
|
93
126
|
center1: loadCenter1(assetDirectory),
|
|
94
127
|
center2: loadCenter2(assetDirectory),
|
|
95
128
|
center3: loadCenter3(assetDirectory),
|
|
96
129
|
edge3: loadEdge3(assetDirectory)
|
|
97
130
|
};
|
|
131
|
+
const hc = loadHc(assetDirectory);
|
|
132
|
+
if (hc)
|
|
133
|
+
tables.hc = hc;
|
|
134
|
+
const c3Pair = loadC3Pair(assetDirectory);
|
|
135
|
+
if (c3Pair)
|
|
136
|
+
tables.c3PairDist = c3Pair;
|
|
137
|
+
return tables;
|
|
98
138
|
}
|
|
@@ -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,23 +19,128 @@ 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^21 = 2,097,152 entries (24 MB in RAM).
|
|
45
|
+
* NOTE: doubling to 4M was tried and reverted (-0.07% nodes on the
|
|
46
|
+
* corpus — the 2M working set already captures the hit locality). */
|
|
47
|
+
private static readonly TT_SIZE;
|
|
48
|
+
private static readonly TT_MASK;
|
|
49
|
+
private static readonly tt;
|
|
50
|
+
private static epoch;
|
|
51
|
+
/**
|
|
52
|
+
* Per-slot exact-length-call tag (8 MB transient). TT pruning stays
|
|
53
|
+
* epoch-scoped (unchanged traversal), but threshold proofs only trust
|
|
54
|
+
* same-call hits: a hit from another call may have validated under a
|
|
55
|
+
* different candidate, so it still prunes yet marks the proof dirty.
|
|
56
|
+
*/
|
|
57
|
+
private static readonly ttGen;
|
|
58
|
+
private static callSeq;
|
|
59
|
+
private callId;
|
|
60
|
+
/** Reset the per-attempt cumulative node counter. */
|
|
61
|
+
resetEpochNodes(): void;
|
|
62
|
+
static nextEpoch(): void;
|
|
63
|
+
/** Fresh per-call id for TT-generation tagging (epoch wrap resets it). */
|
|
64
|
+
private static nextCallId;
|
|
27
65
|
constructor();
|
|
66
|
+
private nodeCount;
|
|
67
|
+
/** Cumulative nodes across calls (reset per attempt via resetEpochNodes). */
|
|
68
|
+
epochNodes: number;
|
|
69
|
+
/**
|
|
70
|
+
* Proof bookkeeping for IDA* threshold propagation (reset per exact-length
|
|
71
|
+
* call). When a length-L search exhausts its tree WITHOUT hitting any of
|
|
72
|
+
* these flags, no (center, edge) solution exists at any length below
|
|
73
|
+
* `minExcess`, so the caller may skip straight to it:
|
|
74
|
+
* - `capped`: the node budget aborted the search (bounds unknown).
|
|
75
|
+
* - `limitHit`: goal enumeration hit its cap (tree not exhausted).
|
|
76
|
+
* - `sawGoal`: a goal was reached (even if the validator rejected it —
|
|
77
|
+
* a nearby length may still validate, so only step L+1).
|
|
78
|
+
* - `ttTouched`: a transposition-table hit from ANOTHER exact-length call
|
|
79
|
+
* skipped a subtree (same-call hits replay this call's own exhausted
|
|
80
|
+
* subtree and stay clean; other calls may validate under a different
|
|
81
|
+
* candidate, so their stored proof does not transfer).
|
|
82
|
+
* Bound-based axis skips need no flag: the skipped siblings are
|
|
83
|
+
* same-face turns, so noteExcess records their triangle-inequality bound.
|
|
84
|
+
*/
|
|
85
|
+
private capped;
|
|
86
|
+
private limitHit;
|
|
87
|
+
private sawGoal;
|
|
88
|
+
private ttTouched;
|
|
89
|
+
private minExcess;
|
|
28
90
|
private getPrun;
|
|
29
91
|
/**
|
|
30
|
-
* Recursive IDA* worker on table transitions.
|
|
92
|
+
* Recursive IDA* worker on table transitions with Transposition Table pruning.
|
|
93
|
+
*/
|
|
94
|
+
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;
|
|
95
|
+
/**
|
|
96
|
+
* Record an IDA* bound prune: the child at `depth + 1` needs at least
|
|
97
|
+
* `childBound` more moves, so no solution exists through this branch
|
|
98
|
+
* below root threshold `depth + 1 + childBound`. When a bound-based axis
|
|
99
|
+
* skip also fires, the skipped siblings are same-face turns (verified:
|
|
100
|
+
* every non-empty skipAxis3 run under m < 14 is a same-base triple),
|
|
101
|
+
* hence at most 1 legal move apart — their bound is at least
|
|
102
|
+
* `childBound - 1` by the triangle inequality on the exact PDBs, so the
|
|
103
|
+
* recorded excess `depth + childBound` stays a true lower bound.
|
|
104
|
+
*/
|
|
105
|
+
private noteExcess;
|
|
106
|
+
/**
|
|
107
|
+
* Search for a phase-3 solution with exact target length (first found).
|
|
108
|
+
*/
|
|
109
|
+
solveLength(edge: Uint8Array, ct3: number, edist: number, length3: number, center3Tables: Center3Tables, edge3Distances: Uint8Array, maxNodes?: number, hc?: HcDenseTables, hcCoord?: number, c3PairDist?: Uint8Array): Cube4Move[] | null;
|
|
110
|
+
/**
|
|
111
|
+
* Search for a phase-3 solution with exact target length, accepting the
|
|
112
|
+
* first goal sequence that passes `validate` (up to `limit` examined,
|
|
113
|
+
* sharing `maxNodes`). With a validator that enforces the downstream
|
|
114
|
+
* requirements (reduction + standard orientation + 3x3 conversion), hard
|
|
115
|
+
* states whose first-found solutions are unusable get more draws from
|
|
116
|
+
* the same budget instead of an immediate miss.
|
|
31
117
|
*/
|
|
32
|
-
|
|
118
|
+
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
119
|
/**
|
|
34
|
-
*
|
|
120
|
+
* Exact-length validated search that also reports what the call proved.
|
|
121
|
+
* `provenThrough` is the greatest length with provably no (center, edge)
|
|
122
|
+
* solution: set only when the tree was exhaustively explored with no goal
|
|
123
|
+
* reached, no node-cap abort, no TT hit, and complete excess info — the
|
|
124
|
+
* caller may then skip every shorter length for this candidate. Otherwise
|
|
125
|
+
* it is `length3 - 1` at most (only the attempted length is settled).
|
|
35
126
|
*/
|
|
36
|
-
|
|
127
|
+
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): {
|
|
128
|
+
moves: Cube4Move[] | null;
|
|
129
|
+
provenThrough: number;
|
|
130
|
+
nodesUsed: number;
|
|
131
|
+
};
|
|
37
132
|
}
|
|
133
|
+
/** Temporary instrumentation for proof-statistics (CUBE4_PROOF_STATS=1). */
|
|
134
|
+
export declare const proofStats: {
|
|
135
|
+
total: number;
|
|
136
|
+
capped: number;
|
|
137
|
+
limitHit: number;
|
|
138
|
+
sawGoal: number;
|
|
139
|
+
ttTouched: number;
|
|
140
|
+
clean: number;
|
|
141
|
+
jumpSum: number;
|
|
142
|
+
};
|
|
143
|
+
export declare function resetProofStats(): void;
|
|
38
144
|
/**
|
|
39
145
|
* Solve Phase 3 with iterative deepening on a single Phase3Start.
|
|
40
146
|
*/
|
|
@@ -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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"}
|