cubing 0.49.3 → 0.50.1
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/dist/lib/cubing/chunks/{chunk-YEGDNPFQ.js → chunk-ZKAZJKI6.js} +1 -1
- package/dist/lib/cubing/chunks/{inside-GXHIRWXB.js → inside-6OZRJVRY.js} +7 -5
- package/dist/lib/cubing/chunks/inside-6OZRJVRY.js.map +7 -0
- package/dist/lib/cubing/chunks/{search-dynamic-solve-4x4x4-SYFDLGU4.js → search-dynamic-solve-4x4x4-MAI2P7G4.js} +2 -2
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-MAI2P7G4.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-fto-UOKDYVD5.js +1405 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-fto-UOKDYVD5.js.map +7 -0
- package/dist/lib/cubing/chunks/search-worker-entry.js +1 -1
- package/dist/lib/cubing/chunks/{twsearch-XKCR3E3R.js → twsearch-MRZGOB6T.js} +38 -38
- package/dist/lib/cubing/chunks/{twsearch-XKCR3E3R.js.map → twsearch-MRZGOB6T.js.map} +2 -2
- package/dist/lib/cubing/chunks/twsearch_wasm_bg-V4F3SIUO-QGKWKUFY.js +15 -0
- package/dist/lib/cubing/chunks/twsearch_wasm_bg-V4F3SIUO-QGKWKUFY.js.map +7 -0
- package/dist/lib/cubing/scramble/index.js +1 -1
- package/dist/lib/cubing/search/index.js +1 -1
- package/package.json +1 -1
- package/dist/lib/cubing/chunks/inside-GXHIRWXB.js.map +0 -7
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-SYFDLGU4.js.map +0 -7
- package/dist/lib/cubing/chunks/search-dynamic-solve-fto-EY5ZVAGO.js +0 -1781
- package/dist/lib/cubing/chunks/search-dynamic-solve-fto-EY5ZVAGO.js.map +0 -7
- package/dist/lib/cubing/chunks/twsearch_wasm_bg-BXMNNHLU-USJMMACR.js +0 -15
- package/dist/lib/cubing/chunks/twsearch_wasm_bg-BXMNNHLU-USJMMACR.js.map +0 -7
- /package/dist/lib/cubing/chunks/{chunk-YEGDNPFQ.js.map → chunk-ZKAZJKI6.js.map} +0 -0
|
@@ -0,0 +1,1405 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Alg
|
|
3
|
+
} from "./chunk-EF6G34T7.js";
|
|
4
|
+
|
|
5
|
+
// src/cubing/vendor/mit/cs0x7f/fto/scramble_fto_standalone.js
|
|
6
|
+
import { randomUIntBelow } from "random-uint-below";
|
|
7
|
+
var DEBUG = false;
|
|
8
|
+
var mathlib = function() {
|
|
9
|
+
var fact = [1];
|
|
10
|
+
for (var i = 0; i < 32; ++i) {
|
|
11
|
+
fact[i + 1] = fact[i] * (i + 1);
|
|
12
|
+
}
|
|
13
|
+
function circle(arr) {
|
|
14
|
+
var length = arguments.length - 1, temp = arr[arguments[length]];
|
|
15
|
+
for (var i2 = length; i2 > 1; i2--) {
|
|
16
|
+
arr[arguments[i2]] = arr[arguments[i2 - 1]];
|
|
17
|
+
}
|
|
18
|
+
arr[arguments[1]] = temp;
|
|
19
|
+
return circle;
|
|
20
|
+
}
|
|
21
|
+
function getPruning(table, index) {
|
|
22
|
+
return table[index >> 3] >> ((index & 7) << 2) & 15;
|
|
23
|
+
}
|
|
24
|
+
function setNPerm(arr, idx, n, even) {
|
|
25
|
+
var prt = 0;
|
|
26
|
+
if (even < 0) {
|
|
27
|
+
idx <<= 1;
|
|
28
|
+
}
|
|
29
|
+
if (n >= 16) {
|
|
30
|
+
arr[n - 1] = 0;
|
|
31
|
+
for (var i2 = n - 2; i2 >= 0; i2--) {
|
|
32
|
+
arr[i2] = idx % (n - i2);
|
|
33
|
+
prt ^= arr[i2];
|
|
34
|
+
idx = ~~(idx / (n - i2));
|
|
35
|
+
for (var j = i2 + 1; j < n; j--) {
|
|
36
|
+
arr[j] >= arr[i2] && arr[j]++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (even < 0 && (prt & 1) != 0) {
|
|
40
|
+
var tmp = arr[n - 1];
|
|
41
|
+
arr[n - 1] = arr[n - 2];
|
|
42
|
+
arr[n - 2] = tmp;
|
|
43
|
+
}
|
|
44
|
+
return arr;
|
|
45
|
+
}
|
|
46
|
+
var vall = 1985229328;
|
|
47
|
+
var valh = 4275878552;
|
|
48
|
+
for (var i2 = 0; i2 < n - 1; i2++) {
|
|
49
|
+
var p = fact[n - 1 - i2];
|
|
50
|
+
var v = idx / p;
|
|
51
|
+
idx = idx % p;
|
|
52
|
+
prt ^= v;
|
|
53
|
+
v <<= 2;
|
|
54
|
+
if (v >= 32) {
|
|
55
|
+
v = v - 32;
|
|
56
|
+
arr[i2] = valh >> v & 15;
|
|
57
|
+
var m = (1 << v) - 1;
|
|
58
|
+
valh = (valh & m) + (valh >> 4 & ~m);
|
|
59
|
+
} else {
|
|
60
|
+
arr[i2] = vall >> v & 15;
|
|
61
|
+
var m = (1 << v) - 1;
|
|
62
|
+
vall = (vall & m) + (vall >>> 4 & ~m) + (valh << 28);
|
|
63
|
+
valh = valh >> 4;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (even < 0 && (prt & 1) != 0) {
|
|
67
|
+
arr[n - 1] = arr[n - 2];
|
|
68
|
+
arr[n - 2] = vall & 15;
|
|
69
|
+
} else {
|
|
70
|
+
arr[n - 1] = vall & 15;
|
|
71
|
+
}
|
|
72
|
+
return arr;
|
|
73
|
+
}
|
|
74
|
+
function getNPerm(arr, n, even) {
|
|
75
|
+
n = n || arr.length;
|
|
76
|
+
var idx = 0;
|
|
77
|
+
if (n >= 16) {
|
|
78
|
+
for (var i2 = 0; i2 < n - 1; i2++) {
|
|
79
|
+
idx *= n - i2;
|
|
80
|
+
for (var j = i2 + 1; j < n; j++) {
|
|
81
|
+
arr[j] < arr[i2] && idx++;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return even < 0 ? idx >> 1 : idx;
|
|
85
|
+
}
|
|
86
|
+
var vall = 1985229328;
|
|
87
|
+
var valh = 4275878552;
|
|
88
|
+
for (var i2 = 0; i2 < n - 1; i2++) {
|
|
89
|
+
var v = arr[i2] << 2;
|
|
90
|
+
idx *= n - i2;
|
|
91
|
+
if (v >= 32) {
|
|
92
|
+
idx += valh >> v - 32 & 15;
|
|
93
|
+
valh -= 286331152 << v - 32;
|
|
94
|
+
} else {
|
|
95
|
+
idx += vall >> v & 15;
|
|
96
|
+
valh -= 286331153;
|
|
97
|
+
vall -= 286331152 << v;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return even < 0 ? idx >> 1 : idx;
|
|
101
|
+
}
|
|
102
|
+
function getNParity(idx, n) {
|
|
103
|
+
var i2, p;
|
|
104
|
+
p = 0;
|
|
105
|
+
for (i2 = n - 2; i2 >= 0; --i2) {
|
|
106
|
+
p ^= idx % (n - i2);
|
|
107
|
+
idx = ~~(idx / (n - i2));
|
|
108
|
+
}
|
|
109
|
+
return p & 1;
|
|
110
|
+
}
|
|
111
|
+
function getNOri(arr, n, evenbase) {
|
|
112
|
+
var base = Math.abs(evenbase);
|
|
113
|
+
var idx = evenbase < 0 ? 0 : arr[0] % base;
|
|
114
|
+
for (var i2 = n - 1; i2 > 0; i2--) {
|
|
115
|
+
idx = idx * base + arr[i2] % base;
|
|
116
|
+
}
|
|
117
|
+
return idx;
|
|
118
|
+
}
|
|
119
|
+
function setNOri(arr, idx, n, evenbase) {
|
|
120
|
+
var base = Math.abs(evenbase);
|
|
121
|
+
var parity = base * n;
|
|
122
|
+
for (var i2 = 1; i2 < n; i2++) {
|
|
123
|
+
arr[i2] = idx % base;
|
|
124
|
+
parity -= arr[i2];
|
|
125
|
+
idx = ~~(idx / base);
|
|
126
|
+
}
|
|
127
|
+
arr[0] = (evenbase < 0 ? parity : idx) % base;
|
|
128
|
+
return arr;
|
|
129
|
+
}
|
|
130
|
+
function bitCount(x) {
|
|
131
|
+
x -= x >> 1 & 1431655765;
|
|
132
|
+
x = (x & 858993459) + (x >> 2 & 858993459);
|
|
133
|
+
return (x + (x >> 4) & 252645135) * 16843009 >> 24;
|
|
134
|
+
}
|
|
135
|
+
function getMPerm(arr, n, cnts, cums) {
|
|
136
|
+
var seen = ~0;
|
|
137
|
+
var idx = 0;
|
|
138
|
+
var x = 1;
|
|
139
|
+
for (var i2 = 0; i2 < n; i2++) {
|
|
140
|
+
var pi = arr[i2];
|
|
141
|
+
idx = idx * (n - i2) + bitCount(seen & (1 << cums[pi]) - 1) * x;
|
|
142
|
+
x = x * cnts[pi]--;
|
|
143
|
+
seen &= ~(1 << cums[pi] + cnts[pi]);
|
|
144
|
+
}
|
|
145
|
+
return Math.round(idx / x);
|
|
146
|
+
}
|
|
147
|
+
function setMPerm(arr, idx, n, cnts, x) {
|
|
148
|
+
for (var i2 = 0; i2 < n; i2++) {
|
|
149
|
+
for (var j = 0; j < cnts.length; j++) {
|
|
150
|
+
if (cnts[j] == 0) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
var x2 = ~~(x * cnts[j] / (n - i2));
|
|
154
|
+
if (idx < x2) {
|
|
155
|
+
cnts[j]--;
|
|
156
|
+
arr[i2] = j;
|
|
157
|
+
x = x2;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
idx -= x2;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return arr;
|
|
164
|
+
}
|
|
165
|
+
function Coord(type, length, evenbase) {
|
|
166
|
+
this.length = length;
|
|
167
|
+
this.evenbase = evenbase;
|
|
168
|
+
if (type == "p") {
|
|
169
|
+
this.get = function(arr) {
|
|
170
|
+
return getNPerm(arr, this.length, this.evenbase);
|
|
171
|
+
};
|
|
172
|
+
this.set = function(arr, idx) {
|
|
173
|
+
return setNPerm(arr, idx, this.length, this.evenbase);
|
|
174
|
+
};
|
|
175
|
+
} else if (type == "o") {
|
|
176
|
+
this.get = function(arr) {
|
|
177
|
+
return getNOri(arr, this.length, this.evenbase);
|
|
178
|
+
};
|
|
179
|
+
this.set = function(arr, idx) {
|
|
180
|
+
return setNOri(arr, idx, this.length, this.evenbase);
|
|
181
|
+
};
|
|
182
|
+
} else if (type == "c") {
|
|
183
|
+
var cnts = evenbase;
|
|
184
|
+
this.cnts = cnts.slice();
|
|
185
|
+
this.cntn = this.cnts.length;
|
|
186
|
+
this.cums = [0];
|
|
187
|
+
for (var i2 = 1; i2 <= this.cntn; i2++) {
|
|
188
|
+
this.cums[i2] = this.cums[i2 - 1] + cnts[i2 - 1];
|
|
189
|
+
}
|
|
190
|
+
this.n = this.cums[this.cntn];
|
|
191
|
+
var n = this.n;
|
|
192
|
+
var x = 1;
|
|
193
|
+
for (var i2 = 0; i2 < this.cntn; i2++) {
|
|
194
|
+
for (var j = 1; j <= cnts[i2]; j++, n--) {
|
|
195
|
+
x *= n / j;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
this.x = Math.round(x);
|
|
199
|
+
this.get = function(arr) {
|
|
200
|
+
return getMPerm(arr, this.n, this.cnts.slice(), this.cums);
|
|
201
|
+
};
|
|
202
|
+
this.set = function(arr, idx) {
|
|
203
|
+
return setMPerm(arr, idx, this.n, this.cnts.slice(), this.x);
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
debugger;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function fillFacelet(facelets, f, perm, ori, divcol) {
|
|
210
|
+
for (var i2 = 0; i2 < facelets.length; i2++) {
|
|
211
|
+
var cubie = facelets[i2];
|
|
212
|
+
var p = perm[i2] === void 0 ? i2 : perm[i2];
|
|
213
|
+
if (typeof cubie == "number") {
|
|
214
|
+
f[cubie] = ~~(facelets[p] / divcol);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
var o = ori[i2] || 0;
|
|
218
|
+
for (var j = 0; j < cubie.length; j++) {
|
|
219
|
+
f[cubie[(j + o) % cubie.length]] = ~~(facelets[p][j] / divcol);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function detectFacelet(facelets, f, perm, ori, divcol) {
|
|
224
|
+
for (var i2 = 0; i2 < facelets.length; i2++) {
|
|
225
|
+
var n_ori = facelets[i2].length;
|
|
226
|
+
outer_loop: for (var j = 0; j < facelets.length + 1; j++) {
|
|
227
|
+
if (j == facelets.length) {
|
|
228
|
+
return -1;
|
|
229
|
+
} else if (facelets[j].length != n_ori) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
for (var o = 0; o < n_ori; o++) {
|
|
233
|
+
var isMatch = true;
|
|
234
|
+
for (var t = 0; t < n_ori; t++) {
|
|
235
|
+
if (~~(facelets[j][t] / divcol) != f[facelets[i2][(t + o) % n_ori]]) {
|
|
236
|
+
isMatch = false;
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (isMatch) {
|
|
241
|
+
perm[i2] = j;
|
|
242
|
+
ori[i2] = o;
|
|
243
|
+
break outer_loop;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
function createMoveHash(initState, validMoves, hashFunc, moveFunc) {
|
|
251
|
+
var states = [initState];
|
|
252
|
+
var hash2idx = {};
|
|
253
|
+
var depthEnds = [];
|
|
254
|
+
hash2idx[hashFunc(initState)] = 0;
|
|
255
|
+
depthEnds[0] = 1;
|
|
256
|
+
var moveTable = [];
|
|
257
|
+
for (var m = 0; m < validMoves.length; m++) {
|
|
258
|
+
moveTable[m] = [];
|
|
259
|
+
}
|
|
260
|
+
var tt = +/* @__PURE__ */ new Date();
|
|
261
|
+
for (var i2 = 0; i2 < states.length; i2++) {
|
|
262
|
+
if (i2 == depthEnds[depthEnds.length - 1]) {
|
|
263
|
+
depthEnds.push(states.length);
|
|
264
|
+
}
|
|
265
|
+
if (i2 % 1e4 == 9999) {
|
|
266
|
+
DEBUG && console.log(i2, "states scanned, tt=", +/* @__PURE__ */ new Date() - tt);
|
|
267
|
+
}
|
|
268
|
+
var curState = states[i2];
|
|
269
|
+
for (var m = 0; m < validMoves.length; m++) {
|
|
270
|
+
var newState = moveFunc(curState, validMoves[m]);
|
|
271
|
+
if (!newState) {
|
|
272
|
+
moveTable[m][i2] = -1;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
var newHash = hashFunc(newState);
|
|
276
|
+
if (!(newHash in hash2idx)) {
|
|
277
|
+
hash2idx[newHash] = states.length;
|
|
278
|
+
states.push(newState);
|
|
279
|
+
}
|
|
280
|
+
moveTable[m][i2] = hash2idx[newHash];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
DEBUG && console.log("[move hash] " + states.length + " states generated, tt=", +/* @__PURE__ */ new Date() - tt, JSON.stringify(depthEnds));
|
|
284
|
+
return [moveTable, hash2idx];
|
|
285
|
+
}
|
|
286
|
+
function createPrun(prun, init, size, maxd, doMove, N_MOVES, N_POWER, N_INV) {
|
|
287
|
+
var isMoveTable = Array.isArray(doMove);
|
|
288
|
+
N_MOVES = N_MOVES || 6;
|
|
289
|
+
N_POWER = N_POWER || 3;
|
|
290
|
+
N_INV = N_INV || 256;
|
|
291
|
+
maxd = maxd || 256;
|
|
292
|
+
for (var i2 = 0, len = size + 7 >>> 3; i2 < len; i2++) {
|
|
293
|
+
prun[i2] = -1;
|
|
294
|
+
}
|
|
295
|
+
if (!Array.isArray(init)) {
|
|
296
|
+
init = [init];
|
|
297
|
+
}
|
|
298
|
+
for (var i2 = 0; i2 < init.length; i2++) {
|
|
299
|
+
prun[init[i2] >> 3] ^= 15 << ((init[i2] & 7) << 2);
|
|
300
|
+
}
|
|
301
|
+
var val = 0;
|
|
302
|
+
for (var l = 0; l <= maxd; l++) {
|
|
303
|
+
var done = 0;
|
|
304
|
+
var inv = l >= N_INV;
|
|
305
|
+
var fill = l + 1 ^ 15;
|
|
306
|
+
var find = inv ? 15 : l;
|
|
307
|
+
var check = inv ? l : 15;
|
|
308
|
+
outer_loop: for (var p = 0; p < size; p++, val >>= 4) {
|
|
309
|
+
if ((p & 7) == 0) {
|
|
310
|
+
val = prun[p >> 3];
|
|
311
|
+
if (!inv && val == -1) {
|
|
312
|
+
p += 7;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if ((val & 15) != find) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
for (var m = 0; m < N_MOVES; m++) {
|
|
320
|
+
var q = p;
|
|
321
|
+
for (var c = 0; c < N_POWER; c++) {
|
|
322
|
+
q = isMoveTable ? doMove[m][q] : doMove(q, m);
|
|
323
|
+
if (q < 0) {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
if (getPruning(prun, q) != check) {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
++done;
|
|
330
|
+
if (inv) {
|
|
331
|
+
prun[p >> 3] ^= fill << ((p & 7) << 2);
|
|
332
|
+
continue outer_loop;
|
|
333
|
+
}
|
|
334
|
+
prun[q >> 3] ^= fill << ((q & 7) << 2);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (done == 0) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
DEBUG && console.log("[prun]", done);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function Searcher(isSolved, getPrun, doMove, N_AXIS, N_POWER, ckmv) {
|
|
345
|
+
this.isSolved = isSolved || function() {
|
|
346
|
+
return true;
|
|
347
|
+
};
|
|
348
|
+
this.getPrun = getPrun;
|
|
349
|
+
this.doMove = doMove;
|
|
350
|
+
this.N_AXIS = N_AXIS;
|
|
351
|
+
this.N_POWER = N_POWER;
|
|
352
|
+
this.ckmv = ckmv || valuedArray(N_AXIS, function(i2) {
|
|
353
|
+
return 1 << i2;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
var _ = Searcher.prototype;
|
|
357
|
+
_.solve = function(idx, minl, MAXL, callback) {
|
|
358
|
+
var sols = this.solveMulti([idx], minl, MAXL, callback);
|
|
359
|
+
return sols == null ? null : sols[0];
|
|
360
|
+
};
|
|
361
|
+
_.solveMulti = function(idxs, minl, MAXL, callback) {
|
|
362
|
+
this.callback = callback || function() {
|
|
363
|
+
return true;
|
|
364
|
+
};
|
|
365
|
+
var sol = [];
|
|
366
|
+
outer_loop: for (var l = minl; l <= MAXL; l++) {
|
|
367
|
+
for (var s = 0; s < idxs.length; s++) {
|
|
368
|
+
this.sidx = s;
|
|
369
|
+
if (this.idaSearch(idxs[s], l, -1, sol) == 0) {
|
|
370
|
+
break outer_loop;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
this.sidx = -1;
|
|
374
|
+
}
|
|
375
|
+
return this.sidx == -1 ? null : [sol, this.sidx];
|
|
376
|
+
};
|
|
377
|
+
_.idaSearch = function(idx, maxl, lm, sol) {
|
|
378
|
+
var prun = this.getPrun(idx);
|
|
379
|
+
if (prun > maxl) {
|
|
380
|
+
return prun > maxl + 1 ? 2 : 1;
|
|
381
|
+
}
|
|
382
|
+
if (maxl == 0) {
|
|
383
|
+
return this.isSolved(idx) && this.callback(sol, this.sidx) ? 0 : 1;
|
|
384
|
+
}
|
|
385
|
+
if (prun == 0 && this.isSolved(idx) && maxl == 1) {
|
|
386
|
+
return 1;
|
|
387
|
+
}
|
|
388
|
+
for (var axis = 0; axis < this.N_AXIS; axis++) {
|
|
389
|
+
if (this.ckmv[lm] >> axis & 1) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
var idx1 = Array.isArray(idx) ? idx.slice() : idx;
|
|
393
|
+
for (var pow = 0; pow < this.N_POWER; pow++) {
|
|
394
|
+
idx1 = this.doMove(idx1, axis);
|
|
395
|
+
if (idx1 == null) {
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
sol.push([axis, pow]);
|
|
399
|
+
var ret = this.idaSearch(idx1, maxl - 1, axis, sol);
|
|
400
|
+
if (ret == 0) {
|
|
401
|
+
return 0;
|
|
402
|
+
}
|
|
403
|
+
sol.pop();
|
|
404
|
+
if (ret == 2) {
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return 1;
|
|
410
|
+
};
|
|
411
|
+
function rn(n) {
|
|
412
|
+
return randomUIntBelow(n);
|
|
413
|
+
}
|
|
414
|
+
function rndPerm(n, isEven) {
|
|
415
|
+
var p = 0;
|
|
416
|
+
var arr = [];
|
|
417
|
+
for (var i2 = 0; i2 < n; i2++) {
|
|
418
|
+
arr[i2] = i2;
|
|
419
|
+
}
|
|
420
|
+
for (var i2 = 0; i2 < n - 1; i2++) {
|
|
421
|
+
var k = rn(n - i2);
|
|
422
|
+
circle(arr, i2, i2 + k);
|
|
423
|
+
p ^= k != 0;
|
|
424
|
+
}
|
|
425
|
+
if (isEven && p) {
|
|
426
|
+
circle(arr, 0, 1);
|
|
427
|
+
}
|
|
428
|
+
return arr;
|
|
429
|
+
}
|
|
430
|
+
function valuedArray(len, val) {
|
|
431
|
+
var ret = [];
|
|
432
|
+
var isFun = typeof val == "function";
|
|
433
|
+
for (var i2 = 0; i2 < len; i2++) {
|
|
434
|
+
ret[i2] = isFun ? val(i2) : val;
|
|
435
|
+
}
|
|
436
|
+
return ret;
|
|
437
|
+
}
|
|
438
|
+
function permOriMult(p1, p2, prod, o1, o2, ori, oriMod) {
|
|
439
|
+
for (var i2 = 0; i2 < p2.length; i2++) {
|
|
440
|
+
if (oriMod) {
|
|
441
|
+
ori[i2] = (o1[p2[i2]] + o2[i2]) % oriMod;
|
|
442
|
+
}
|
|
443
|
+
prod[i2] = p1[p2[i2]];
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
bitCount,
|
|
448
|
+
getPruning,
|
|
449
|
+
setNOri,
|
|
450
|
+
getNOri,
|
|
451
|
+
getNPerm,
|
|
452
|
+
getNParity,
|
|
453
|
+
Coord,
|
|
454
|
+
createMoveHash,
|
|
455
|
+
createPrun,
|
|
456
|
+
fillFacelet,
|
|
457
|
+
detectFacelet,
|
|
458
|
+
rn,
|
|
459
|
+
valuedArray,
|
|
460
|
+
Searcher,
|
|
461
|
+
rndPerm,
|
|
462
|
+
permOriMult
|
|
463
|
+
};
|
|
464
|
+
}();
|
|
465
|
+
var ftosolver = function() {
|
|
466
|
+
function FtoCubie(cp, co, ep, uf, rl) {
|
|
467
|
+
this.cp = cp && cp.slice() || [0, 1, 2, 3, 4, 5];
|
|
468
|
+
this.co = co && co.slice() || [0, 0, 0, 0, 0, 0];
|
|
469
|
+
this.ep = ep && ep.slice() || [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
470
|
+
this.uf = uf && uf.slice() || [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
471
|
+
this.rl = rl && rl.slice() || [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
472
|
+
}
|
|
473
|
+
var U = 0, F = 9, r = 18, l = 27, D = 36, B = 45, R = 54, L = 63;
|
|
474
|
+
var cornFacelets = [
|
|
475
|
+
[U + 0, R + 0, F + 0, L + 0],
|
|
476
|
+
[U + 4, B + 8, r + 4, R + 8],
|
|
477
|
+
[U + 8, L + 4, l + 8, B + 4],
|
|
478
|
+
[l + 0, D + 0, r + 0, B + 0],
|
|
479
|
+
[F + 4, D + 8, l + 4, L + 8],
|
|
480
|
+
[r + 8, D + 4, F + 8, R + 4]
|
|
481
|
+
];
|
|
482
|
+
var edgeFacelets = [
|
|
483
|
+
[U + 1, R + 3],
|
|
484
|
+
[U + 3, L + 1],
|
|
485
|
+
[U + 6, B + 6],
|
|
486
|
+
[l + 1, D + 3],
|
|
487
|
+
[r + 3, D + 1],
|
|
488
|
+
[F + 6, D + 6],
|
|
489
|
+
[F + 3, R + 1],
|
|
490
|
+
[F + 1, L + 3],
|
|
491
|
+
[l + 6, L + 6],
|
|
492
|
+
[l + 3, B + 1],
|
|
493
|
+
[r + 1, B + 3],
|
|
494
|
+
[r + 6, R + 6]
|
|
495
|
+
];
|
|
496
|
+
var ctufFacelets = [
|
|
497
|
+
U + 2,
|
|
498
|
+
U + 5,
|
|
499
|
+
U + 7,
|
|
500
|
+
F + 2,
|
|
501
|
+
F + 5,
|
|
502
|
+
F + 7,
|
|
503
|
+
r + 2,
|
|
504
|
+
r + 5,
|
|
505
|
+
r + 7,
|
|
506
|
+
l + 2,
|
|
507
|
+
l + 5,
|
|
508
|
+
l + 7
|
|
509
|
+
];
|
|
510
|
+
var ctrlFacelets = [
|
|
511
|
+
D + 2,
|
|
512
|
+
D + 5,
|
|
513
|
+
D + 7,
|
|
514
|
+
B + 2,
|
|
515
|
+
B + 5,
|
|
516
|
+
B + 7,
|
|
517
|
+
L + 2,
|
|
518
|
+
L + 5,
|
|
519
|
+
L + 7,
|
|
520
|
+
R + 2,
|
|
521
|
+
R + 5,
|
|
522
|
+
R + 7
|
|
523
|
+
];
|
|
524
|
+
FtoCubie.prototype.isEqual = function(fc) {
|
|
525
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
526
|
+
if (this.ep[i2] != fc.ep[i2] || this.uf[i2] != fc.uf[i2] || this.rl[i2] != fc.rl[i2] || i2 < 6 && (this.cp[i2] != fc.cp[i2] || this.co[i2] != fc.co[i2])) {
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return true;
|
|
531
|
+
};
|
|
532
|
+
FtoCubie.prototype.toFaceCube = function(todiv) {
|
|
533
|
+
var f = [];
|
|
534
|
+
todiv = todiv || 9;
|
|
535
|
+
var co = [];
|
|
536
|
+
for (var i2 = 0; i2 < 6; i2++) {
|
|
537
|
+
co[i2] = this.co[i2] * 2;
|
|
538
|
+
}
|
|
539
|
+
mathlib.fillFacelet(cornFacelets, f, this.cp, co, todiv);
|
|
540
|
+
mathlib.fillFacelet(edgeFacelets, f, this.ep, [], todiv);
|
|
541
|
+
mathlib.fillFacelet(ctufFacelets, f, this.uf, null, todiv);
|
|
542
|
+
mathlib.fillFacelet(ctrlFacelets, f, this.rl, null, todiv);
|
|
543
|
+
return f;
|
|
544
|
+
};
|
|
545
|
+
FtoCubie.prototype.fromFacelet = function(facelet) {
|
|
546
|
+
var count = 0;
|
|
547
|
+
var f = [];
|
|
548
|
+
for (var i2 = 0; i2 < 72; ++i2) {
|
|
549
|
+
f[i2] = facelet[i2];
|
|
550
|
+
count += Math.pow(16, f[i2]);
|
|
551
|
+
}
|
|
552
|
+
if (count != 2576980377) {
|
|
553
|
+
return -1;
|
|
554
|
+
}
|
|
555
|
+
var co = [];
|
|
556
|
+
if (mathlib.detectFacelet(cornFacelets, f, this.cp, co, 9) == -1 || mathlib.detectFacelet(edgeFacelets, f, this.ep, [], 9) == -1) {
|
|
557
|
+
return -1;
|
|
558
|
+
}
|
|
559
|
+
var parity = 0;
|
|
560
|
+
for (var i2 = 0; i2 < 6; i2++) {
|
|
561
|
+
this.co[i2] = co[i2] >> 1;
|
|
562
|
+
parity ^= this.co[i2];
|
|
563
|
+
}
|
|
564
|
+
if (parity != 0 || mathlib.getNParity(mathlib.getNPerm(this.cp, 6), 6) != 0 || mathlib.getNParity(mathlib.getNPerm(this.ep, 12), 12) != 0) {
|
|
565
|
+
return -1;
|
|
566
|
+
}
|
|
567
|
+
var remainCnts = [3, 3, 3, 3];
|
|
568
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
569
|
+
var col = f[ctufFacelets[i2]];
|
|
570
|
+
if (!(remainCnts[col] > 0)) {
|
|
571
|
+
return -1;
|
|
572
|
+
}
|
|
573
|
+
this.uf[i2] = col * 3 + 3 - remainCnts[col];
|
|
574
|
+
remainCnts[col]--;
|
|
575
|
+
}
|
|
576
|
+
remainCnts = [3, 3, 3, 3];
|
|
577
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
578
|
+
var col = [0, 1, 3, 2][f[ctrlFacelets[i2]] - 4];
|
|
579
|
+
if (!(remainCnts[col] > 0)) {
|
|
580
|
+
return -1;
|
|
581
|
+
}
|
|
582
|
+
this.rl[i2] = col * 3 + 3 - remainCnts[col];
|
|
583
|
+
remainCnts[col]--;
|
|
584
|
+
}
|
|
585
|
+
if (mathlib.getNParity(mathlib.getNPerm(this.uf, 12), 12) != 0) {
|
|
586
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
587
|
+
this.uf[i2] ^= this.uf[i2] < 2 ? 1 : 0;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (mathlib.getNParity(mathlib.getNPerm(this.rl, 12), 12) != 0) {
|
|
591
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
592
|
+
this.rl[i2] ^= this.rl[i2] < 2 ? 1 : 0;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return this;
|
|
596
|
+
};
|
|
597
|
+
FtoCubie.prototype.toString = function(todiv) {
|
|
598
|
+
var f = this.toFaceCube(todiv);
|
|
599
|
+
var ret = " U8 U7 U6 U5 U4 B8 B7 B6 B5 B4\nL4 U3 U2 U1 R8 r4 B3 B2 B1 l8\nL5 L1 U0 R3 R7 r5 r1 B0 l3 l7\nL6 L2 L0 R0 R2 R6 r6 r2 r0 l0 l2 l6\nL7 L3 F0 R1 R5 r7 r3 D0 l1 l5\nL8 F1 F2 F3 R4 r8 D1 D2 D3 l4\n F4 F5 F6 F7 F8 D4 D5 D6 D7 D8";
|
|
600
|
+
ret = ret.replace(/([UFrlDBRL])([0-8])/g, function(m, p1, p2) {
|
|
601
|
+
var i2 = "UFrlDBRL".indexOf(p1) * 9 + ~~p2;
|
|
602
|
+
return "UFrlDBRL"[~~(f[i2] / 9)] + f[i2] % 9;
|
|
603
|
+
});
|
|
604
|
+
return ret;
|
|
605
|
+
};
|
|
606
|
+
FtoCubie.FtoMult = function() {
|
|
607
|
+
var prod = arguments[arguments.length - 1] || new FtoCubie();
|
|
608
|
+
for (var k = 0; k < arguments.length; k++) {
|
|
609
|
+
var a = arguments[arguments.length - 1 - k];
|
|
610
|
+
for (var i2 = 0; i2 < 6; i2++) {
|
|
611
|
+
prod.co[i2] = k == 0 ? 0 : a.co[prod.cp[i2]] ^ prod.co[i2];
|
|
612
|
+
prod.cp[i2] = k == 0 ? i2 : a.cp[prod.cp[i2]];
|
|
613
|
+
}
|
|
614
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
615
|
+
prod.ep[i2] = k == 0 ? i2 : a.ep[prod.ep[i2]];
|
|
616
|
+
prod.uf[i2] = k == 0 ? i2 : a.uf[prod.uf[i2]];
|
|
617
|
+
prod.rl[i2] = k == 0 ? i2 : a.rl[prod.rl[i2]];
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return prod;
|
|
621
|
+
};
|
|
622
|
+
function initMoveCube() {
|
|
623
|
+
var rotU = new FtoCubie(
|
|
624
|
+
//move[U]
|
|
625
|
+
[1, 2, 0, 4, 5, 3],
|
|
626
|
+
[0, 0, 0, 0, 0, 0],
|
|
627
|
+
[2, 0, 1, 5, 3, 4, 10, 11, 6, 7, 8, 9],
|
|
628
|
+
[1, 2, 0, 7, 8, 6, 10, 11, 9, 4, 5, 3],
|
|
629
|
+
[2, 0, 1, 8, 6, 7, 11, 9, 10, 5, 3, 4]
|
|
630
|
+
);
|
|
631
|
+
var rotR = new FtoCubie(
|
|
632
|
+
//move[R]
|
|
633
|
+
[5, 0, 4, 2, 3, 1],
|
|
634
|
+
[1, 1, 0, 1, 1, 0],
|
|
635
|
+
[6, 5, 7, 9, 2, 10, 11, 4, 3, 8, 1, 0],
|
|
636
|
+
[5, 3, 4, 8, 6, 7, 2, 0, 1, 11, 9, 10],
|
|
637
|
+
[4, 5, 3, 7, 8, 6, 1, 2, 0, 10, 11, 9]
|
|
638
|
+
);
|
|
639
|
+
var rotUi = FtoCubie.FtoMult(rotU, rotU, null);
|
|
640
|
+
var rotRi = FtoCubie.FtoMult(rotR, rotR, null);
|
|
641
|
+
var rotL = FtoCubie.FtoMult(rotUi, rotR, rotU, null);
|
|
642
|
+
var rotF = FtoCubie.FtoMult(rotR, rotU, rotRi, null);
|
|
643
|
+
var moveCube = [];
|
|
644
|
+
moveCube[0] = new FtoCubie(
|
|
645
|
+
//moveU
|
|
646
|
+
[1, 2, 0, 3, 4, 5],
|
|
647
|
+
[0, 0, 0, 0, 0, 0],
|
|
648
|
+
[2, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
|
649
|
+
[1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
|
650
|
+
[0, 1, 2, 3, 6, 7, 11, 9, 8, 5, 10, 4]
|
|
651
|
+
);
|
|
652
|
+
moveCube[2] = new FtoCubie(
|
|
653
|
+
//moveF
|
|
654
|
+
[4, 1, 2, 3, 5, 0],
|
|
655
|
+
[1, 0, 0, 0, 1, 0],
|
|
656
|
+
[0, 1, 2, 3, 4, 6, 7, 5, 8, 9, 10, 11],
|
|
657
|
+
[0, 1, 2, 4, 5, 3, 6, 7, 8, 9, 10, 11],
|
|
658
|
+
[0, 9, 10, 3, 4, 5, 2, 7, 1, 8, 6, 11]
|
|
659
|
+
);
|
|
660
|
+
moveCube[4] = new FtoCubie(
|
|
661
|
+
//mover
|
|
662
|
+
[0, 5, 2, 1, 4, 3],
|
|
663
|
+
[0, 1, 0, 0, 0, 1],
|
|
664
|
+
[0, 1, 2, 3, 10, 5, 6, 7, 8, 9, 11, 4],
|
|
665
|
+
[0, 1, 2, 3, 4, 5, 7, 8, 6, 9, 10, 11],
|
|
666
|
+
[5, 3, 2, 11, 4, 10, 6, 7, 8, 9, 0, 1]
|
|
667
|
+
);
|
|
668
|
+
moveCube[6] = new FtoCubie(
|
|
669
|
+
//movel
|
|
670
|
+
[0, 1, 3, 4, 2, 5],
|
|
671
|
+
[0, 0, 1, 1, 0, 0],
|
|
672
|
+
[0, 1, 2, 8, 4, 5, 6, 7, 9, 3, 10, 11],
|
|
673
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 9],
|
|
674
|
+
[8, 1, 7, 2, 0, 5, 6, 3, 4, 9, 10, 11]
|
|
675
|
+
);
|
|
676
|
+
moveCube[8] = new FtoCubie(
|
|
677
|
+
//moveD
|
|
678
|
+
[0, 1, 2, 5, 3, 4],
|
|
679
|
+
[0, 0, 0, 0, 0, 0],
|
|
680
|
+
[0, 1, 2, 4, 5, 3, 6, 7, 8, 9, 10, 11],
|
|
681
|
+
[0, 1, 2, 3, 9, 10, 5, 7, 4, 8, 6, 11],
|
|
682
|
+
[1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
|
683
|
+
);
|
|
684
|
+
moveCube[10] = new FtoCubie(
|
|
685
|
+
//moveB
|
|
686
|
+
[0, 3, 1, 2, 4, 5],
|
|
687
|
+
[0, 1, 1, 0, 0, 0],
|
|
688
|
+
[0, 1, 10, 3, 4, 5, 6, 7, 8, 2, 9, 11],
|
|
689
|
+
[0, 6, 7, 3, 4, 5, 11, 9, 8, 2, 10, 1],
|
|
690
|
+
[0, 1, 2, 4, 5, 3, 6, 7, 8, 9, 10, 11]
|
|
691
|
+
);
|
|
692
|
+
moveCube[12] = new FtoCubie(
|
|
693
|
+
//moveR
|
|
694
|
+
[5, 0, 2, 3, 4, 1],
|
|
695
|
+
[1, 1, 0, 0, 0, 0],
|
|
696
|
+
[6, 1, 2, 3, 4, 5, 11, 7, 8, 9, 10, 0],
|
|
697
|
+
[5, 3, 2, 8, 4, 7, 6, 0, 1, 9, 10, 11],
|
|
698
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 9]
|
|
699
|
+
);
|
|
700
|
+
moveCube[14] = new FtoCubie(
|
|
701
|
+
//moveL
|
|
702
|
+
[2, 1, 4, 3, 0, 5],
|
|
703
|
+
[1, 0, 1, 0, 0, 0],
|
|
704
|
+
[0, 8, 2, 3, 4, 5, 6, 1, 7, 9, 10, 11],
|
|
705
|
+
[11, 1, 10, 2, 0, 5, 6, 7, 8, 9, 3, 4],
|
|
706
|
+
[0, 1, 2, 3, 4, 5, 7, 8, 6, 9, 10, 11]
|
|
707
|
+
);
|
|
708
|
+
moveCube[16] = FtoCubie.FtoMult(rotU, moveCube[8], null);
|
|
709
|
+
moveCube[18] = FtoCubie.FtoMult(rotF, moveCube[10], null);
|
|
710
|
+
moveCube[20] = FtoCubie.FtoMult(rotR, moveCube[6], null);
|
|
711
|
+
moveCube[22] = FtoCubie.FtoMult(rotL, moveCube[4], null);
|
|
712
|
+
for (var i2 = 1; i2 < 24; i2 += 2) {
|
|
713
|
+
moveCube[i2] = new FtoCubie();
|
|
714
|
+
FtoCubie.FtoMult(moveCube[i2 - 1], moveCube[i2 - 1], moveCube[i2]);
|
|
715
|
+
}
|
|
716
|
+
var moveHash = [];
|
|
717
|
+
for (var i2 = 0; i2 < 24; i2++) {
|
|
718
|
+
moveHash[i2] = moveCube[i2].ep.join(",");
|
|
719
|
+
}
|
|
720
|
+
var symCube = [];
|
|
721
|
+
var symMult = [];
|
|
722
|
+
var symMulI = [];
|
|
723
|
+
var symMulM = [];
|
|
724
|
+
var symHash = [];
|
|
725
|
+
var fc = new FtoCubie();
|
|
726
|
+
var fc2 = new FtoCubie();
|
|
727
|
+
var tmp;
|
|
728
|
+
for (var s = 0; s < 12; s++) {
|
|
729
|
+
symCube[s] = new FtoCubie(fc.cp, fc.co, fc.ep, fc.uf, fc.rl);
|
|
730
|
+
symHash[s] = symCube[s].ep.join(",");
|
|
731
|
+
symMult[s] = [];
|
|
732
|
+
symMulI[s] = [];
|
|
733
|
+
fc = FtoCubie.FtoMult(fc, rotU, null);
|
|
734
|
+
if (s % 3 == 2) {
|
|
735
|
+
fc = FtoCubie.FtoMult(fc, rotR, rotU, null);
|
|
736
|
+
}
|
|
737
|
+
if (s % 6 == 5) {
|
|
738
|
+
fc = FtoCubie.FtoMult(fc, rotU, rotR, null);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
742
|
+
for (var j = 0; j < 12; j++) {
|
|
743
|
+
FtoCubie.FtoMult(symCube[i2], symCube[j], fc);
|
|
744
|
+
var k = symHash.indexOf(fc.ep.join(","));
|
|
745
|
+
symMult[i2][j] = k;
|
|
746
|
+
symMulI[k][j] = i2;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
for (var s = 0; s < 12; s++) {
|
|
750
|
+
symMulM[s] = [];
|
|
751
|
+
for (var j = 0; j < 8; j++) {
|
|
752
|
+
FtoCubie.FtoMult(symCube[symMulI[0][s]], moveCube[j * 2], symCube[s], fc);
|
|
753
|
+
var k = moveHash.indexOf(fc.ep.join(","));
|
|
754
|
+
symMulM[s][j] = k >> 1;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
FtoCubie.moveCube = moveCube;
|
|
758
|
+
FtoCubie.symCube = symCube;
|
|
759
|
+
FtoCubie.symMult = symMult;
|
|
760
|
+
FtoCubie.symMulI = symMulI;
|
|
761
|
+
FtoCubie.symMulM = symMulM;
|
|
762
|
+
}
|
|
763
|
+
;
|
|
764
|
+
initMoveCube();
|
|
765
|
+
function ftoPermMove(key, perm, move) {
|
|
766
|
+
var ret = [];
|
|
767
|
+
var movePerm = FtoCubie.moveCube[move][key];
|
|
768
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
769
|
+
ret[i2] = perm[movePerm[i2]];
|
|
770
|
+
}
|
|
771
|
+
return ret;
|
|
772
|
+
}
|
|
773
|
+
function ftoFullMove(fc, move) {
|
|
774
|
+
return FtoCubie.FtoMult(fc, FtoCubie.moveCube[move], null);
|
|
775
|
+
}
|
|
776
|
+
function phase1EdgeHash(ep) {
|
|
777
|
+
var ret = 0;
|
|
778
|
+
var e3fst = -1;
|
|
779
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
780
|
+
if ((56 >> ep[i2] & 1) == 0) {
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
if (e3fst == -1) {
|
|
784
|
+
e3fst = ep[i2];
|
|
785
|
+
}
|
|
786
|
+
ret += (ep[i2] - e3fst + 3) % 3 + 1 << i2 * 2;
|
|
787
|
+
}
|
|
788
|
+
return ret;
|
|
789
|
+
}
|
|
790
|
+
function phase1CtrlHash(rl) {
|
|
791
|
+
var ret = 0;
|
|
792
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
793
|
+
if (rl[i2] < 3) {
|
|
794
|
+
ret |= 1 << i2;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
return ret;
|
|
798
|
+
}
|
|
799
|
+
function phase2EdgeHash(ep) {
|
|
800
|
+
var edge2group = [0, 1, 2, 3, 3, 3, 0, 1, 1, 2, 2, 0];
|
|
801
|
+
var groups = [[0, 6, 11], [1, 7, 8], [2, 9, 10], [3, 4, 5]];
|
|
802
|
+
var ret = 0;
|
|
803
|
+
var egoff = [-1, -1, -1, -1];
|
|
804
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
805
|
+
var g = edge2group[ep[i2]];
|
|
806
|
+
var gidx = groups[g].indexOf(ep[i2]);
|
|
807
|
+
if (egoff[g] == -1) {
|
|
808
|
+
egoff[g] = gidx;
|
|
809
|
+
}
|
|
810
|
+
ret += (g * 4 + (gidx - egoff[g] + 3) % 3) * Math.pow(16, i2);
|
|
811
|
+
}
|
|
812
|
+
return ret;
|
|
813
|
+
}
|
|
814
|
+
function phase2CtHash(ct) {
|
|
815
|
+
var ret = 0;
|
|
816
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
817
|
+
ret |= ~~(ct[i2] / 3) << i2 * 2;
|
|
818
|
+
}
|
|
819
|
+
return ret;
|
|
820
|
+
}
|
|
821
|
+
function phase3EdgeHash(ep) {
|
|
822
|
+
return String.fromCharCode.apply(null, ep);
|
|
823
|
+
}
|
|
824
|
+
function phase3CcufHash(fc) {
|
|
825
|
+
return String.fromCharCode.apply(null, [].concat(fc.cp, fc.co));
|
|
826
|
+
}
|
|
827
|
+
function randomMoves(validMoves, len) {
|
|
828
|
+
var scramble = [];
|
|
829
|
+
for (var i2 = 0; i2 < len; i2++) {
|
|
830
|
+
scramble.push(validMoves[~~(Math.random() * validMoves.length)]);
|
|
831
|
+
}
|
|
832
|
+
var fc = new FtoCubie();
|
|
833
|
+
for (var i2 = 0; i2 < scramble.length; i2++) {
|
|
834
|
+
fc = FtoCubie.FtoMult(fc, FtoCubie.moveCube[scramble[i2]], null);
|
|
835
|
+
}
|
|
836
|
+
return [fc, scramble];
|
|
837
|
+
}
|
|
838
|
+
function genCkmv(moves) {
|
|
839
|
+
var ckmv = [];
|
|
840
|
+
var tmp1 = new FtoCubie();
|
|
841
|
+
var tmp2 = new FtoCubie();
|
|
842
|
+
for (var m1 = 0; m1 < moves.length; m1++) {
|
|
843
|
+
ckmv[m1] = 1 << m1;
|
|
844
|
+
for (var m2 = 0; m2 < m1; m2++) {
|
|
845
|
+
FtoCubie.FtoMult(FtoCubie.moveCube[moves[m1]], FtoCubie.moveCube[moves[m2]], tmp1);
|
|
846
|
+
FtoCubie.FtoMult(FtoCubie.moveCube[moves[m2]], FtoCubie.moveCube[moves[m1]], tmp2);
|
|
847
|
+
if (tmp1.isEqual(tmp2)) {
|
|
848
|
+
ckmv[m1] |= 1 << m2;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return ckmv;
|
|
853
|
+
}
|
|
854
|
+
var phase1Moves = [0, 2, 22, 6, 16, 10, 12, 14];
|
|
855
|
+
var p1epMoves = null;
|
|
856
|
+
var p1rlMoves = null;
|
|
857
|
+
var ckmv1 = null;
|
|
858
|
+
var solv1 = null;
|
|
859
|
+
var pyraSymCube = [];
|
|
860
|
+
for (var i = 0; i < 12; i++) {
|
|
861
|
+
pyraSymCube.push(new FtoCubie(
|
|
862
|
+
FtoCubie.symCube[i].cp,
|
|
863
|
+
FtoCubie.symCube[i].co,
|
|
864
|
+
null,
|
|
865
|
+
FtoCubie.symCube[i].uf,
|
|
866
|
+
null
|
|
867
|
+
));
|
|
868
|
+
}
|
|
869
|
+
function phase1Init() {
|
|
870
|
+
var fc = new FtoCubie();
|
|
871
|
+
p1epMoves = mathlib.createMoveHash(fc.ep.slice(), phase1Moves, phase1EdgeHash, ftoPermMove.bind(null, "ep"));
|
|
872
|
+
p1rlMoves = mathlib.createMoveHash(fc.rl.slice(), phase1Moves, phase1CtrlHash, ftoPermMove.bind(null, "rl"));
|
|
873
|
+
var N_P1EP = p1epMoves[0][0].length;
|
|
874
|
+
var N_P1RL = p1rlMoves[0][0].length;
|
|
875
|
+
DEBUG && console.log("p1ep len=" + N_P1EP + " p1rl len=" + N_P1RL);
|
|
876
|
+
ckmv1 = genCkmv(phase1Moves);
|
|
877
|
+
var p1eprlPrun = [];
|
|
878
|
+
mathlib.createPrun(p1eprlPrun, 0, N_P1EP * N_P1RL, 14, function(idx, move) {
|
|
879
|
+
var rl = ~~(idx / N_P1EP);
|
|
880
|
+
var ep = idx % N_P1EP;
|
|
881
|
+
return p1rlMoves[0][move][rl] * N_P1EP + p1epMoves[0][move][ep];
|
|
882
|
+
}, phase1Moves.length, 2);
|
|
883
|
+
solv1 = new mathlib.Searcher(null, function(idx) {
|
|
884
|
+
return mathlib.getPruning(p1eprlPrun, idx[1] * N_P1EP + idx[0]);
|
|
885
|
+
}, function(idx, move) {
|
|
886
|
+
return [
|
|
887
|
+
p1epMoves[0][move][idx[0]],
|
|
888
|
+
p1rlMoves[0][move][idx[1]]
|
|
889
|
+
];
|
|
890
|
+
}, 8, 2, ckmv1);
|
|
891
|
+
}
|
|
892
|
+
function phase1GenIdxs(fc) {
|
|
893
|
+
var idxs = [];
|
|
894
|
+
var syms = [];
|
|
895
|
+
var fc2 = new FtoCubie();
|
|
896
|
+
var fc3 = new FtoCubie();
|
|
897
|
+
for (var sidx = 0; sidx < 12; sidx += 3) {
|
|
898
|
+
FtoCubie.FtoMult(FtoCubie.symCube[sidx % 12], fc, fc2);
|
|
899
|
+
var rot;
|
|
900
|
+
for (rot = 0; rot < 12; rot++) {
|
|
901
|
+
FtoCubie.FtoMult(fc2, FtoCubie.symCube[rot], fc3);
|
|
902
|
+
if (fc3.ep[4] == 4) {
|
|
903
|
+
break;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
var epidxs = [];
|
|
907
|
+
var rlidxs = [];
|
|
908
|
+
idxs.push([
|
|
909
|
+
p1epMoves[1][phase1EdgeHash(fc3.ep)],
|
|
910
|
+
p1rlMoves[1][phase1CtrlHash(fc3.rl)]
|
|
911
|
+
]);
|
|
912
|
+
syms.push([sidx, rot]);
|
|
913
|
+
}
|
|
914
|
+
return [idxs, syms];
|
|
915
|
+
}
|
|
916
|
+
function phase1ProcSol(sol, solsym, fc) {
|
|
917
|
+
for (var i2 = 0; i2 < sol.length; i2++) {
|
|
918
|
+
sol[i2] = phase1Moves[sol[i2][0]] + sol[i2][1];
|
|
919
|
+
}
|
|
920
|
+
var std = move2std(sol);
|
|
921
|
+
for (var i2 = 0; i2 < std[0].length; i2++) {
|
|
922
|
+
var move = std[0][i2];
|
|
923
|
+
sol[i2] = FtoCubie.symMulM[FtoCubie.symMulI[0][solsym[1]]][move >> 1] * 2 + (move & 1);
|
|
924
|
+
fc = FtoCubie.FtoMult(fc, FtoCubie.moveCube[sol[i2]], null);
|
|
925
|
+
}
|
|
926
|
+
solsym[1] = FtoCubie.symMulI[solsym[1]][std[1]];
|
|
927
|
+
fc = FtoCubie.FtoMult(
|
|
928
|
+
pyraSymCube[~~(solsym[0] / 12)],
|
|
929
|
+
FtoCubie.symCube[solsym[0] % 12],
|
|
930
|
+
fc,
|
|
931
|
+
FtoCubie.symCube[solsym[1]],
|
|
932
|
+
null
|
|
933
|
+
);
|
|
934
|
+
return [fc, sol, solsym[0], solsym[1]];
|
|
935
|
+
}
|
|
936
|
+
var N_PHASE1_SOLS = 1e3;
|
|
937
|
+
function solvePhase1(fc) {
|
|
938
|
+
if (!solv1) {
|
|
939
|
+
phase1Init();
|
|
940
|
+
}
|
|
941
|
+
var tt = performance.now();
|
|
942
|
+
var idxs = phase1GenIdxs(fc);
|
|
943
|
+
var syms = idxs[1];
|
|
944
|
+
idxs = idxs[0];
|
|
945
|
+
var p1sols = [];
|
|
946
|
+
var sol1s = solv1.solveMulti(idxs, 0, 12, function(sol, sidx) {
|
|
947
|
+
var param = phase1ProcSol(sol.slice(), syms[sidx].slice(), fc);
|
|
948
|
+
p1sols.push(param);
|
|
949
|
+
return p1sols.length >= N_PHASE1_SOLS;
|
|
950
|
+
});
|
|
951
|
+
tt = performance.now() - tt;
|
|
952
|
+
for (var i2 = 0; i2 < p1sols.length; i2++) {
|
|
953
|
+
p1sols[i2].push(tt);
|
|
954
|
+
}
|
|
955
|
+
return p1sols;
|
|
956
|
+
}
|
|
957
|
+
var phase2Moves = [0, 12, 14, 8, 10];
|
|
958
|
+
var p2epMoves = null;
|
|
959
|
+
var p2rlMoves = null;
|
|
960
|
+
var p2ccMoves = null;
|
|
961
|
+
var p2cc2ufBit = {};
|
|
962
|
+
var ckmv2 = null;
|
|
963
|
+
var solv2 = null;
|
|
964
|
+
var P2EPRL_MAXL = 11;
|
|
965
|
+
var p2symMap = [];
|
|
966
|
+
var ufStd2Raw = [];
|
|
967
|
+
var ufRaw2Std = [];
|
|
968
|
+
var p2ufCoord = new mathlib.Coord("c", 12, [3, 3, 3, 3]);
|
|
969
|
+
var cornExFacelets = [
|
|
970
|
+
[U + 2, R + 2, F + 2, L + 2],
|
|
971
|
+
[U + 5, B + 7, r + 5, R + 7],
|
|
972
|
+
[U + 7, L + 5, l + 7, B + 5],
|
|
973
|
+
[l + 2, D + 2, r + 2, B + 2],
|
|
974
|
+
[F + 5, D + 7, l + 5, L + 7],
|
|
975
|
+
[r + 7, D + 5, F + 7, R + 5]
|
|
976
|
+
];
|
|
977
|
+
function phase2CpcoHash(fc) {
|
|
978
|
+
var ret = String.fromCharCode.apply(null, [].concat(fc.cp, fc.co));
|
|
979
|
+
if (!(ret in p2cc2ufBit)) {
|
|
980
|
+
var co = [];
|
|
981
|
+
for (var i2 = 0; i2 < 6; i2++) {
|
|
982
|
+
co[i2] = fc.co[i2] * 2;
|
|
983
|
+
}
|
|
984
|
+
var facelet = fc.toFaceCube();
|
|
985
|
+
mathlib.fillFacelet(cornExFacelets, facelet, fc.cp, co, 9);
|
|
986
|
+
var fc2 = new FtoCubie().fromFacelet(facelet);
|
|
987
|
+
p2cc2ufBit[ret] = phase2CtHash(fc2.uf);
|
|
988
|
+
}
|
|
989
|
+
return ret;
|
|
990
|
+
}
|
|
991
|
+
function phase2ufStd(uf, symMap) {
|
|
992
|
+
var col1 = uf[0], col2 = -1;
|
|
993
|
+
for (var i2 = 1; i2 < 12; i2++) {
|
|
994
|
+
if (uf[i2] != col1) {
|
|
995
|
+
col2 = uf[i2];
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
var sym = symMap[col1 * 4 + col2];
|
|
1000
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
1001
|
+
uf[i2] = ~~(FtoCubie.symCube[sym].uf[uf[i2] * 3] / 3);
|
|
1002
|
+
}
|
|
1003
|
+
return sym;
|
|
1004
|
+
}
|
|
1005
|
+
function getPhase2ufIdx(uf) {
|
|
1006
|
+
var ufstd = [];
|
|
1007
|
+
for (var i2 = 0; i2 < 12; i2++) {
|
|
1008
|
+
ufstd[i2] = ~~(uf[i2] / 3);
|
|
1009
|
+
}
|
|
1010
|
+
var sym = phase2ufStd(ufstd, p2symMap);
|
|
1011
|
+
return ufRaw2Std[p2ufCoord.get(ufstd)] << 4 | sym;
|
|
1012
|
+
}
|
|
1013
|
+
function phase2Init() {
|
|
1014
|
+
var fc = new FtoCubie();
|
|
1015
|
+
p2epMoves = mathlib.createMoveHash(fc.ep.slice(), phase2Moves, phase2EdgeHash, ftoPermMove.bind(null, "ep"));
|
|
1016
|
+
p2rlMoves = mathlib.createMoveHash(fc.rl.slice(), phase2Moves, phase2CtHash, ftoPermMove.bind(null, "rl"));
|
|
1017
|
+
p2ccMoves = mathlib.createMoveHash(fc, phase2Moves, phase2CpcoHash, ftoFullMove);
|
|
1018
|
+
var arr = [];
|
|
1019
|
+
var arr2 = [];
|
|
1020
|
+
var p2ufMoveStd = [[], [], [], [], []];
|
|
1021
|
+
var ufStd2Bit = [];
|
|
1022
|
+
var p2ccRecol = [];
|
|
1023
|
+
for (var s = 0; s < 12; s++) {
|
|
1024
|
+
var uf = FtoCubie.symCube[s].uf;
|
|
1025
|
+
var col1 = ~~(uf.indexOf(0) / 3);
|
|
1026
|
+
var col2 = ~~(uf.indexOf(3) / 3);
|
|
1027
|
+
p2symMap[col1 * 4 + col2] = s;
|
|
1028
|
+
p2ccRecol[s] = [];
|
|
1029
|
+
}
|
|
1030
|
+
out: for (var i2 = 0; i2 < 42e3; i2++) {
|
|
1031
|
+
p2ufCoord.set(arr, i2);
|
|
1032
|
+
for (var j = 1; j < 12; j++) {
|
|
1033
|
+
if (arr[j] > 1) {
|
|
1034
|
+
continue out;
|
|
1035
|
+
} else if (arr[j] == 1) {
|
|
1036
|
+
break;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
ufRaw2Std[i2] = ufStd2Raw.length;
|
|
1040
|
+
ufStd2Raw.push(i2);
|
|
1041
|
+
}
|
|
1042
|
+
for (var i2 = 0; i2 < ufStd2Raw.length; i2++) {
|
|
1043
|
+
p2ufCoord.set(arr, ufStd2Raw[i2]);
|
|
1044
|
+
var hash = 0;
|
|
1045
|
+
for (var j = 0; j < 12; j++) {
|
|
1046
|
+
hash |= arr[j] << j * 2;
|
|
1047
|
+
}
|
|
1048
|
+
ufStd2Bit[i2] = hash;
|
|
1049
|
+
for (var m = 0; m < phase2Moves.length; m++) {
|
|
1050
|
+
mathlib.permOriMult(arr, FtoCubie.moveCube[phase2Moves[m]].uf, arr2);
|
|
1051
|
+
var sym = phase2ufStd(arr2, p2symMap);
|
|
1052
|
+
p2ufMoveStd[m][i2] = ufRaw2Std[p2ufCoord.get(arr2)] << 4 | sym;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
var cc2Bit = [];
|
|
1056
|
+
for (var key in p2ccMoves[1]) {
|
|
1057
|
+
var idx = p2ccMoves[1][key];
|
|
1058
|
+
cc2Bit[idx] = p2cc2ufBit[key];
|
|
1059
|
+
var cpco = [];
|
|
1060
|
+
for (var s = 0; s < 12; s++) {
|
|
1061
|
+
var sc = FtoCubie.symCube[s];
|
|
1062
|
+
for (var i2 = 0; i2 < 6; i2++) {
|
|
1063
|
+
var scpi = key.charCodeAt(i2);
|
|
1064
|
+
cpco[i2] = sc.cp[scpi];
|
|
1065
|
+
cpco[i2 + 6] = sc.co[scpi] ^ key.charCodeAt(i2 + 6);
|
|
1066
|
+
}
|
|
1067
|
+
var hash = String.fromCharCode.apply(null, cpco);
|
|
1068
|
+
p2ccRecol[s][idx] = p2ccMoves[1][hash];
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
var p2necPrun = [
|
|
1072
|
+
// idx = a * 7 + b, a: #mismatch 3 U corners, b: other corners
|
|
1073
|
+
0,
|
|
1074
|
+
0,
|
|
1075
|
+
3,
|
|
1076
|
+
4,
|
|
1077
|
+
5,
|
|
1078
|
+
6,
|
|
1079
|
+
8,
|
|
1080
|
+
0,
|
|
1081
|
+
2,
|
|
1082
|
+
3,
|
|
1083
|
+
4,
|
|
1084
|
+
5,
|
|
1085
|
+
6,
|
|
1086
|
+
8,
|
|
1087
|
+
1,
|
|
1088
|
+
2,
|
|
1089
|
+
4,
|
|
1090
|
+
4,
|
|
1091
|
+
5,
|
|
1092
|
+
6,
|
|
1093
|
+
8,
|
|
1094
|
+
1,
|
|
1095
|
+
3,
|
|
1096
|
+
4,
|
|
1097
|
+
5,
|
|
1098
|
+
6,
|
|
1099
|
+
7,
|
|
1100
|
+
8,
|
|
1101
|
+
3,
|
|
1102
|
+
3,
|
|
1103
|
+
4,
|
|
1104
|
+
5,
|
|
1105
|
+
6,
|
|
1106
|
+
7,
|
|
1107
|
+
9,
|
|
1108
|
+
4,
|
|
1109
|
+
4,
|
|
1110
|
+
5,
|
|
1111
|
+
6,
|
|
1112
|
+
7,
|
|
1113
|
+
8,
|
|
1114
|
+
9,
|
|
1115
|
+
5,
|
|
1116
|
+
5,
|
|
1117
|
+
6,
|
|
1118
|
+
7,
|
|
1119
|
+
8,
|
|
1120
|
+
9,
|
|
1121
|
+
10
|
|
1122
|
+
];
|
|
1123
|
+
var N_P2EP = p2epMoves[0][0].length;
|
|
1124
|
+
var N_P2RL = p2rlMoves[0][0].length;
|
|
1125
|
+
var p2eprlPrun = [];
|
|
1126
|
+
mathlib.createPrun(p2eprlPrun, 0, N_P2EP * N_P2RL, P2EPRL_MAXL - 2, function(idx2, move) {
|
|
1127
|
+
var rl = ~~(idx2 / N_P2EP);
|
|
1128
|
+
var ep = idx2 % N_P2EP;
|
|
1129
|
+
return p2rlMoves[0][move][rl] * N_P2EP + p2epMoves[0][move][ep];
|
|
1130
|
+
}, phase2Moves.length, 2);
|
|
1131
|
+
ckmv2 = genCkmv(phase2Moves);
|
|
1132
|
+
solv2 = new mathlib.Searcher(function(idx2) {
|
|
1133
|
+
return ufStd2Bit[idx2[3] >> 4] == cc2Bit[p2ccRecol[idx2[3] & 15][idx2[2]]];
|
|
1134
|
+
}, function(idx2) {
|
|
1135
|
+
var xors = ufStd2Bit[idx2[3] >> 4] ^ cc2Bit[p2ccRecol[idx2[3] & 15][idx2[2]]];
|
|
1136
|
+
xors = (xors | xors >> 1) & 5592405;
|
|
1137
|
+
var necIdx = mathlib.bitCount(xors & 12632319) * 7 + mathlib.bitCount(xors & 4144896);
|
|
1138
|
+
return Math.max(
|
|
1139
|
+
Math.min(P2EPRL_MAXL, mathlib.getPruning(p2eprlPrun, idx2[1] * N_P2EP + idx2[0])),
|
|
1140
|
+
p2necPrun[necIdx]
|
|
1141
|
+
);
|
|
1142
|
+
}, function(idx2, move) {
|
|
1143
|
+
var ufidx1 = p2ufMoveStd[move][idx2[3] >> 4];
|
|
1144
|
+
var ufcol = FtoCubie.symMult[ufidx1 & 15][idx2[3] & 15];
|
|
1145
|
+
return [
|
|
1146
|
+
p2epMoves[0][move][idx2[0]],
|
|
1147
|
+
p2rlMoves[0][move][idx2[1]],
|
|
1148
|
+
p2ccMoves[0][move][idx2[2]],
|
|
1149
|
+
ufidx1 & ~15 | ufcol
|
|
1150
|
+
];
|
|
1151
|
+
}, phase2Moves.length, 2, ckmv2);
|
|
1152
|
+
}
|
|
1153
|
+
function solvePhase2(solvInfos) {
|
|
1154
|
+
if (!solv2) {
|
|
1155
|
+
phase2Init();
|
|
1156
|
+
}
|
|
1157
|
+
var tt = performance.now();
|
|
1158
|
+
var idxs = [];
|
|
1159
|
+
for (var i2 = 0; i2 < solvInfos.length; i2++) {
|
|
1160
|
+
idxs.push([
|
|
1161
|
+
p2epMoves[1][phase2EdgeHash(solvInfos[i2][0].ep)],
|
|
1162
|
+
p2rlMoves[1][phase2CtHash(solvInfos[i2][0].rl)],
|
|
1163
|
+
p2ccMoves[1][phase2CpcoHash(solvInfos[i2][0])],
|
|
1164
|
+
getPhase2ufIdx(solvInfos[i2][0].uf)
|
|
1165
|
+
]);
|
|
1166
|
+
}
|
|
1167
|
+
var sol2s = solv2.solveMulti(idxs, 0, 25);
|
|
1168
|
+
var sol = sol2s[0];
|
|
1169
|
+
var src = sol2s[1];
|
|
1170
|
+
var solvInfo = solvInfos[src];
|
|
1171
|
+
var fc = solvInfo[0];
|
|
1172
|
+
for (var i2 = 0; i2 < sol.length; i2++) {
|
|
1173
|
+
var move = phase2Moves[sol[i2][0]] + sol[i2][1];
|
|
1174
|
+
sol[i2] = FtoCubie.symMulM[FtoCubie.symMulI[0][solvInfo[3]]][move >> 1] * 2 + (move & 1);
|
|
1175
|
+
fc = FtoCubie.FtoMult(fc, FtoCubie.moveCube[move], null);
|
|
1176
|
+
}
|
|
1177
|
+
return [fc, sol, solvInfo[2], solvInfo[3], src, performance.now() - tt];
|
|
1178
|
+
}
|
|
1179
|
+
var phase3Moves = [8, 10, 12, 14];
|
|
1180
|
+
var p3epMoves = null;
|
|
1181
|
+
var p3ufMoves = null;
|
|
1182
|
+
var p3epPrun = null;
|
|
1183
|
+
var p3ufPrun = null;
|
|
1184
|
+
var ckmv3 = null;
|
|
1185
|
+
var solv3 = null;
|
|
1186
|
+
function phase3Init() {
|
|
1187
|
+
var fc = new FtoCubie();
|
|
1188
|
+
p3epMoves = mathlib.createMoveHash(fc.ep.slice(), phase3Moves, phase3EdgeHash, ftoPermMove.bind(null, "ep"));
|
|
1189
|
+
p3ufMoves = mathlib.createMoveHash(new FtoCubie(), phase3Moves, phase3CcufHash, ftoFullMove);
|
|
1190
|
+
p3epPrun = [];
|
|
1191
|
+
p3ufPrun = [];
|
|
1192
|
+
mathlib.createPrun(p3epPrun, 0, 81, 14, p3epMoves[0], 4, 2);
|
|
1193
|
+
mathlib.createPrun(p3ufPrun, 0, 11520, 14, p3ufMoves[0], 4, 2);
|
|
1194
|
+
ckmv3 = genCkmv(phase3Moves);
|
|
1195
|
+
solv3 = new mathlib.Searcher(null, function(idx) {
|
|
1196
|
+
return Math.max(
|
|
1197
|
+
mathlib.getPruning(p3epPrun, idx[0]),
|
|
1198
|
+
mathlib.getPruning(p3ufPrun, idx[1])
|
|
1199
|
+
);
|
|
1200
|
+
}, function(idx, move) {
|
|
1201
|
+
return [p3epMoves[0][move][idx[0]], p3ufMoves[0][move][idx[1]]];
|
|
1202
|
+
}, 4, 2, ckmv3);
|
|
1203
|
+
}
|
|
1204
|
+
function solvePhase3(solvInfo) {
|
|
1205
|
+
var fc = solvInfo[0];
|
|
1206
|
+
if (!p3epPrun) {
|
|
1207
|
+
phase3Init();
|
|
1208
|
+
}
|
|
1209
|
+
var tt = performance.now();
|
|
1210
|
+
var p3epidx = p3epMoves[1][phase3EdgeHash(fc.ep)];
|
|
1211
|
+
var p3ufidx = p3ufMoves[1][phase3CcufHash(fc)];
|
|
1212
|
+
var sol = solv3.solve([p3epidx, p3ufidx], 0, 25);
|
|
1213
|
+
for (var i2 = 0; i2 < sol.length; i2++) {
|
|
1214
|
+
var move = phase3Moves[sol[i2][0]] + sol[i2][1];
|
|
1215
|
+
sol[i2] = FtoCubie.symMulM[FtoCubie.symMulI[0][solvInfo[3]]][move >> 1] * 2 + (move & 1);
|
|
1216
|
+
fc = FtoCubie.FtoMult(fc, FtoCubie.moveCube[move], null);
|
|
1217
|
+
}
|
|
1218
|
+
return [fc, sol, solvInfo[2], solvInfo[3], performance.now() - tt];
|
|
1219
|
+
}
|
|
1220
|
+
function move2std(moves) {
|
|
1221
|
+
var sym = 0;
|
|
1222
|
+
var ret = [];
|
|
1223
|
+
var w2axis = [4, 5, 3, 2];
|
|
1224
|
+
var w2rot = [1, 10, 5, 11];
|
|
1225
|
+
for (var i2 = 0; i2 < moves.length; i2++) {
|
|
1226
|
+
var rot = 0;
|
|
1227
|
+
var axis = moves[i2] >> 1;
|
|
1228
|
+
var pow = moves[i2] & 1;
|
|
1229
|
+
if (axis >= 8) {
|
|
1230
|
+
rot = w2rot[axis - 8];
|
|
1231
|
+
axis = w2axis[axis - 8];
|
|
1232
|
+
}
|
|
1233
|
+
if (!pow) {
|
|
1234
|
+
rot = FtoCubie.symMult[rot][rot];
|
|
1235
|
+
}
|
|
1236
|
+
ret.push(FtoCubie.symMulM[sym][axis] * 2 + pow);
|
|
1237
|
+
sym = FtoCubie.symMult[rot][sym];
|
|
1238
|
+
}
|
|
1239
|
+
return [ret, sym];
|
|
1240
|
+
}
|
|
1241
|
+
function applyMoves(fc, moves) {
|
|
1242
|
+
for (var i2 = 0; i2 < moves.length; i2++) {
|
|
1243
|
+
fc = FtoCubie.FtoMult(fc, FtoCubie.moveCube[moves[i2]], null);
|
|
1244
|
+
}
|
|
1245
|
+
return fc;
|
|
1246
|
+
}
|
|
1247
|
+
var move2str = ["U", "U'", "F", "F'", "r", "r'", "l", "l'", "D", "D'", "B", "B'", "R", "R'", "L", "L'"];
|
|
1248
|
+
function prettyMoves(moves) {
|
|
1249
|
+
var buf = [];
|
|
1250
|
+
for (var i2 = 0; i2 < moves.length; i2++) {
|
|
1251
|
+
buf[i2] = move2str[moves[i2]];
|
|
1252
|
+
}
|
|
1253
|
+
return buf.join(" ").replace(/l/g, "BL").replace(/r/g, "BR");
|
|
1254
|
+
}
|
|
1255
|
+
function FtoSolver() {
|
|
1256
|
+
}
|
|
1257
|
+
FtoSolver.prototype.solveFto = function(fc, invSol) {
|
|
1258
|
+
if (!solv1) {
|
|
1259
|
+
var tt = performance.now();
|
|
1260
|
+
phase1Init();
|
|
1261
|
+
phase2Init();
|
|
1262
|
+
phase3Init();
|
|
1263
|
+
DEBUG && console.log("[ftosolver] init time:", performance.now() - tt);
|
|
1264
|
+
}
|
|
1265
|
+
var solvInfos = solvePhase1(fc);
|
|
1266
|
+
var solvInfo2 = solvePhase2(solvInfos);
|
|
1267
|
+
var solvInfo1 = solvInfos[solvInfo2[4]];
|
|
1268
|
+
this.sol1 = solvInfo1[1].slice();
|
|
1269
|
+
this.tt1 = solvInfo1[4];
|
|
1270
|
+
var sym1Idx = solvInfo1[2];
|
|
1271
|
+
this.sol2 = solvInfo2[1].slice();
|
|
1272
|
+
this.tt2 = solvInfo2[5];
|
|
1273
|
+
solvInfo2[0] = FtoCubie.FtoMult(pyraSymCube[FtoCubie.symMulI[0][~~(sym1Idx / 12)]], solvInfo2[0], null);
|
|
1274
|
+
var solvInfo3 = solvePhase3(solvInfo2);
|
|
1275
|
+
this.sol3 = solvInfo3[1].slice();
|
|
1276
|
+
this.tt3 = solvInfo3[4];
|
|
1277
|
+
var sol = [].concat(this.sol1, this.sol2, this.sol3);
|
|
1278
|
+
if (invSol) {
|
|
1279
|
+
for (var i2 = 0; i2 < sol.length; i2++) {
|
|
1280
|
+
sol[i2] ^= 1;
|
|
1281
|
+
}
|
|
1282
|
+
sol.reverse();
|
|
1283
|
+
}
|
|
1284
|
+
return prettyMoves(sol);
|
|
1285
|
+
};
|
|
1286
|
+
var solver = new FtoSolver();
|
|
1287
|
+
function solveTest(n_moves) {
|
|
1288
|
+
var solvInfo = randomMoves([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], n_moves);
|
|
1289
|
+
var scramble = prettyMoves(solvInfo[1].slice());
|
|
1290
|
+
var solution = solver.solveFto(solvInfo[0]);
|
|
1291
|
+
var fc = solvInfo[0];
|
|
1292
|
+
DEBUG && console.log("scrambled state\n", fc.toString(1));
|
|
1293
|
+
fc = applyMoves(fc, solver.sol1);
|
|
1294
|
+
DEBUG && console.log("after phase 1 (" + prettyMoves(solver.sol1) + "):\n", fc.toString(1));
|
|
1295
|
+
fc = applyMoves(fc, solver.sol2);
|
|
1296
|
+
DEBUG && console.log("after phase 2 (" + prettyMoves(solver.sol2) + "):\n", fc.toString(1));
|
|
1297
|
+
fc = applyMoves(fc, solver.sol3);
|
|
1298
|
+
DEBUG && console.log("after phase 3 (" + prettyMoves(solver.sol3) + "):\n", fc.toString(1));
|
|
1299
|
+
var facelets = fc.toFaceCube();
|
|
1300
|
+
var isSolved = true;
|
|
1301
|
+
outer_loop: for (var i2 = 0; i2 < 8; i2++) {
|
|
1302
|
+
for (var j = 1; j < 9; j++) {
|
|
1303
|
+
if (facelets[i2 * 9 + j] != facelets[i2 * 9]) {
|
|
1304
|
+
isSolved = false;
|
|
1305
|
+
break outer_loop;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
if (!isSolved) {
|
|
1310
|
+
console.log("error, FTO not solved!!!");
|
|
1311
|
+
}
|
|
1312
|
+
DEBUG && console.log(scramble, solution);
|
|
1313
|
+
return [
|
|
1314
|
+
solver.sol1.length + solver.sol2.length + solver.sol3.length,
|
|
1315
|
+
solver.sol1.length,
|
|
1316
|
+
solver.sol2.length,
|
|
1317
|
+
solver.sol3.length,
|
|
1318
|
+
solver.tt1,
|
|
1319
|
+
solver.tt2,
|
|
1320
|
+
solver.tt3
|
|
1321
|
+
];
|
|
1322
|
+
}
|
|
1323
|
+
function testbench(ntest) {
|
|
1324
|
+
ntest = ntest || 100;
|
|
1325
|
+
var cumlen = [];
|
|
1326
|
+
for (var nsolv = 0; nsolv < ntest; nsolv++) {
|
|
1327
|
+
var lengths = solveTest(200);
|
|
1328
|
+
for (var i2 = 0; i2 < lengths.length; i2++) {
|
|
1329
|
+
cumlen[i2] = (cumlen[i2] || 0) + lengths[i2];
|
|
1330
|
+
}
|
|
1331
|
+
console.log("AvgL: ", cumlen[0] / (nsolv + 1));
|
|
1332
|
+
}
|
|
1333
|
+
console.log("AvgL1:", cumlen[1] / ntest);
|
|
1334
|
+
console.log("AvgL2:", cumlen[2] / ntest);
|
|
1335
|
+
console.log("AvgL3:", cumlen[3] / ntest);
|
|
1336
|
+
console.log("AvgT1:", cumlen[4] / ntest);
|
|
1337
|
+
console.log("AvgT2:", cumlen[5] / ntest);
|
|
1338
|
+
console.log("AvgT3:", cumlen[6] / ntest);
|
|
1339
|
+
}
|
|
1340
|
+
function solveFacelet(facelet, invSol) {
|
|
1341
|
+
var fc = new FtoCubie();
|
|
1342
|
+
if (fc.fromFacelet(facelet) == -1) {
|
|
1343
|
+
return "FTO Solver ERROR!";
|
|
1344
|
+
}
|
|
1345
|
+
return solver.solveFto(fc, invSol);
|
|
1346
|
+
}
|
|
1347
|
+
return {
|
|
1348
|
+
solveFacelet,
|
|
1349
|
+
FtoCubie,
|
|
1350
|
+
testbench
|
|
1351
|
+
};
|
|
1352
|
+
}();
|
|
1353
|
+
var fto_scrambler = function() {
|
|
1354
|
+
function getRandomScramble(solvedEdge, solvedCenter, solvedCorner) {
|
|
1355
|
+
var fc = new ftosolver.FtoCubie();
|
|
1356
|
+
if (!solvedEdge) {
|
|
1357
|
+
fc.ep = mathlib.rndPerm(12, true);
|
|
1358
|
+
}
|
|
1359
|
+
if (!solvedCenter) {
|
|
1360
|
+
fc.uf = mathlib.rndPerm(12, true);
|
|
1361
|
+
fc.rl = mathlib.rndPerm(12, true);
|
|
1362
|
+
}
|
|
1363
|
+
if (!solvedCorner) {
|
|
1364
|
+
fc.cp = mathlib.rndPerm(6, true);
|
|
1365
|
+
mathlib.setNOri(fc.co, mathlib.rn(32), 6, -2);
|
|
1366
|
+
}
|
|
1367
|
+
return new Alg(ftosolver.solveFacelet(fc.toFaceCube(), true));
|
|
1368
|
+
}
|
|
1369
|
+
function getLNTScramble(ufs) {
|
|
1370
|
+
var solved = false;
|
|
1371
|
+
var nCorn = ufs.length >> 1;
|
|
1372
|
+
var fc = new ftosolver.FtoCubie();
|
|
1373
|
+
var cp, co, uf;
|
|
1374
|
+
do {
|
|
1375
|
+
cp = mathlib.rndPerm(nCorn, true);
|
|
1376
|
+
co = mathlib.setNOri([], mathlib.rn(1 << nCorn >> 1), nCorn, -2);
|
|
1377
|
+
uf = mathlib.rndPerm(ufs.length, true);
|
|
1378
|
+
solved = true;
|
|
1379
|
+
for (var i = 0; i < ufs.length; i++) {
|
|
1380
|
+
solved = solved && ~~(ufs[uf[i]] / 3) == ~~(ufs[i] / 3);
|
|
1381
|
+
}
|
|
1382
|
+
for (var i = 0; i < nCorn; i++) {
|
|
1383
|
+
solved = solved && cp[i] == i && co[i] == 0;
|
|
1384
|
+
}
|
|
1385
|
+
} while (solved);
|
|
1386
|
+
for (var i = 0; i < nCorn; i++) {
|
|
1387
|
+
fc.cp[i] = cp[i];
|
|
1388
|
+
fc.co[i] = co[i];
|
|
1389
|
+
}
|
|
1390
|
+
for (var i = 0; i < ufs.length; i++) {
|
|
1391
|
+
fc.uf[ufs[i]] = ufs[uf[i]];
|
|
1392
|
+
}
|
|
1393
|
+
return ftosolver.solveFacelet(fc.toFaceCube(), true);
|
|
1394
|
+
}
|
|
1395
|
+
return {
|
|
1396
|
+
getRandomScramble: getRandomScramble.bind(null, false, false, false)
|
|
1397
|
+
};
|
|
1398
|
+
}();
|
|
1399
|
+
function getRandomFTOScramble() {
|
|
1400
|
+
return fto_scrambler.getRandomScramble();
|
|
1401
|
+
}
|
|
1402
|
+
export {
|
|
1403
|
+
getRandomFTOScramble
|
|
1404
|
+
};
|
|
1405
|
+
//# sourceMappingURL=search-dynamic-solve-fto-UOKDYVD5.js.map
|