Guest User

Untitled

a guest
Nov 17th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.08 KB | None | 0 0
  1. /*
  2.  
  3. scramble_333.js
  4.  
  5. 3x3x3 Solver / Scramble Generator in Javascript.
  6.  
  7. The core 3x3x3 code is from a min2phase solver by Shuang Chen.
  8. Compiled to Javascript using GWT and j2js project.
  9.  
  10. new feature:
  11. remove flip twist pruning table
  12. reduce memory used
  13. initialization time is decreased to about 40% (200ms / 500ms)
  14. average solving time is increased to about 150% (10ms / 7ms)
  15.  
  16. */
  17. "use strict";
  18.  
  19. if (typeof scramblers == "undefined") {
  20. var scramblers = {};
  21. }
  22.  
  23. scramblers["333fm"] = scramblers["333ft"] = scramblers["333bf"] = scramblers["333oh"] = scramblers["333"] = (function() {
  24.  
  25. "use strict";
  26.  
  27. function createArray(length1, length2){
  28. var result, i;
  29. result = [];
  30. if (length2 != undefined) {
  31. for (i=0; i<length1; i++) {
  32. result[i] = [];
  33. }
  34. }
  35. return result;
  36. }
  37.  
  38. function CoordCube_$clinit(){
  39. UDSliceMove = createArray(495, 18);
  40. TwistMove = createArray(324, 18);
  41. FlipMove = createArray(336, 18);
  42. UDSliceConj = createArray(495, 8);
  43. UDSliceTwistPrun = createArray(20048);
  44. UDSliceFlipPrun = createArray(20790);
  45. CPermMove = createArray(2768, 18);
  46. EPermMove = createArray(2768, 10);
  47. MPermMove = createArray(24, 10);
  48. MPermConj = createArray(24, 16);
  49. MCPermPrun = createArray(8304);
  50. MEPermPrun = createArray(8304);
  51. }
  52.  
  53. function getPruning(table, index){
  54. return table[index >> 3] >> ((index & 7) << 2) & 15;
  55. }
  56.  
  57. function initCPermMove(){
  58. var c, d, i, j;
  59. c = new CubieCube;
  60. d = new CubieCube;
  61. for (i = 0; i < 2768; ++i) {
  62. $setCPerm(c, epermS2R[i]);
  63. for (j = 0; j < 18; ++j) {
  64. cornMult(c, moveCube[j], d);
  65. CPermMove[i][j] = $getCPermSym(d);
  66. }
  67. }
  68. }
  69.  
  70. function initEPermMove(){
  71. var c, d, i, j;
  72. c = new CubieCube;
  73. d = new CubieCube;
  74. for (i = 0; i < 2768; ++i) {
  75. $setEPerm(c, epermS2R[i]);
  76. for (j = 0; j < 10; ++j) {
  77. EdgeMult(c, moveCube[ud2std[j]], d);
  78. EPermMove[i][j] = $getEPermSym(d);
  79. }
  80. }
  81. }
  82.  
  83. function initFlipMove(){
  84. var c, d, i, j;
  85. c = new CubieCube;
  86. d = new CubieCube;
  87. for (i = 0; i < 336; ++i) {
  88. $setFlip(c, FlipS2R[i]);
  89. for (j = 0; j < 18; ++j) {
  90. EdgeMult(c, moveCube[j], d);
  91. FlipMove[i][j] = $getFlipSym(d);
  92. }
  93. }
  94. }
  95.  
  96. function initMPermMoveConj(){
  97. var c, d, i, j;
  98. c = new CubieCube;
  99. d = new CubieCube;
  100. for (i = 0; i < 24; ++i) {
  101. setComb(c.ep, i << 9);
  102. for (j = 0; j < 10; ++j) {
  103. EdgeMult(c, moveCube[ud2std[j]], d);
  104. MPermMove[i][j] = getComb(d.ep, 8) >> 9;
  105. }
  106. for (j = 0; j < 16; ++j) {
  107. EdgeConjugate(c, SymInv[j], d);
  108. MPermConj[i][j] = getComb(d.ep, 8) >> 9;
  109. }
  110. }
  111. }
  112.  
  113. function initRawSymPrun(PrunTable, INV_DEPTH, RawMove, RawConj, SymMove, SymState, SymSwitch, moveMap, SYM_SHIFT){
  114. var N_MOVES, N_RAW, N_SIZE, N_SYM, SYM_MASK, check, depth, done, end, i, idx, idxx, inv, j, m, raw, rawx, select, sym, symState, symx, val, fill, len;
  115. SYM_MASK = (1 << SYM_SHIFT) - 1;
  116. N_RAW = RawMove.length;
  117. N_SYM = SymMove.length;
  118. N_SIZE = N_RAW * N_SYM;
  119. N_MOVES = RawMove[0].length;
  120. for (i = 0, len = (N_RAW * N_SYM + 7) >> 3; i < len; ++i) {
  121. PrunTable[i] = -1;
  122. }
  123. PrunTable[0] ^= 15;
  124. depth = 0;
  125. done = 1;
  126. while (done < N_SIZE) {
  127. inv = depth > INV_DEPTH;
  128. select = inv?15:depth;
  129. check = inv?depth:15;
  130. ++depth;
  131. fill = depth ^ 15;
  132. for (i = 0; i < N_SIZE;) {
  133. val = PrunTable[i >> 3];
  134. if (!inv && val == -1) {
  135. i += 8;
  136. continue;
  137. }
  138. for (end = i + 8 < N_SIZE?i + 8:N_SIZE; i < end; ++i , val >>= 4) {
  139. if ((val & 15) == select) {
  140. raw = i % N_RAW;
  141. sym = ~~(i / N_RAW);
  142. for (m = 0; m < N_MOVES; ++m) {
  143. symx = SymMove[sym][moveMap == null?m:moveMap[m]];
  144. rawx = RawConj[RawMove[raw][m] & 511][symx & SYM_MASK];
  145. symx >>>= SYM_SHIFT;
  146. idx = symx * N_RAW + rawx;
  147. if ((PrunTable[idx >> 3] >> ((idx & 7) << 2) & 15) == check) {
  148. ++done;
  149. if (inv) {
  150. PrunTable[i >> 3] ^= fill << ((i & 7) << 2);
  151. break;
  152. }
  153. else {
  154. PrunTable[idx >> 3] ^= fill << ((idx & 7) << 2);
  155. for (j = 1 , symState = SymState[symx]; (symState >>= 1) != 0; ++j) {
  156. if ((symState & 1) == 1) {
  157. idxx = symx * N_RAW + RawConj[rawx][j ^ (SymSwitch == null?0:SymSwitch[j])];
  158. if ((PrunTable[idxx >> 3] >> ((idxx & 7) << 2) & 15) == 15) {
  159. PrunTable[idxx >> 3] ^= fill << ((idxx & 7) << 2);
  160. ++done;
  161. }
  162. }
  163. }
  164. }
  165. }
  166. }
  167. }
  168. }
  169. }
  170. // console.log(done);
  171. }
  172. }
  173.  
  174. function initTwistMove(){
  175. var c, d, i, j;
  176. c = new CubieCube;
  177. d = new CubieCube;
  178. for (i = 0; i < 324; ++i) {
  179. $setTwist(c, TwistS2R[i]);
  180. for (j = 0; j < 18; ++j) {
  181. cornMult(c, moveCube[j], d);
  182. TwistMove[i][j] = $getTwistSym(d);
  183. }
  184. }
  185. }
  186.  
  187. function initUDSliceMoveConj(){
  188. var c, cx, d, i, j, k, udslice;
  189. c = new CubieCube;
  190. d = new CubieCube;
  191. for (i = 0; i < 495; ++i) {
  192. setComb(c.ep, i);
  193. for (j = 0; j < 18; j += 3) {
  194. EdgeMult(c, moveCube[j], d);
  195. UDSliceMove[i][j] = getComb(d.ep, 8);
  196. }
  197. for (j = 0; j < 16; j += 2) {
  198. EdgeConjugate(c, SymInv[j], d);
  199. UDSliceConj[i][j >>> 1] = getComb(d.ep, 8) & 511;
  200. }
  201. }
  202. for (i = 0; i < 495; ++i) {
  203. for (j = 0; j < 18; j += 3) {
  204. udslice = UDSliceMove[i][j];
  205. for (k = 1; k < 3; ++k) {
  206. cx = UDSliceMove[udslice & 511][j];
  207. udslice = permMult[udslice >>> 9][cx >>> 9] << 9 | cx & 511;
  208. UDSliceMove[i][j + k] = udslice;
  209. }
  210. }
  211. }
  212. }
  213.  
  214. var CPermMove, EPermMove, FlipMove, MCPermPrun, MEPermPrun, MPermConj, MPermMove, TwistMove, UDSliceConj, UDSliceFlipPrun, UDSliceMove, UDSliceTwistPrun;
  215. function CubieCube_$clinit(){
  216. CubeSym = createArray(16);
  217. moveCube = createArray(18);
  218. SymInv = createArray(16, 1);
  219. SymMult = createArray(16, 16);
  220. SymMove = createArray(16, 18);
  221. Sym8Mult = createArray(8, 8);
  222. Sym8Move = createArray(8, 18);
  223. Sym8MultInv = createArray(8, 8);
  224. SymMoveUD = createArray(16, 10);
  225. FlipS2R = createArray(336);
  226. TwistS2R = createArray(324);
  227. epermS2R = createArray(2768);
  228. e2c = [0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 0, 0, 0, 0];
  229. MtoEPerm = createArray(40320);
  230. SymStateTwist = createArray(324);
  231. SymStateFlip = createArray(336);
  232. SymStatePerm = createArray(2768);
  233. urf1 = new CubieCube1(2531, 1373, 67026819, 1367);
  234. urf2 = new CubieCube1(2089, 1906, 322752913, 2040);
  235. urfMove = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], [6, 7, 8, 0, 1, 2, 3, 4, 5, 15, 16, 17, 9, 10, 11, 12, 13, 14], [3, 4, 5, 6, 7, 8, 0, 1, 2, 12, 13, 14, 15, 16, 17, 9, 10, 11], [2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17, 16, 15], [8, 7, 6, 2, 1, 0, 5, 4, 3, 17, 16, 15, 11, 10, 9, 14, 13, 12], [5, 4, 3, 8, 7, 6, 2, 1, 0, 14, 13, 12, 17, 16, 15, 11, 10, 9]];
  236. }
  237.  
  238. function CubieCube_$$init(obj){
  239. obj.cp = [0, 1, 2, 3, 4, 5, 6, 7];
  240. obj.co = [0, 0, 0, 0, 0, 0, 0, 0];
  241. obj.ep = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  242. obj.eo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  243. }
  244.  
  245. function $copy(obj, c){
  246. var i;
  247. for (i = 0; i < 8; ++i) {
  248. obj.cp[i] = c.cp[i];
  249. obj.co[i] = c.co[i];
  250. }
  251. for (i = 0; i < 12; ++i) {
  252. obj.ep[i] = c.ep[i];
  253. obj.eo[i] = c.eo[i];
  254. }
  255. }
  256.  
  257. function $getCPermSym(obj){
  258. var idx;
  259. idx = epermR2S[get8Perm(obj.cp)];
  260. idx ^= e2c[idx & 15];
  261. return idx;
  262. }
  263.  
  264. function $getEPermSym(obj){
  265. return epermR2S[get8Perm(obj.ep)];
  266. }
  267.  
  268. function $getFlip(obj){
  269. var i, idx;
  270. idx = 0;
  271. for (i = 0; i < 11; ++i) {
  272. idx <<= 1;
  273. idx |= obj.eo[i];
  274. }
  275. return idx;
  276. }
  277.  
  278. function $getFlipSym(obj){
  279. return FlipR2S[$getFlip(obj)];
  280. }
  281.  
  282. function $getTwist(obj){
  283. var i, idx;
  284. idx = 0;
  285. for (i = 0; i < 7; ++i) {
  286. idx *= 3;
  287. idx += obj.co[i];
  288. }
  289. return idx;
  290. }
  291.  
  292. function $getTwistSym(obj){
  293. return TwistR2S[$getTwist(obj)];
  294. }
  295.  
  296. function $invCubieCube(obj){
  297. var corn, edge, ori;
  298. for (edge = 0; edge < 12; ++edge)
  299. obj.temps.ep[obj.ep[edge]] = edge;
  300. for (edge = 0; edge < 12; ++edge)
  301. obj.temps.eo[edge] = obj.eo[obj.temps.ep[edge]];
  302. for (corn = 0; corn < 8; ++corn)
  303. obj.temps.cp[obj.cp[corn]] = corn;
  304. for (corn = 0; corn < 8; ++corn) {
  305. ori = obj.co[obj.temps.cp[corn]];
  306. obj.temps.co[corn] = -ori;
  307. obj.temps.co[corn] < 0 && (obj.temps.co[corn] = obj.temps.co[corn] + 3);
  308. }
  309. $copy(obj, obj.temps);
  310. }
  311.  
  312. function $setCPerm(obj, idx){
  313. set8Perm(obj.cp, idx);
  314. }
  315.  
  316. function $setEPerm(obj, idx){
  317. set8Perm(obj.ep, idx);
  318. }
  319.  
  320. function $setFlip(obj, idx){
  321. var i, parity;
  322. parity = 0;
  323. for (i = 10; i >= 0; --i) {
  324. parity ^= obj.eo[i] = (idx & 1);
  325. idx >>= 1;
  326. }
  327. obj.eo[11] = parity;
  328. }
  329.  
  330. function $setTwist(obj, idx){
  331. var i, twst;
  332. twst = 0;
  333. for (i = 6; i >= 0; --i) {
  334. twst += obj.co[i] = idx % 3;
  335. idx = ~~(idx / 3);
  336. }
  337. obj.co[7] = (15 - twst) % 3;
  338. }
  339.  
  340. function $verify(obj){
  341. var c, cornMask, e, edgeMask, i, sum;
  342. sum = 0;
  343. edgeMask = 0;
  344. for (e = 0; e < 12; ++e)
  345. edgeMask |= 1 << obj.ep[e];
  346. if (edgeMask != 4095)
  347. return -2;
  348. for (i = 0; i < 12; ++i)
  349. sum ^= obj.eo[i];
  350. if (sum % 2 != 0)
  351. return -3;
  352. cornMask = 0;
  353. for (c = 0; c < 8; ++c)
  354. cornMask |= 1 << obj.cp[c];
  355. if (cornMask != 255)
  356. return -4;
  357. sum = 0;
  358. for (i = 0; i < 8; ++i)
  359. sum += obj.co[i];
  360. if (sum % 3 != 0)
  361. return -5;
  362. if ((getNParity(getNPerm(obj.ep, 12), 12) ^ getNParity(get8Perm(obj.cp), 8)) != 0)
  363. return -6;
  364. return 0;
  365. }
  366.  
  367. function cornConjugate(a, idx, b){
  368. var corn, oriA, oriB, s, sinv;
  369. sinv = CubeSym[SymInv[idx]];
  370. s = CubeSym[idx];
  371. for (corn = 0; corn < 8; ++corn) {
  372. b.cp[corn] = sinv.cp[a.cp[s.cp[corn]]];
  373. oriA = sinv.co[a.cp[s.cp[corn]]];
  374. oriB = a.co[s.cp[corn]];
  375. b.co[corn] = oriA < 3?oriB:(3 - oriB) % 3;
  376. }
  377. }
  378.  
  379. function cornMult(a, b, prod){
  380. var corn, ori, oriA, oriB;
  381. for (corn = 0; corn < 8; ++corn) {
  382. prod.cp[corn] = a.cp[b.cp[corn]];
  383. oriA = a.co[b.cp[corn]];
  384. oriB = b.co[corn];
  385. ori = oriA;
  386. ori += oriA < 3?oriB:6 - oriB;
  387. ori %= 3;
  388. oriA >= 3 ^ oriB >= 3 && (ori += 3);
  389. prod.co[corn] = ori;
  390. }
  391. }
  392.  
  393. function CubieCube(){
  394. CubieCube_$$init(this);
  395. }
  396.  
  397. function CubieCube1(cperm, twist, eperm, flip){
  398. CubieCube_$$init(this);
  399. set8Perm(this.cp, cperm);
  400. $setTwist(this, twist);
  401. setNPerm(this.ep, eperm, 12);
  402. $setFlip(this, flip);
  403. }
  404.  
  405. function CubieCube2(c){
  406. CubieCube_$$init(this);
  407. $copy(this, c);
  408. }
  409.  
  410. function EdgeConjugate(a, idx, b){
  411. var ed, s, sinv;
  412. sinv = CubeSym[SymInv[idx]];
  413. s = CubeSym[idx];
  414. for (ed = 0; ed < 12; ++ed) {
  415. b.ep[ed] = sinv.ep[a.ep[s.ep[ed]]];
  416. b.eo[ed] = s.eo[ed] ^ a.eo[s.ep[ed]] ^ sinv.eo[a.ep[s.ep[ed]]];
  417. }
  418. }
  419.  
  420. function EdgeMult(a, b, prod){
  421. var ed;
  422. for (ed = 0; ed < 12; ++ed) {
  423. prod.ep[ed] = a.ep[b.ep[ed]];
  424. prod.eo[ed] = b.eo[ed] ^ a.eo[b.ep[ed]];
  425. }
  426. }
  427.  
  428. function initFlipSym2Raw(){
  429. var c, count, d, i, idx, occ, s;
  430. c = new CubieCube;
  431. d = new CubieCube;
  432. occ = createArray(64);
  433. count = 0;
  434. for (i = 0; i < 64; occ[i++] = 0) {}
  435. FlipR2S = createArray(2048);
  436. for (i = 0; i < 2048; ++i) {
  437. if ((occ[i >> 5] & 1 << (i & 31)) == 0) {
  438. $setFlip(c, i);
  439. for (s = 0; s < 16; s += 2) {
  440. EdgeConjugate(c, s, d);
  441. idx = $getFlip(d);
  442. idx == i && (SymStateFlip[count] |= 1 << (s >> 1));
  443. occ[idx >> 5] |= 1 << (idx & 31);
  444. FlipR2S[idx] = count << 3 | s >> 1;
  445. }
  446. FlipS2R[count++] = i;
  447. }
  448. }
  449. }
  450.  
  451. function initMove(){
  452. var a, p;
  453. moveCube[0] = new CubieCube1(15120, 0, 119750400, 0);
  454. moveCube[3] = new CubieCube1(21021, 1494, 323403417, 0);
  455. moveCube[6] = new CubieCube1(8064, 1236, 29441808, 550);
  456. moveCube[9] = new CubieCube1(9, 0, 5880, 0);
  457. moveCube[12] = new CubieCube1(1230, 412, 2949660, 0);
  458. moveCube[15] = new CubieCube1(224, 137, 328552, 137);
  459. for (a = 0; a < 18; a += 3) {
  460. for (p = 0; p < 2; ++p) {
  461. moveCube[a + p + 1] = new CubieCube;
  462. EdgeMult(moveCube[a + p], moveCube[a], moveCube[a + p + 1]);
  463. cornMult(moveCube[a + p], moveCube[a], moveCube[a + p + 1]);
  464. }
  465. }
  466. }
  467.  
  468. function initPermSym2Raw(){
  469. var a, b, c, count, d, i, idx, m, occ, s;
  470. c = new CubieCube;
  471. d = new CubieCube;
  472. occ = createArray(1260);
  473. count = 0;
  474. for (i = 0; i < 1260; occ[i++] = 0) {}
  475. epermR2S = createArray(40320);
  476. for (i = 0; i < 40320; ++i) {
  477. if ((occ[i >> 5] & 1 << (i & 31)) == 0) {
  478. set8Perm(c.ep, i);
  479. for (s = 0; s < 16; ++s) {
  480. EdgeConjugate(c, s, d);
  481. idx = get8Perm(d.ep);
  482. idx == i && (SymStatePerm[count] |= 1 << s);
  483. occ[idx >> 5] |= 1 << (idx & 31);
  484. a = getComb(d.ep, 0);
  485. b = getComb(d.ep, 4) >> 9;
  486. m = 494 - (a & 511) + (a >> 9) * 70 + b * 1680;
  487. MtoEPerm[m] = epermR2S[idx] = count << 4 | s;
  488. }
  489. epermS2R[count++] = i;
  490. }
  491. }
  492. }
  493.  
  494. function initSym(){
  495. var c, d, f2, i, j, k, lr2, m, s, t, u4;
  496. c = new CubieCube;
  497. d = new CubieCube;
  498. f2 = new CubieCube1(28783, 0, 259268407, 0);
  499. u4 = new CubieCube1(15138, 0, 119765538, 7);
  500. lr2 = new CubieCube1(5167, 0, 83473207, 0);
  501. lr2.co = [3, 3, 3, 3, 3, 3, 3, 3];
  502. for (i = 0; i < 16; ++i) {
  503. CubeSym[i] = new CubieCube2(c);
  504. cornMult(c, u4, d);
  505. EdgeMult(c, u4, d);
  506. t = d;
  507. d = c;
  508. c = t;
  509. if (i % 4 == 3) {
  510. cornMult(t, lr2, d);
  511. EdgeMult(t, lr2, d);
  512. t = d;
  513. d = c;
  514. c = t;
  515. }
  516. if (i % 8 == 7) {
  517. cornMult(t, f2, d);
  518. EdgeMult(t, f2, d);
  519. t = d;
  520. d = c;
  521. c = t;
  522. }
  523. }
  524. for (i = 0; i < 16; ++i) {
  525. for (j = 0; j < 16; ++j) {
  526. cornMult(CubeSym[i], CubeSym[j], c);
  527. for (k = 0; k < 16; ++k) {
  528. if (CubeSym[k].cp[0] == c.cp[0] && CubeSym[k].cp[1] == c.cp[1] && CubeSym[k].cp[2] == c.cp[2]) {
  529. SymMult[i][j] = k;
  530. k == 0 && (SymInv[i] = j);
  531. break;
  532. }
  533. }
  534. }
  535. }
  536. for (j = 0; j < 18; ++j) {
  537. for (s = 0; s < 16; ++s) {
  538. cornConjugate(moveCube[j], SymInv[s], c);
  539. CONTINUE: for (m = 0; m < 18; ++m) {
  540. for (i = 0; i < 8; i += 2) {
  541. if (c.cp[i] != moveCube[m].cp[i]) {
  542. continue CONTINUE;
  543. }
  544. }
  545. SymMove[s][j] = m;
  546. break;
  547. }
  548. }
  549. }
  550. for (j = 0; j < 10; ++j) {
  551. for (s = 0; s < 16; ++s) {
  552. SymMoveUD[s][j] = std2ud[SymMove[s][ud2std[j]]];
  553. }
  554. }
  555. for (j = 0; j < 8; ++j) {
  556. for (s = 0; s < 8; ++s) {
  557. Sym8Mult[j][s] = SymMult[j << 1][s << 1] >> 1;
  558. Sym8MultInv[j][s] = SymMult[j << 1][SymInv[s << 1]] >> 1;
  559. }
  560. }
  561. for (j = 0; j < 18; ++j) {
  562. for (s = 0; s < 8; ++s) {
  563. Sym8Move[s][j] = SymMove[s << 1][j];
  564. }
  565. }
  566. }
  567.  
  568. function initTwistSym2Raw(){
  569. var c, count, d, i, idx, occ, s;
  570. c = new CubieCube;
  571. d = new CubieCube;
  572. occ = createArray(69);
  573. count = 0;
  574. for (i = 0; i < 69; occ[i++] = 0) {}
  575. TwistR2S = createArray(2187);
  576. for (i = 0; i < 2187; ++i) {
  577. if ((occ[i >> 5] & 1 << (i & 31)) == 0) {
  578. $setTwist(c, i);
  579. for (s = 0; s < 16; s += 2) {
  580. cornConjugate(c, s, d);
  581. idx = $getTwist(d);
  582. idx == i && (SymStateTwist[count] = (SymStateTwist[count] | 1 << (s >> 1)));
  583. occ[idx >> 5] |= 1 << (idx & 31);
  584. TwistR2S[idx] = (count << 3 | s >> 1);
  585. }
  586. TwistS2R[count++] = i;
  587. }
  588. }
  589. }
  590.  
  591. var _ = CubieCube2.prototype = CubieCube1.prototype = CubieCube.prototype;
  592. _.temps = null;
  593. var CubeSym, epermR2S = null, epermS2R, FlipR2S = null, FlipS2R, MtoEPerm, Sym8Move, Sym8Mult, Sym8MultInv, SymInv, SymMove, SymMoveUD, SymMult, SymStateFlip, SymStatePerm, SymStateTwist, TwistR2S = null, TwistS2R, e2c, moveCube, urf1, urf2, urfMove;
  594. function $initPhase2(obj){
  595. var cidx, csym, cx, d4e, depth2, edge, esym, i, lm, m, mid, prun, u4e;
  596. if (+new Date > (obj.solution == null?obj.timeOut:obj.timeMin)) {
  597. return 0;
  598. }
  599. obj.valid2 = Math.min(obj.valid2, obj.valid1);
  600. cidx = obj.corn[obj.valid1] >>> 4;
  601. csym = obj.corn[obj.valid1] & 15;
  602. for (i = obj.valid1; i < obj.depth1; ++i) {
  603. m = obj.move[i];
  604. cidx = CPermMove[cidx][SymMove[csym][m]];
  605. csym = SymMult[cidx & 15][csym];
  606. cidx >>>= 4;
  607. obj.corn[i + 1] = cidx << 4 | csym;
  608. cx = UDSliceMove[obj.mid4[i] & 511][m];
  609. obj.mid4[i + 1] = permMult[obj.mid4[i] >>> 9][cx >>> 9] << 9 | cx & 511;
  610. }
  611. obj.valid1 = obj.depth1;
  612. mid = obj.mid4[obj.depth1] >>> 9;
  613. prun = getPruning(MCPermPrun, cidx * 24 + MPermConj[mid][csym]);
  614. if (prun >= obj.maxDep2) {
  615. return prun > obj.maxDep2?2:1;
  616. }
  617. u4e = obj.ud8e[obj.valid2] >>> 16;
  618. d4e = obj.ud8e[obj.valid2] & 65535;
  619. for (i = obj.valid2; i < obj.depth1; ++i) {
  620. m = obj.move[i];
  621. cx = UDSliceMove[u4e & 511][m];
  622. u4e = permMult[u4e >>> 9][cx >>> 9] << 9 | cx & 511;
  623. cx = UDSliceMove[d4e & 511][m];
  624. d4e = permMult[d4e >>> 9][cx >>> 9] << 9 | cx & 511;
  625. obj.ud8e[i + 1] = u4e << 16 | d4e;
  626. }
  627. obj.valid2 = obj.depth1;
  628. edge = MtoEPerm[494 - (u4e & 511) + (u4e >>> 9) * 70 + (d4e >>> 9) * 1680];
  629. esym = edge & 15;
  630. edge >>>= 4;
  631. prun = Math.max(getPruning(MEPermPrun, edge * 24 + MPermConj[mid][esym]), prun);
  632. if (prun >= obj.maxDep2) {
  633. return prun > obj.maxDep2?2:1;
  634. }
  635. lm = obj.depth1 == 0?10:std2ud[~~(obj.move[obj.depth1 - 1] / 3) * 3 + 1];
  636. for (depth2 = prun; depth2 < obj.maxDep2; ++depth2) {
  637. if ($phase2(obj, edge, esym, cidx, csym, mid, depth2, obj.depth1, lm)) {
  638. obj.sol = obj.depth1 + depth2;
  639. obj.maxDep2 = Math.min(12, obj.sol - obj.depth1);
  640. obj.solution = $solutionToString(obj);
  641. return (+new Date > obj.timeMin)?0:1;
  642. }
  643. }
  644. return 1;
  645. }
  646.  
  647. function $phase1(obj, twist, tsym, flip, fsym, slice, maxl, lm){
  648. var axis, flipx, fsymx, m, power, prun, ret, slicex, tsymx, twistx;
  649. if (twist == 0 && flip == 0 && slice == 0 && maxl < 5) {
  650. return maxl == 0?$initPhase2(obj):1;
  651. }
  652. for (axis = 0; axis < 18; axis += 3) {
  653. if (axis == lm || axis == lm - 9) {
  654. continue;
  655. }
  656. for (power = 0; power < 3; ++power) {
  657. m = axis + power;
  658. slicex = UDSliceMove[slice][m] & 511;
  659. twistx = TwistMove[twist][Sym8Move[tsym][m]];
  660. tsymx = Sym8Mult[twistx & 7][tsym];
  661. twistx >>>= 3;
  662. prun = getPruning(UDSliceTwistPrun, twistx * 495 + UDSliceConj[slicex][tsymx]);
  663. if (prun > maxl) {
  664. break;
  665. }
  666. else if (prun == maxl) {
  667. continue;
  668. }
  669. flipx = FlipMove[flip][Sym8Move[fsym][m]];
  670. fsymx = Sym8Mult[flipx & 7][fsym];
  671. flipx >>>= 3;
  672. prun = getPruning(UDSliceFlipPrun, flipx * 495 + UDSliceConj[slicex][fsymx]);
  673. if (prun > maxl) {
  674. break;
  675. }
  676. else if (prun == maxl) {
  677. continue;
  678. }
  679. obj.move[obj.depth1 - maxl] = m;
  680. obj.valid1 = Math.min(obj.valid1, obj.depth1 - maxl);
  681. ret = $phase1(obj, twistx, tsymx, flipx, fsymx, slicex, maxl - 1, axis);
  682. if (ret != 1) {
  683. return ret >> 1;
  684. }
  685. }
  686. }
  687. return 1;
  688. }
  689.  
  690. function $phase2(obj, eidx, esym, cidx, csym, mid, maxl, depth, lm){
  691. var cidxx, csymx, eidxx, esymx, m, midx;
  692. if (eidx == 0 && cidx == 0 && mid == 0) {
  693. return true;
  694. }
  695. for (m = 0; m < 10; ++m) {
  696. if (ckmv2[lm][m]) {
  697. continue;
  698. }
  699. midx = MPermMove[mid][m];
  700. cidxx = CPermMove[cidx][SymMove[csym][ud2std[m]]];
  701. csymx = SymMult[cidxx & 15][csym];
  702. cidxx >>>= 4;
  703. if (getPruning(MCPermPrun, cidxx * 24 + MPermConj[midx][csymx]) >= maxl) {
  704. continue;
  705. }
  706. eidxx = EPermMove[eidx][SymMoveUD[esym][m]];
  707. esymx = SymMult[eidxx & 15][esym];
  708. eidxx >>>= 4;
  709. if (getPruning(MEPermPrun, eidxx * 24 + MPermConj[midx][esymx]) >= maxl) {
  710. continue;
  711. }
  712. if ($phase2(obj, eidxx, esymx, cidxx, csymx, midx, maxl - 1, depth + 1, m)) {
  713. obj.move[depth] = ud2std[m];
  714. return true;
  715. }
  716. }
  717. return false;
  718. }
  719.  
  720. function $solution(obj, facelets, maxDepth, timeOut, timeMin, verbose){
  721. var check;
  722. check = Search_$verify(obj, facelets);
  723. if (check != 0) {
  724. return 'Error ' + (check < 0?-check:check);
  725. }
  726. obj.sol = (maxDepth || 21) + 1;
  727. obj.timeOut = +new Date + (timeOut || 1000);
  728. obj.timeMin = obj.timeOut + Math.min((timeMin || 50) - (timeOut || 1000), 0);
  729. obj.verbose = verbose || 2;
  730. obj.solution = null;
  731. return $solve(obj, obj.cc);
  732. }
  733.  
  734. function $solutionToString(obj){
  735. var s, sb, urf;
  736. sb = '';
  737. urf = (obj.verbose & 2) != 0?(obj.urfIdx + 3) % 6:obj.urfIdx;
  738. if (urf < 3) {
  739. for (s = 0; s < obj.depth1; ++s) {
  740. sb += move2str[urfMove[urf][obj.move[s]]] + ' ';
  741. }
  742. (obj.verbose & 1) != 0 && (sb += '. ');
  743. for (s = obj.depth1; s < obj.sol; ++s) {
  744. sb += move2str[urfMove[urf][obj.move[s]]] + ' ';
  745. }
  746. }
  747. else {
  748. for (s = obj.sol - 1; s >= obj.depth1; --s) {
  749. sb += move2str[urfMove[urf][obj.move[s]]] + ' ';
  750. }
  751. (obj.verbose & 1) != 0 && (sb += '. ');
  752. for (s = obj.depth1 - 1; s >= 0; --s) {
  753. sb += move2str[urfMove[urf][obj.move[s]]] + ' ';
  754. }
  755. }
  756. (obj.verbose & 4) != 0 && (sb += '(' + obj.sol + 'f)');
  757. return sb;
  758. }
  759.  
  760. function $solve(obj, c){
  761. var conjMask, i, j;
  762. conjMask = 0;
  763. for (i = 0; i < 6; ++i) {
  764. obj.twist[i] = $getTwistSym(c);
  765. obj.flip[i] = $getFlipSym(c);
  766. obj.slice[i] = getComb(c.ep, 8);
  767. obj.corn0[i] = $getCPermSym(c);
  768. obj.ud8e0[i] = getComb(c.ep, 0) << 16 | getComb(c.ep, 4);
  769. for (j = 0; j < i; ++j) {
  770. if (obj.twist[i] == obj.twist[j] && obj.flip[i] == obj.flip[j] && obj.slice[i] == obj.slice[j] && obj.corn0[i] == obj.corn0[j] && obj.ud8e0[i] == obj.ud8e0[j]) {
  771. conjMask |= 1 << i;
  772. break;
  773. }
  774. }
  775. (conjMask & 1 << i) == 0 && (obj.prun[i] = Math.max(Math.max(getPruning(UDSliceTwistPrun, (obj.twist[i] >>> 3) * 495 + UDSliceConj[obj.slice[i] & 511][obj.twist[i] & 7]), getPruning(UDSliceFlipPrun, (obj.flip[i] >>> 3) * 495 + UDSliceConj[obj.slice[i] & 511][obj.flip[i] & 7])), 0));
  776. !c.temps && (c.temps = new CubieCube);
  777. cornMult(urf2, c, c.temps);
  778. cornMult(c.temps, urf1, c);
  779. EdgeMult(urf2, c, c.temps);
  780. EdgeMult(c.temps, urf1, c);
  781. i == 2 && $invCubieCube(c);
  782. }
  783. for (obj.depth1 = 0; obj.depth1 < obj.sol; ++obj.depth1) {
  784. obj.maxDep2 = Math.min(12, obj.sol - obj.depth1);
  785. for (obj.urfIdx = 0; obj.urfIdx < 6; ++obj.urfIdx) {
  786. if ((conjMask & 1 << obj.urfIdx) != 0) {
  787. continue;
  788. }
  789. obj.corn[0] = obj.corn0[obj.urfIdx];
  790. obj.mid4[0] = obj.slice[obj.urfIdx];
  791. obj.ud8e[0] = obj.ud8e0[obj.urfIdx];
  792. if (obj.prun[obj.urfIdx] <= obj.depth1 && $phase1(obj, obj.twist[obj.urfIdx] >>> 3, obj.twist[obj.urfIdx] & 7, obj.flip[obj.urfIdx] >>> 3, obj.flip[obj.urfIdx] & 7, obj.slice[obj.urfIdx] & 511, obj.depth1, -1) == 0) {
  793. return obj.solution == null?'Error 8':obj.solution;
  794. }
  795. }
  796. }
  797. return obj.solution == null?'Error 7':obj.solution;
  798. }
  799.  
  800. function Search_$verify(obj, facelets){
  801. var $e0, count, i;
  802. count = 0;
  803. for (i = 0; i < 54; ++i) {
  804. switch (facelets.charCodeAt(i)) {
  805. case 85:
  806. obj.f[i] = 0;
  807. break;
  808. case 82:
  809. obj.f[i] = 1;
  810. break;
  811. case 70:
  812. obj.f[i] = 2;
  813. break;
  814. case 68:
  815. obj.f[i] = 3;
  816. break;
  817. case 76:
  818. obj.f[i] = 4;
  819. break;
  820. case 66:
  821. obj.f[i] = 5;
  822. break;
  823. default:return -1;
  824. }
  825. count += 1 << (obj.f[i] << 2);
  826. }
  827. if (count != 10066329) {
  828. return -1;
  829. }
  830. toCubieCube(obj.f, obj.cc);
  831. return $verify(obj.cc);
  832. }
  833.  
  834. function Search(){
  835. this.move = [];
  836. this.corn = [];
  837. this.mid4 = [];
  838. this.ud8e = [];
  839. this.twist = [];
  840. this.flip = [];
  841. this.slice = [];
  842. this.corn0 = [];
  843. this.ud8e0 = [];
  844. this.prun = [];
  845. this.f = [];
  846. this.cc = new CubieCube;
  847. }
  848.  
  849. _ = Search.prototype;
  850. _.depth1 = 0;
  851. _.maxDep2 = 0;
  852. _.sol = 0;
  853. _.solution = null;
  854. _.timeMin = 0;
  855. _.timeOut = 0;
  856. _.urfIdx = 0;
  857. _.valid1 = 0;
  858. _.valid2 = 0;
  859. _.verbose = 0;
  860.  
  861. function Util_$clinit(){
  862. var arr1, arr2, arr3, i, ix, j, jx, k;
  863. cornerFacelet = [[8, 9, 20], [6, 18, 38], [0, 36, 47], [2, 45, 11], [29, 26, 15], [27, 44, 24], [33, 53, 42], [35, 17, 51]];
  864. edgeFacelet = [[5, 10], [7, 19], [3, 37], [1, 46], [32, 16], [28, 25], [30, 43], [34, 52], [23, 12], [21, 41], [50, 39], [48, 14]];
  865. Cnk = createArray(12, 12);
  866. fact = createArray(13);
  867. permMult = createArray(24, 24);
  868. move2str = ['U ', 'U2', "U'", 'R ', 'R2', "R'", 'F ', 'F2', "F'", 'D ', 'D2', "D'", 'L ', 'L2', "L'", 'B ', 'B2', "B'"];
  869. ud2std = [0, 1, 2, 4, 7, 9, 10, 11, 13, 16];
  870. std2ud = createArray(18);
  871. ckmv2 = createArray(11, 10);
  872. for (i = 0; i < 10; ++i) {
  873. std2ud[ud2std[i]] = i;
  874. }
  875. for (i = 0; i < 10; ++i) {
  876. for (j = 0; j < 10; ++j) {
  877. ix = ud2std[i];
  878. jx = ud2std[j];
  879. ckmv2[i][j] = ~~(ix / 3) == ~~(jx / 3) || ~~(ix / 3) % 3 == ~~(jx / 3) % 3 && ix >= jx;
  880. }
  881. ckmv2[10][i] = false;
  882. }
  883. fact[0] = 1;
  884. for (i=0; i<12; ++i)
  885. for (j=0; j<12; ++j)
  886. Cnk[i][j] = 0;
  887. for (i = 0; i < 12; ++i) {
  888. Cnk[i][0] = Cnk[i][i] = 1;
  889. fact[i + 1] = fact[i] * (i + 1);
  890. for (j = 1; j < i; ++j) {
  891. Cnk[i][j] = Cnk[i - 1][j - 1] + Cnk[i - 1][j];
  892. }
  893. }
  894. arr1 = createArray(4);
  895. arr2 = createArray(4);
  896. arr3 = createArray(4);
  897. for (i = 0; i < 24; ++i) {
  898. for (j = 0; j < 24; ++j) {
  899. setNPerm(arr1, i, 4);
  900. setNPerm(arr2, j, 4);
  901. for (k = 0; k < 4; ++k) {
  902. arr3[k] = arr1[arr2[k]];
  903. }
  904. permMult[i][j] = getNPerm(arr3, 4);
  905. }
  906. }
  907. }
  908.  
  909. function binarySearch(arr, key){
  910. var l, length, mid, r, val;
  911. length = arr.length;
  912. if (key <= arr[length - 1]) {
  913. l = 0;
  914. r = length - 1;
  915. while (l <= r) {
  916. mid = (l + r) >>> 1;
  917. val = arr[mid];
  918. if (key > val) {
  919. l = mid + 1;
  920. }
  921. else if (key < val) {
  922. r = mid - 1;
  923. }
  924. else {
  925. return mid;
  926. }
  927. }
  928. }
  929. return 65535;
  930. }
  931.  
  932. function get8Perm(arr){
  933. var i, idx, v, val;
  934. idx = 0;
  935. val = 1985229328;
  936. for (i = 0; i < 7; ++i) {
  937. v = arr[i] << 2;
  938. idx = (8 - i) * idx + (val >> v & 7);
  939. val -= 286331152 << v;
  940. }
  941. return idx;
  942. }
  943.  
  944. function getComb(arr, mask){
  945. var i, idxC, idxP, r, v, val;
  946. idxC = 0;
  947. idxP = 0;
  948. r = 4;
  949. val = 291;
  950. for (i = 11; i >= 0; --i) {
  951. if ((arr[i] & 12) == mask) {
  952. v = (arr[i] & 3) << 2;
  953. idxP = r * idxP + (val >> v & 15);
  954. val -= 273 >> 12 - v;
  955. idxC += Cnk[i][r--];
  956. }
  957. }
  958. return idxP << 9 | 494 - idxC;
  959. }
  960.  
  961. function getNParity(idx, n){
  962. var i, p;
  963. p = 0;
  964. for (i = n - 2; i >= 0; --i) {
  965. p ^= idx % (n - i);
  966. idx = ~~(idx / (n - i));
  967. }
  968. return p & 1;
  969. }
  970.  
  971. function getNPerm(arr, n){
  972. var i, idx, j;
  973. idx = 0;
  974. for (i = 0; i < n; ++i) {
  975. idx *= n - i;
  976. for (j = i + 1; j < n; ++j) {
  977. arr[j] < arr[i] && ++idx;
  978. }
  979. }
  980. return idx;
  981. }
  982.  
  983. function set8Perm(arr, idx){
  984. var i, m, p, v, val;
  985. val = 1985229328;
  986. for (i = 0; i < 7; ++i) {
  987. p = fact[7 - i];
  988. v = ~~(idx / p);
  989. idx -= v * p;
  990. v <<= 2;
  991. arr[i] = val >> v & 7;
  992. m = (1 << v) - 1;
  993. val = (val & m) + (val >> 4 & ~m);
  994. }
  995. arr[7] = val;
  996. }
  997.  
  998. function setComb(arr, idx){
  999. var fill, i, idxC, idxP, m, p, r, v, val;
  1000. r = 4;
  1001. fill = 11;
  1002. val = 291;
  1003. idxC = 494 - (idx & 511);
  1004. idxP = idx >>> 9;
  1005. for (i = 11; i >= 0; --i) {
  1006. if (idxC >= Cnk[i][r]) {
  1007. idxC -= Cnk[i][r--];
  1008. p = fact[r & 3];
  1009. v = ~~(idxP / p) << 2;
  1010. idxP %= p;
  1011. arr[i] = val >> v & 3 | 8;
  1012. m = (1 << v) - 1;
  1013. val = (val & m) + (val >> 4 & ~m);
  1014. }
  1015. else {
  1016. (fill & 12) == 8 && (fill -= 4);
  1017. arr[i] = fill--;
  1018. }
  1019. }
  1020. }
  1021.  
  1022. function setNPerm(arr, idx, n){
  1023. var i, j;
  1024. arr[n - 1] = 0;
  1025. for (i = n - 2; i >= 0; --i) {
  1026. arr[i] = idx % (n - i);
  1027. idx = ~~(idx / (n - i));
  1028. for (j = i + 1; j < n; ++j) {
  1029. arr[j] >= arr[i] && ++arr[j];
  1030. }
  1031. }
  1032. }
  1033.  
  1034. function toCubieCube(f, ccRet){
  1035. var col1, col2, i, j, ori;
  1036. for (i = 0; i < 8; ++i)
  1037. ccRet.cp[i] = 0;
  1038. for (i = 0; i < 12; ++i)
  1039. ccRet.ep[i] = 0;
  1040. for (i = 0; i < 8; ++i) {
  1041. for (ori = 0; ori < 3; ++ori)
  1042. if (f[cornerFacelet[i][ori]] == 0 || f[cornerFacelet[i][ori]] == 3)
  1043. break;
  1044. col1 = f[cornerFacelet[i][(ori + 1) % 3]];
  1045. col2 = f[cornerFacelet[i][(ori + 2) % 3]];
  1046. for (j = 0; j < 8; ++j) {
  1047. if (col1 == ~~(cornerFacelet[j][1] / 9) && col2 == ~~(cornerFacelet[j][2] / 9)) {
  1048. ccRet.cp[i] = j;
  1049. ccRet.co[i] = ori % 3;
  1050. break;
  1051. }
  1052. }
  1053. }
  1054. for (i = 0; i < 12; ++i) {
  1055. for (j = 0; j < 12; ++j) {
  1056. if (f[edgeFacelet[i][0]] == ~~(edgeFacelet[j][0] / 9) && f[edgeFacelet[i][1]] == ~~(edgeFacelet[j][1] / 9)) {
  1057. ccRet.ep[i] = j;
  1058. ccRet.eo[i] = 0;
  1059. break;
  1060. }
  1061. if (f[edgeFacelet[i][0]] == ~~(edgeFacelet[j][1] / 9) && f[edgeFacelet[i][1]] == ~~(edgeFacelet[j][0] / 9)) {
  1062. ccRet.ep[i] = j;
  1063. ccRet.eo[i] = 1;
  1064. break;
  1065. }
  1066. }
  1067. }
  1068. }
  1069.  
  1070. function toFaceCube(cc){
  1071. var c, e, f, i, j, n, ori, ts;
  1072. f = createArray(54);
  1073. ts = [85, 82, 70, 68, 76, 66];
  1074. for (i = 0; i < 54; ++i) {
  1075. f[i] = ts[~~(i / 9)];
  1076. }
  1077. for (c = 0; c < 8; ++c) {
  1078. j = cc.cp[c];
  1079. ori = cc.co[c];
  1080. for (n = 0; n < 3; ++n)
  1081. f[cornerFacelet[c][(n + ori) % 3]] = ts[~~(cornerFacelet[j][n] / 9)];
  1082. }
  1083. for (e = 0; e < 12; ++e) {
  1084. j = cc.ep[e];
  1085. ori = cc.eo[e];
  1086. for (n = 0; n < 2; ++n)
  1087. f[edgeFacelet[e][(n + ori) % 2]] = ts[~~(edgeFacelet[j][n] / 9)];
  1088. }
  1089. return String.fromCharCode.apply(null, f);
  1090. }
  1091.  
  1092. var Cnk, ckmv2, cornerFacelet, edgeFacelet, fact, move2str, permMult, std2ud, ud2std;
  1093.  
  1094. function initialize() {
  1095. Util_$clinit();
  1096. CubieCube_$clinit();
  1097. CoordCube_$clinit();
  1098. initMove();
  1099. initSym();
  1100. initFlipSym2Raw();
  1101. initTwistSym2Raw();
  1102. initPermSym2Raw();
  1103. initFlipMove();
  1104. initTwistMove();
  1105. initUDSliceMoveConj();
  1106. initCPermMove();
  1107. initEPermMove();
  1108. initMPermMoveConj();
  1109. initRawSymPrun(UDSliceTwistPrun, 6, UDSliceMove, UDSliceConj, TwistMove, SymStateTwist, null, null, 3);
  1110. initRawSymPrun(UDSliceFlipPrun, 6, UDSliceMove, UDSliceConj, FlipMove, SymStateFlip, null, null, 3);
  1111. initRawSymPrun(MEPermPrun, 7, MPermMove, MPermConj, EPermMove, SymStatePerm, null, null, 4);
  1112. initRawSymPrun(MCPermPrun, 10, MPermMove, MPermConj, CPermMove, SymStatePerm, e2c, ud2std, 4);
  1113. }
  1114.  
  1115. var randomSource = Math;
  1116.  
  1117. var initialized = false;
  1118.  
  1119. function ini(iniRandomSource, statusCallback) {
  1120.  
  1121. if (typeof statusCallback != "function") {
  1122. statusCallback = function() {};
  1123. }
  1124.  
  1125. if (!initialized) {
  1126. // var cur = +new Date;
  1127. initialize();
  1128. randomSource = iniRandomSource;
  1129. search = new Search;
  1130. initialized = true;
  1131. // console.log(+new Date - cur);
  1132. }
  1133. }
  1134.  
  1135.  
  1136. // SCRAMBLERS
  1137.  
  1138. function rn(n) {
  1139. return ~~(randomSource.random() * n);
  1140. }
  1141.  
  1142. var search;
  1143.  
  1144. function getRandomScramble() {
  1145. ini(Math);
  1146. var cperm, eperm = rn(479001600);
  1147. do {
  1148. cperm = rn(40320);
  1149. } while ((getNParity(cperm,8) ^ getNParity(eperm,12)) != 0);
  1150. var posit = toFaceCube(new CubieCube1(cperm, rn(2187), eperm, rn(2048)));
  1151. var solution = $solution(search, posit);
  1152.  
  1153. return solution;
  1154. }
  1155.  
  1156. function cntU(b){for(var c=0,a=0;a<b.length;a++)-1==b[a]&&c++;return c};
  1157.  
  1158. function fixOri(arr, cntU, base) {
  1159. var sum = 0;
  1160. var idx = 0;
  1161. for (var i=0; i<arr.length-1; i++) {
  1162. if (arr[i] == -1) {
  1163. if (cntU-- == 1) {
  1164. arr[i] = ((base << 4) - sum) % base;
  1165. } else {
  1166. arr[i] = rn(base);
  1167. }
  1168. }
  1169. sum += arr[i];
  1170. idx *= base;
  1171. idx += arr[i];
  1172. }
  1173. return idx;
  1174. }
  1175.  
  1176. function fixPerm(arr, cntU, parity) {
  1177. var val = [0,1,2,3,4,5,6,7,8,9,10,11];
  1178. for (var i=0; i<arr.length; i++) {
  1179. if (arr[i] != -1) {
  1180. val[arr[i]] = -1;
  1181. }
  1182. }
  1183. for (var i=0, j=0; i<val.length; i++) {
  1184. if (val[i] != -1) {
  1185. val[j++] = val[i];
  1186. }
  1187. }
  1188. var last;
  1189. for (var i=0; i<arr.length && cntU>0; i++) {
  1190. if (arr[i] == -1) {
  1191. var r = rn(cntU);
  1192. arr[i] = val[r];
  1193. for (var j=r; j<11; j++) {
  1194. val[j] = val[j+1];
  1195. }
  1196. if (cntU-- == 2) {
  1197. last = i;
  1198. }
  1199. }
  1200. }
  1201. if (getNParity(getNPerm(arr, arr.length), arr.length) == 1-parity) {
  1202. var temp = arr[i-1];
  1203. arr[i-1] = arr[last];
  1204. arr[last] = temp;
  1205. }
  1206. return getNPerm(arr, arr.length);
  1207. }
  1208.  
  1209. function getAnyScramble(ep, eo, cp, co) {
  1210. ini(Math);
  1211. var neo = fixOri(eo, cntU(eo), 2);
  1212. var nco = fixOri(co, cntU(co), 3);
  1213. var nep, ncp;
  1214. var ue = cntU(ep);
  1215. var uc = cntU(cp);
  1216. if (ue==0 && uc==0) {
  1217. nep = getNPerm(ep, 12);
  1218. ncp = getNPerm(cp, 8);
  1219. } else if (ue!=0 && uc==0) {
  1220. ncp = getNPerm(cp, 8);
  1221. nep = fixPerm(ep, ue, getNParity(ncp, 8));
  1222. } else if (ue==0 && uc!=0) {
  1223. nep = getNPerm(ep, 12);
  1224. ncp = fixPerm(cp, uc, getNParity(nep, 12));
  1225. } else {
  1226. nep = fixPerm(ep, ue, -1);
  1227. ncp = fixPerm(cp, uc, getNParity(nep, 12));
  1228. }
  1229. var posit = toFaceCube(new CubieCube1(ncp, nco, nep, neo));
  1230. var solution = $solution(search, posit);
  1231.  
  1232. return solution;
  1233. }
  1234.  
  1235. function getEdgeScramble() {
  1236. return getAnyScramble([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
  1237. [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[0,1,2,3,4,5,6,7],[0,0,0,0,0,0,0,0]);
  1238. }
  1239.  
  1240. function getCornerScramble() {
  1241. return getAnyScramble([0,1,2,3,4,5,6,7,8,9,10,11],
  1242. [0,0,0,0,0,0,0,0,0,0,0,0],[-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1]);
  1243. }
  1244.  
  1245. function getLLScramble() {
  1246. return getAnyScramble([-1,-1,-1,-1,4,5,6,7,8,9,10,11],
  1247. [-1,-1,-1,-1,0,0,0,0,0,0,0,0],[-1,-1,-1,-1,4,5,6,7],[-1,-1,-1,-1,0,0,0,0]);
  1248. }
  1249.  
  1250. function getLSLLScramble() {
  1251. return getAnyScramble([-1,-1,-1,-1,4,5,6,7,-1,9,10,11],
  1252. [-1,-1,-1,-1,0,0,0,0,-1,0,0,0],[-1,-1,-1,-1,-1,5,6,7],[-1,-1,-1,-1,-1,0,0,0]);
  1253. }
  1254.  
  1255. function getF2LScramble() {
  1256. return getAnyScramble([-1,-1,-1,-1,4,5,6,7,-1,-1,-1,-1],
  1257. [-1,-1,-1,-1,0,0,0,0,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1]);
  1258. }
  1259.  
  1260. function getZBLLScramble() {
  1261. return getAnyScramble([-1,-1,-1,-1,4,5,6,7,8,9,10,11],
  1262. [0,0,0,0,0,0,0,0,0,0,0,0],[-1,-1,-1,-1,4,5,6,7],[-1,-1,-1,-1,0,0,0,0]);
  1263. }
  1264.  
  1265. function getLSEScramble() {
  1266. switch (rn(4)) {
  1267. case 0: return getAnyScramble([-1,-1,-1,-1,4,-1,6,-1,8,9,10,11],[-1,-1,-1,-1,0,-1,0,-1,0,0,0,0],[0,1,2,3,4,5,6,7],[0,0,0,0,0,0,0,0]);
  1268. case 1: return getAnyScramble([11,-1,10,-1,8,-1,9,-1,0,2,-1,-1],[0,-1,0,-1,0,-1,0,-1,0,0,-1,-1],[3,2,6,7,0,1,5,4],[2,1,2,1,1,2,1,2])+"x'";
  1269. case 2: return getAnyScramble([4,-1,6,-1,-1,-1,-1,-1,11,10,9,8],[0,-1,0,-1,-1,-1,-1,-1,0,0,0,0],[7,6,5,4,3,2,1,0],[0,0,0,0,0,0,0,0])+"x2";
  1270. case 3: return getAnyScramble([8,-1,9,-1,11,-1,10,-1,-1,-1,2,0],[0,-1,0,-1,0,-1,0,-1,-1,-1,0,0],[4,5,1,0,7,6,2,3],[2,1,2,1,1,2,1,2])+"x";
  1271. }
  1272. }
  1273.  
  1274. function getCMLLScramble() {
  1275. switch (rn(4)) {
  1276. case 0: return getAnyScramble([-1,-1,-1,-1,4,-1,6,-1,8,9,10,11],[-1,-1,-1,-1,0,-1,0,-1,0,0,0,0],[-1,-1,-1,-1,4,5,6,7],[-1,-1,-1,-1,0,0,0,0]);
  1277. case 1: return getAnyScramble([11,-1,10,-1,8,-1,9,-1,0,2,-1,-1],[0,-1,0,-1,0,-1,0,-1,0,0,-1,-1],[3,2,-1,-1,0,1,-1,-1],[2,1,-1,-1,1,2,-1,-1])+"x'";
  1278. case 2: return getAnyScramble([4,-1,6,-1,-1,-1,-1,-1,11,10,9,8],[0,-1,0,-1,-1,-1,-1,-1,0,0,0,0],[7,6,5,4,-1,-1,-1,-1],[0,0,0,0,-1,-1,-1,-1])+"x2";
  1279. case 3: return getAnyScramble([8,-1,9,-1,11,-1,10,-1,-1,-1,2,0],[0,-1,0,-1,0,-1,0,-1,-1,-1,0,0],[-1,-1,1,0,-1,-1,2,3],[-1,-1,2,1,-1,-1,1,2])+"x";
  1280. }
  1281. }
  1282.  
  1283. function getCLLScramble() {
  1284. return getAnyScramble([0,1,2,3,4,5,6,7,8,9,10,11],[0,0,0,0,0,0,0,0,0,0,0,0],[-1,-1,-1,-1,4,5,6,7],[-1,-1,-1,-1,0,0,0,0]);
  1285. }
  1286.  
  1287. function getELLScramble() {
  1288. return getAnyScramble([-1,-1,-1,-1,4,5,6,7,8,9,10,11],[-1,-1,-1,-1,0,0,0,0,0,0,0,0],[0,1,2,3,4,5,6,7],[0,0,0,0,0,0,0,0]);
  1289. }
  1290.  
  1291. return {
  1292. /* mark2 interface */
  1293. getRandomScramble: getRandomScramble,//getRandomScramble,
  1294.  
  1295. /* added methods */
  1296. getEdgeScramble: getEdgeScramble,
  1297. getCornerScramble: getCornerScramble,
  1298. getLLScramble: getLLScramble,
  1299. getLSLLScramble: getLSLLScramble,
  1300. getZBLLScramble: getZBLLScramble,
  1301. getF2LScramble: getF2LScramble,
  1302. getLSEScramble: getLSEScramble,
  1303. getCMLLScramble: getCMLLScramble,
  1304. getCLLScramble: getCLLScramble,
  1305. getELLScramble: getELLScramble,
  1306. getAnyScramble: getAnyScramble
  1307. };
  1308.  
  1309. })();
Add Comment
Please, Sign In to add comment