Created
April 7, 2012 16:38
-
-
Save cs0x7f/2330203 to your computer and use it in GitHub Desktop.
generate random state subset scramble
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| scramble_333.js | |
| 3x3x3 Solver / Scramble Generator in Javascript. | |
| The core 3x3x3 code is from a min2phase solver by Shuang Chen. | |
| Compiled to Javascript using GWT. | |
| (There may be a lot of redundant code right now, but it's still really fast.) | |
| */ | |
| "use strict"; | |
| if (typeof scramblers == "undefined") { | |
| var scramblers = {}; | |
| } | |
| scramblers["333fm"] = scramblers["333ft"] = scramblers["333bf"] = scramblers["333oh"] = scramblers["333"] = (function() { | |
| var cornerFacelet, edgeFacelet, cornerColor, edgeColor, Cnk, fact, move2str, ud2std, std2ud, ckmv, ckmv2, parity4, perm3, moveCube, CubeSym, SymInv, SymMult, SymMove, Sym8Mult, Sym8Move, Sym8MultInv, SymMoveUD, e2c, merge, FlipS2R, TwistS2R, PermS2R, FlipR2S, TwistR2S, PermR2S, MtoEPerm, SymStateTwist, SymStateFlip, SymStatePerm, UDSliceMove, TwistMove, FlipMove, UDSliceConj, UDSliceTwistPrun, UDSliceFlipPrun, TwistFlipPrun, Mid3Move, Mid32MPerm, CParity, CPermMove, EPermMove, MPermMove, MPermConj, MCPermPrun, MEPermPrun, urf1, urf2, urfMove; | |
| function createArray(length1, length2){ | |
| var result, i; | |
| result = []; | |
| if (length2 == undefined) { | |
| result[i] = 0; | |
| } else { | |
| for (i=0; i<length1; i++) { | |
| result[i] = []; | |
| } | |
| } | |
| return result; | |
| } | |
| function initCParity(){ | |
| CParity = createArray(346); | |
| for (var i=0; i<2768; ++i) { | |
| CParity[i >>> 3] = (CParity[i >>> 3] | getNParity(8,PermS2R[i]) << (i & 7)); | |
| } | |
| } | |
| function initCPermMove(){ | |
| CPermMove = createArray(2768, 18); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 2768; ++i) { | |
| set8Perm(c.cp, PermS2R[i]); | |
| for (var j = 0; j < 18; ++j) { | |
| CornMult(c, moveCube[j], d); | |
| CPermMove[i][j] = getCPermSym(d); | |
| } | |
| } | |
| } | |
| function initEPermMove(){ | |
| EPermMove = createArray(2768, 10); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 2768; ++i) { | |
| set8Perm(c.ep, PermS2R[i]); | |
| for (var j = 0; j < 10; ++j) { | |
| EdgeMult(c, moveCube[ud2std[j]], d); | |
| EPermMove[i][j] = getEPermSym(d); | |
| } | |
| } | |
| } | |
| function initFlipMove(){ | |
| FlipMove = createArray(336, 18); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 336; ++i) { | |
| setFlip(c, FlipS2R[i]); | |
| for (var j = 0; j < 18; ++j) { | |
| EdgeMult(c, moveCube[j], d); | |
| FlipMove[i][j] = getFlipSym(d); | |
| } | |
| } | |
| } | |
| function initMCEPermPrun(callback){ | |
| var check, corn, cornx, depth, done, edge, edgex, i, idx, idxx, inv, j, m, mid, midx, select, sym, symx; | |
| depth = 0; | |
| done = 1; | |
| MEPermPrun = [];//Array(66432); | |
| for (i = 0; i < 66432; ++i) { | |
| MEPermPrun[i] = -1; | |
| } | |
| MEPermPrun[0] = 0; | |
| while (done < 66432) { | |
| inv = depth > 7; | |
| select = inv?-1:depth; | |
| check = inv?depth:-1; | |
| ++depth; | |
| for (i = 0; i < 66432; ++i) { | |
| if (MEPermPrun[i] != select) | |
| continue; | |
| mid = i % 24; | |
| edge = ~~(i / 24); | |
| for (m = 0; m < 10; ++m) { | |
| edgex = EPermMove[edge][m]; | |
| symx = edgex & 15; | |
| midx = MPermConj[MPermMove[mid][m]][symx]; | |
| edgex >>>= 4; | |
| idx = edgex * 24 + midx; | |
| if (MEPermPrun[idx] == check) { | |
| ++done; | |
| if (inv) { | |
| MEPermPrun[i] = depth; | |
| break; | |
| } else { | |
| MEPermPrun[idx] = depth; | |
| sym = SymStatePerm[edgex]; | |
| if (sym != 0) { | |
| for (j = 1; j < 16; ++j) { | |
| sym = sym >> 1; | |
| if ((sym & 1) == 1) { | |
| idxx = edgex * 24 + MPermConj[midx][j]; | |
| if (MEPermPrun[idxx] == -1) { | |
| MEPermPrun[idxx] = depth; | |
| ++done; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // callback("MEPermPrun: " + (Math.floor(done * 100 / 66432)) +"% (" + done + "/66432)"); | |
| } | |
| MCPermPrun = [];//Array(66432); | |
| for (i = 0; i < 66432; ++i) { | |
| MCPermPrun[i] = -1; | |
| } | |
| MCPermPrun[0] = 0; | |
| depth = 0; | |
| done = 1; | |
| while (done < 66432) { | |
| inv = depth > 7; | |
| select = inv?-1:depth; | |
| check = inv?depth:-1; | |
| ++depth; | |
| for (i = 0; i < 66432; ++i) { | |
| if (MCPermPrun[i] != select) | |
| continue; | |
| mid = i % 24; | |
| corn = ~~(i / 24); | |
| for (m = 0; m < 10; ++m) { | |
| cornx = CPermMove[corn][ud2std[m]]; | |
| symx = (cornx & 15); | |
| midx = MPermConj[MPermMove[mid][m]][symx]; | |
| cornx = cornx >>> 4; | |
| idx = cornx * 24 + midx; | |
| if (MCPermPrun[idx] == check) { | |
| ++done; | |
| if (inv) { | |
| MCPermPrun[i] = depth; | |
| break; | |
| } else { | |
| MCPermPrun[idx] = depth; | |
| sym = SymStatePerm[cornx]; | |
| if (sym != 0) { | |
| for (j = 1; j < 16; ++j) { | |
| sym = sym >> 1; | |
| if ((sym & 1) == 1) { | |
| idxx = cornx * 24 + MPermConj[midx][j ^ e2c[j]]; | |
| if (MCPermPrun[idxx] == -1) { | |
| MCPermPrun[idxx] = depth; | |
| ++done; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // callback("MCPermPrun: " + (Math.floor(done * 100 / 66432)) +"% (" + done + "/66432)"); | |
| } | |
| } | |
| function initMPermMoveConj(){ | |
| MPermMove = createArray(24, 10); | |
| MPermConj = createArray(24, 16); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 24; ++i) { | |
| setMPerm(c, i); | |
| for (var j = 0; j < 10; ++j) { | |
| EdgeMult(c, moveCube[ud2std[j]], d); | |
| MPermMove[i][j] = getMPerm(d); | |
| } | |
| for (var j = 0; j < 16; ++j) { | |
| EdgeConjugate(c, SymInv[j], d); | |
| MPermConj[i][j] = getMPerm(d); | |
| } | |
| } | |
| } | |
| function initMid32MPerm(){ | |
| Mid32MPerm = [];//24); | |
| var c = new CubieCube_0; | |
| for (var i = 0; i < 24; ++i) { | |
| setMPerm(c, i); | |
| Mid32MPerm[getMid3(c) % 24] = i; | |
| } | |
| } | |
| function initMid3Move(){ | |
| Mid3Move = createArray(1320, 18); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 1320; ++i) { | |
| setMid3(c, i); | |
| for (var j = 0; j < 18; ++j) { | |
| EdgeMult(c, moveCube[j], d); | |
| Mid3Move[i][j] = getMid3(d); | |
| } | |
| } | |
| } | |
| function initTwistFlipSlicePrun(callback){ | |
| var check, depth, done, flip, flipx, fsym, fsymx, fsymxx, idx, idxx, inv, j, k, select, slice, slicex, sym, symF, symx, tsymx, twist, twistx; | |
| TwistFlipPrun = []; | |
| for (var i = 0; i < 870912; ++i) { | |
| TwistFlipPrun[i] = -1; | |
| } | |
| for (var i = 0; i < 8; ++i) { | |
| TwistFlipPrun[i] = 0; | |
| } | |
| depth = 0; | |
| done = 8; | |
| while (done < 870912) { | |
| inv = depth > 6; | |
| select = inv?-1:depth; | |
| check = inv?depth:-1; | |
| ++depth; | |
| for (var i = 0; i < 870912; ++i) { | |
| if (TwistFlipPrun[i] != select) | |
| continue; | |
| twist = ~~(i / 2688); | |
| flip = i % 2688; | |
| fsym = i & 7; | |
| flip >>>= 3; | |
| for (var m = 0; m < 18; ++m) { | |
| twistx = TwistMove[twist][m]; | |
| tsymx = twistx & 7; | |
| twistx >>>= 3; | |
| flipx = FlipMove[flip][Sym8Move[fsym][m]]; | |
| fsymx = Sym8MultInv[Sym8Mult[flipx & 7][fsym]][tsymx]; | |
| flipx >>>= 3; | |
| idx = twistx * 2688 + (flipx << 3 | fsymx); | |
| if (TwistFlipPrun[idx] == check) { | |
| ++done; | |
| if (inv) { | |
| TwistFlipPrun[i] = depth; | |
| break; | |
| } else { | |
| TwistFlipPrun[idx] = depth; | |
| sym = SymStateTwist[twistx]; | |
| symF = SymStateFlip[flipx]; | |
| if (sym != 1 || symF != 1) { | |
| for (j = 0; j < 8; ++j , symF = symF >> 1) { | |
| if ((symF & 1) == 1) { | |
| fsymxx = Sym8MultInv[fsymx][j]; | |
| for (k = 0; k < 8; ++k) { | |
| if ((sym & 1 << k) != 0) { | |
| idxx = twistx * 2688 + (flipx << 3 | Sym8MultInv[fsymxx][k]); | |
| if (TwistFlipPrun[idxx] == -1) { | |
| TwistFlipPrun[idxx] = depth; | |
| ++done; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // callback("TwistFlipPrun: " + (Math.floor(done * 100 / 870912)) +"% (" + done + "/870912)"); | |
| } | |
| UDSliceTwistPrun = []; | |
| for (var i = 0; i < 160380; ++i) { | |
| UDSliceTwistPrun[i] = -1; | |
| } | |
| UDSliceTwistPrun[0] = 0; | |
| depth = 0; | |
| done = 1; | |
| while (done < 160380) { | |
| inv = depth > 6; | |
| select = inv?-1:depth; | |
| check = inv?depth:-1; | |
| ++depth; | |
| for (var i = 0; i < 160380; ++i) { | |
| if (UDSliceTwistPrun[i] != select) | |
| continue; | |
| slice = i % 495; | |
| twist = ~~(i / 495); | |
| for (var m = 0; m < 18; ++m) { | |
| twistx = TwistMove[twist][m]; | |
| symx = twistx & 7; | |
| slicex = UDSliceConj[UDSliceMove[slice][m]][symx]; | |
| twistx >>>= 3; | |
| idx = twistx * 495 + slicex; | |
| if (UDSliceTwistPrun[idx] == check) { | |
| ++done; | |
| if (inv) { | |
| UDSliceTwistPrun[i] = depth; | |
| break; | |
| } else { | |
| UDSliceTwistPrun[idx] = depth; | |
| sym = SymStateTwist[twistx]; | |
| if (sym != 1) { | |
| for (j = 1; j < 8; ++j) { | |
| sym = sym >> 1; | |
| if ((sym & 1) == 1) { | |
| idxx = twistx * 495 + UDSliceConj[slicex][j]; | |
| if (UDSliceTwistPrun[idxx] == -1) { | |
| UDSliceTwistPrun[idxx] = depth; | |
| ++done; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // callback("UDSliceTwistPrun: " + (Math.floor(done * 100 / 160380)) +"% (" + done + "/160380)"); | |
| } | |
| UDSliceFlipPrun = []; | |
| for (var i = 0; i < 166320; ++i) { | |
| UDSliceFlipPrun[i] = -1; | |
| } | |
| UDSliceFlipPrun[0] = 0; | |
| depth = 0; | |
| done = 1; | |
| while (done < 166320) { | |
| inv = depth > 6; | |
| select = inv?-1:depth; | |
| check = inv?depth:-1; | |
| ++depth; | |
| for (var i = 0; i < 166320; ++i) { | |
| if (UDSliceFlipPrun[i] != select) | |
| continue; | |
| slice = i % 495; | |
| flip = ~~(i / 495); | |
| for (var m = 0; m < 18; ++m) { | |
| flipx = FlipMove[flip][m]; | |
| symx = flipx & 7; | |
| slicex = UDSliceConj[UDSliceMove[slice][m]][symx]; | |
| flipx >>>= 3; | |
| idx = flipx * 495 + slicex; | |
| if (UDSliceFlipPrun[idx] == check) { | |
| ++done; | |
| if (inv) { | |
| UDSliceFlipPrun[i] = depth; | |
| break; | |
| } else { | |
| UDSliceFlipPrun[idx] = depth; | |
| sym = SymStateFlip[flipx]; | |
| if (sym != 1) { | |
| for (j = 1; j < 8; ++j) { | |
| sym = sym >> 1; | |
| if ((sym & 1) == 1) { | |
| idxx = flipx * 495 + UDSliceConj[slicex][j]; | |
| if (UDSliceFlipPrun[idxx] == -1) { | |
| UDSliceFlipPrun[idxx] = depth; | |
| ++done; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // callback("UDSliceFlipPrun: " + (Math.floor(done * 100 / 166320)) +"% (" + done + "/166320)"); | |
| } | |
| } | |
| function initTwistMove(){ | |
| TwistMove = createArray(324, 18); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 324; ++i) { | |
| setTwist(c, TwistS2R[i]); | |
| for (var j = 0; j < 18; ++j) { | |
| CornMult(c, moveCube[j], d); | |
| TwistMove[i][j] = getTwistSym(d); | |
| } | |
| } | |
| } | |
| function initUDSliceMoveConj(){ | |
| UDSliceMove = createArray(495, 18); | |
| UDSliceConj = createArray(495, 8); | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| for (var i = 0; i < 495; ++i) { | |
| setUDSlice(c, i); | |
| for (var j = 0; j < 18; ++j) { | |
| EdgeMult(c, moveCube[j], d); | |
| UDSliceMove[i][j] = getUDSlice(d); | |
| } | |
| for (var j = 0; j < 16; j = j + 2) { | |
| EdgeConjugate(c, SymInv[j], d); | |
| UDSliceConj[i][j >>> 1] = getUDSlice(d); | |
| } | |
| } | |
| } | |
| function $$init(obj){ | |
| obj.cp = [0, 1, 2, 3, 4, 5, 6, 7]; | |
| obj.co = [0, 0, 0, 0, 0, 0, 0, 0]; | |
| obj.ep = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; | |
| obj.eo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; | |
| } | |
| function $copy(obj, c){ | |
| var i; | |
| for (i = 0; i < 8; ++i) { | |
| obj.cp[i] = c.cp[i]; | |
| obj.co[i] = c.co[i]; | |
| } | |
| for (i = 0; i < 12; ++i) { | |
| obj.ep[i] = c.ep[i]; | |
| obj.eo[i] = c.eo[i]; | |
| } | |
| } | |
| function getCPermSym(obj){ | |
| var idx = PermR2S[get8Perm(obj.cp)]; | |
| return idx ^ e2c[idx & 15]; | |
| } | |
| function getDRtoDL(obj){ | |
| var idxA = 0; | |
| var idxB = 0; | |
| var mask = 0; | |
| var r = 3; | |
| for (var i = 11; i >= 0; --i) { | |
| if (4 <= obj.ep[i] && obj.ep[i] <= 6) { | |
| idxA = idxA + Cnk[i][r--]; | |
| var t = 1 << obj.ep[i]; | |
| idxB = idxB + bitCount(mask & t - 1) * fact[2 - r]; | |
| mask = (mask | t); | |
| } | |
| } | |
| return idxA * 6 + idxB; | |
| } | |
| function getEPermSym(obj){ | |
| return PermR2S[get8Perm(obj.ep)]; | |
| } | |
| function getEdgePerm(obj){ | |
| var i, idx, m, t; | |
| m = 1 << obj.ep[11]; | |
| idx = 0; | |
| for (i = 10; i >= 0; --i) { | |
| t = 1 << obj.ep[i]; | |
| idx += bitCount(m & t - 1) * fact[11 - i]; | |
| m |= t; | |
| } | |
| return idx; | |
| } | |
| function getFlip(obj){ | |
| var i, idx; | |
| idx = 0; | |
| for (i = 0; i < 11; ++i) { | |
| idx = (idx | obj.eo[i] << i); | |
| } | |
| return idx; | |
| } | |
| function getFlipSym(obj){ | |
| return FlipR2S[getFlip(obj)]; | |
| } | |
| function getMPerm(obj) { | |
| var idx = 0; | |
| var val = 0x76543210; | |
| for (var i=0; i<3; i++) { | |
| var v = (obj.ep[i+8]-8) << 2; | |
| idx = (4 - i) * idx + ((val >> v) & 0x0f); | |
| val -= 0x11111110 << v; | |
| } | |
| return idx; | |
| } | |
| function getMid3(obj){ | |
| var i, idxA, idxB, mask, r, t; | |
| idxA = 0; | |
| idxB = 0; | |
| mask = 0; | |
| r = 3; | |
| for (i = 11; i >= 0; --i) { | |
| if (obj.ep[i] >= 9) { | |
| idxA = idxA + Cnk[i][r--]; | |
| t = 1 << obj.ep[i]; | |
| idxB = idxB + bitCount(mask & t - 1) * fact[2 - r]; | |
| mask = (mask | t); | |
| } | |
| } | |
| return idxA * 6 + idxB; | |
| } | |
| function getTwist(obj){ | |
| var i, idx; | |
| idx = 0; | |
| for (i = 0; i < 7; ++i) { | |
| idx *= 3; | |
| idx += obj.co[i]; | |
| } | |
| return idx; | |
| } | |
| function getTwistSym(obj){ | |
| return TwistR2S[getTwist(obj)]; | |
| } | |
| function getUDSlice(obj){ | |
| var idx = 0; | |
| var r = 4; | |
| for (var i = 0; i < 12; ++i) { | |
| obj.ep[i] >= 8 && (idx += Cnk[11 - i][r--]); | |
| } | |
| return idx; | |
| } | |
| function getURtoUL(obj){ | |
| var idxA = 0; | |
| var idxB = 0; | |
| var mask = 0; | |
| var r = 3; | |
| for (var i = 11; i >= 0; --i) { | |
| if (obj.ep[i] <= 2) { | |
| idxA += Cnk[i][r--]; | |
| var t = 1 << obj.ep[i]; | |
| idxB += bitCount(mask & t - 1) * fact[2 - r]; | |
| mask |= t; | |
| } | |
| } | |
| return idxA * 6 + idxB; | |
| } | |
| function $invCubieCube(obj){ | |
| var corn, edge, ori; | |
| for (edge = 0; edge < 12; ++edge) | |
| obj.temps.ep[obj.ep[edge]] = edge; | |
| for (edge = 0; edge < 12; ++edge) | |
| obj.temps.eo[edge] = obj.eo[obj.temps.ep[edge]]; | |
| for (corn = 0; corn < 8; ++corn) | |
| obj.temps.cp[obj.cp[corn]] = corn; | |
| for (corn = 0; corn < 8; ++corn) { | |
| ori = obj.co[obj.temps.cp[corn]]; | |
| obj.temps.co[corn] = -ori; | |
| obj.temps.co[corn] < 0 && (obj.temps.co[corn] = obj.temps.co[corn] + 3); | |
| } | |
| $copy(obj, obj.temps); | |
| } | |
| function setEdgePerm(obj, idx){ | |
| var i, j; | |
| obj.ep[11] = 0; | |
| for (i = 10; i >= 0; --i) { | |
| obj.ep[i] = idx % (12 - i); | |
| idx = ~~(idx / (12 - i)); | |
| for (j = i + 1; j < 12; ++j) { | |
| obj.ep[j] >= obj.ep[i] && ++obj.ep[j]; | |
| } | |
| } | |
| } | |
| function setFlip(obj, idx){ | |
| var parity = 0; | |
| for (var i=0; i<11; ++i) { | |
| parity ^= obj.eo[i] = (idx & 1); | |
| idx >>>= 1; | |
| } | |
| obj.eo[11] = parity; | |
| } | |
| function setMPerm(obj, idx) { | |
| var val = 0x3210; | |
| for (var i=8; i<11; i++) { | |
| var p = fact[11-i]; | |
| var v = (~~(idx / p)) << 2; | |
| idx %= p; | |
| obj.ep[i] = (val >> v) & 0xf | 8; | |
| var m = (1 << v) - 1; | |
| val = (val & m) + ((val >> 4) & ~m); | |
| } | |
| obj.ep[11] = (val|8); | |
| } | |
| function setMid3(obj, idxA){ | |
| var edge = perm3[idxA % 6]; | |
| idxA = ~~(idxA / 6); | |
| var r = 3; | |
| for (var i = 11; i >= 0; --i) { | |
| if (idxA >= Cnk[i][r]) { | |
| idxA -= Cnk[i][r--]; | |
| obj.ep[i] = edge[2 - r]; | |
| } | |
| else { | |
| obj.ep[i] = 8 - i + r; | |
| } | |
| } | |
| } | |
| function setTwist(obj, idx){ | |
| var twst = 0; | |
| for (var i = 6; i >= 0; --i) { | |
| twst = twst + (obj.co[i] = idx % 3); | |
| idx = ~~(idx / 3); | |
| } | |
| obj.co[7] = (15 - twst) % 3; | |
| } | |
| function setUDSlice(obj, idx){ | |
| var r = 4; | |
| for (var i = 0; i < 12; ++i) { | |
| if (idx >= Cnk[11 - i][r]) { | |
| idx = idx - Cnk[11 - i][r--]; | |
| obj.ep[i] = 11 - r; | |
| } | |
| else { | |
| obj.ep[i] = i + r - 4; | |
| } | |
| } | |
| } | |
| function $verify(obj){ | |
| var c, cornMask, e, edgeMask, i, sum; | |
| sum = 0; | |
| edgeMask = 0; | |
| for (e = 0; e < 12; ++e) | |
| edgeMask = (edgeMask | 1 << obj.ep[e]); | |
| if (edgeMask != 4095) | |
| return -2; | |
| for (i = 0; i < 12; ++i) | |
| sum ^= obj.eo[i]; | |
| if (sum % 2 != 0) | |
| return -3; | |
| cornMask = 0; | |
| for (c = 0; c < 8; ++c) | |
| cornMask |= 1 << obj.cp[c]; | |
| if (cornMask != 255) | |
| return -4; | |
| sum = 0; | |
| for (i = 0; i < 8; ++i) | |
| sum += obj.co[i]; | |
| if (sum % 3 != 0) | |
| return -5; | |
| if ((getNParity(12,getEdgePerm(obj)) ^ getNParity(8,get8Perm(obj.cp))) != 0) | |
| return -6; | |
| return 0; | |
| } | |
| function CornConjugate(a, idx, b) { | |
| var sinv = CubeSym[SymInv[idx]]; | |
| var s = CubeSym[idx]; | |
| for (var corn=0; corn<8; corn++) { | |
| b.cp[corn] = sinv.cp[a.cp[s.cp[corn]]]; | |
| var oriA = sinv.co[a.cp[s.cp[corn]]]; | |
| var oriB = a.co[s.cp[corn]]; | |
| b.co[corn] = ((oriA<3) ? oriB : (3-oriB) % 3); | |
| } | |
| } | |
| function CornMult(a, b, prod){ | |
| for (var corn = 0; corn < 8; ++corn) { | |
| prod.cp[corn] = a.cp[b.cp[corn]]; | |
| var oriA = a.co[b.cp[corn]]; | |
| var oriB = b.co[corn]; | |
| var ori = oriA; | |
| ori = ori + (oriA < 3?oriB:3 - oriB); | |
| ori %= 3; | |
| oriA < 3 ^ oriB < 3 && (ori += 3); | |
| prod.co[corn] = ori; | |
| } | |
| } | |
| function CubieCube_0(){ | |
| $$init(this); | |
| } | |
| function CubieCube_1(cp, co, ep, eo){ | |
| $$init(this); | |
| for (var i = 0; i < 8; ++i) { | |
| this.cp[i] = cp[i]; | |
| this.co[i] = co[i]; | |
| } | |
| for (var i = 0; i < 12; ++i) { | |
| this.ep[i] = ep[i]; | |
| this.eo[i] = eo[i]; | |
| } | |
| } | |
| function CubieCube_2(cperm, twist, eperm, flip){ | |
| $$init(this); | |
| set8Perm(this.cp, cperm); | |
| setTwist(this, twist); | |
| setEdgePerm(this, eperm); | |
| setFlip(this, flip); | |
| } | |
| function CubieCube_3(c){ | |
| CubieCube_1.call(this, c.cp, c.co, c.ep, c.eo); | |
| } | |
| function EdgeConjugate(a, idx, b){ | |
| var sinv = CubeSym[SymInv[idx]]; | |
| var s = CubeSym[idx]; | |
| for (var ed=0; ed<12; ed++) { | |
| b.ep[ed] = sinv.ep[a.ep[s.ep[ed]]]; | |
| b.eo[ed] = (s.eo[ed] ^ a.eo[s.ep[ed]] ^ sinv.eo[a.ep[s.ep[ed]]]); | |
| } | |
| } | |
| function EdgeMult(a, b, prod){ | |
| for (var ed = 0; ed < 12; ++ed) { | |
| prod.ep[ed] = a.ep[b.ep[ed]]; | |
| prod.eo[ed] = (b.eo[ed] ^ a.eo[b.ep[ed]]); | |
| } | |
| } | |
| function get8Perm(arr){ | |
| var idx = 0; | |
| var val = 0x76543210; | |
| for (var i = 0; i < 7; ++i) { | |
| var v = arr[i] << 2; | |
| idx = (8 - i) * idx + (val >> v & 7); | |
| val -= 0x11111110 << v; | |
| } | |
| return idx; | |
| } | |
| function getNPerm(d,N){for(var c=0,a=0;N>a;a++){for(var e=0,b=0;N>b&&!(d[b]==a);b++)d[b]>a&&e++;c=c*(N-a)+e}return c}; | |
| function initMove(){ | |
| var mc = [];//18); | |
| moveCube = [new CubieCube_2(15120, 0, 119750400, 0), new CubieCube_2(21021, 1494, 323403417, 0), new CubieCube_2(8064, 1236, 29441808, 802), new CubieCube_2(9, 0, 5880, 0), new CubieCube_2(1230, 412, 2949660, 0), new CubieCube_2(224, 137, 328552, 1160)]; | |
| for (var m = 0; m < 6; ++m) { | |
| mc[m*3] = moveCube[m]; | |
| for (var p=0; p<2; ++p) { | |
| mc[m * 3 + p + 1] = new CubieCube_0; | |
| EdgeMult(mc[m * 3 + p], moveCube[m], mc[m * 3 + p + 1]); | |
| CornMult(mc[m * 3 + p], moveCube[m], mc[m * 3 + p + 1]); | |
| } | |
| } | |
| moveCube = mc; | |
| } | |
| function initSym(){ | |
| var i, j, k, m, s, temp; | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| var f2 = new CubieCube_2(28783, 0, 259268407, 0); | |
| var u4 = new CubieCube_2(15138, 0, 119765538, 1792); | |
| var lr2 = new CubieCube_2(5167, 0, 83473207, 0); | |
| lr2.co = [3, 3, 3, 3, 3, 3, 3, 3]; | |
| CubeSym = [];//16); | |
| for (i = 0; i < 16; ++i) { | |
| CubeSym[i] = new CubieCube_3(c); | |
| CornMult(c, u4, d); | |
| EdgeMult(c, u4, d); | |
| temp = d; | |
| d = c; | |
| c = temp; | |
| if (i % 4 == 3) { | |
| CornMult(temp, lr2, d); | |
| EdgeMult(temp, lr2, d); | |
| temp = d; | |
| d = c; | |
| c = temp; | |
| } | |
| if (i % 8 == 7) { | |
| CornMult(temp, f2, d); | |
| EdgeMult(temp, f2, d); | |
| temp = d; | |
| d = c; | |
| c = temp; | |
| } | |
| } | |
| SymInv = [];//Array(16); | |
| SymMult = createArray(16, 16); | |
| for (i = 0; i < 16; ++i) { | |
| for (j = 0; j < 16; ++j) { | |
| CornMult(CubeSym[i], CubeSym[j], c); | |
| for (k = 0; k < 16; ++k) { | |
| if (CubeSym[k].cp[0] == c.cp[0] && CubeSym[k].cp[1] == c.cp[1] && CubeSym[k].cp[2] == c.cp[2]) { | |
| SymMult[i][j] = k; | |
| if (k==0) { | |
| SymInv[i] = j; | |
| } | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| SymMove = createArray(16, 18); | |
| for (j = 0; j < 18; ++j) { | |
| for (s = 0; s < 16; ++s) { | |
| CornConjugate(moveCube[j], SymInv[s], c); | |
| CONTINUE: for (m = 0; m < 18; ++m) { | |
| for (i = 0; i < 8; ++i) { | |
| if (c.cp[i] != moveCube[m].cp[i] || c.co[i] != moveCube[m].co[i]) { | |
| continue CONTINUE; | |
| } | |
| } | |
| SymMove[s][j] = m; | |
| } | |
| } | |
| } | |
| Sym8Mult = createArray(8, 8); | |
| Sym8Move = createArray(8, 18); | |
| Sym8MultInv = createArray(8, 8); | |
| SymMoveUD = createArray(16, 10); | |
| for (j = 0; j < 10; ++j) { | |
| for (s = 0; s < 16; ++s) { | |
| SymMoveUD[s][j] = std2ud[SymMove[s][ud2std[j]]]; | |
| } | |
| } | |
| for (j = 0; j < 8; ++j) { | |
| for (s = 0; s < 8; ++s) { | |
| Sym8Mult[s][j] = SymMult[s << 1][j << 1] >>> 1; | |
| } | |
| } | |
| for (j = 0; j < 18; ++j) { | |
| for (s = 0; s < 8; ++s) { | |
| Sym8Move[s][j] = SymMove[s << 1][j]; | |
| } | |
| } | |
| for (j = 0; j < 8; ++j) { | |
| for (s = 0; s < 8; ++s) { | |
| Sym8MultInv[j][s] = Sym8Mult[j][SymInv[s << 1] >> 1]; | |
| } | |
| } | |
| } | |
| function initSym2Raw(){ | |
| var a, b, count, idx, j, m; | |
| var c = new CubieCube_0; | |
| var d = new CubieCube_0; | |
| var occ = createArray(1260); | |
| var count = 0; | |
| FlipS2R = []; | |
| FlipR2S = []; | |
| SymStateFlip = createArray(336); | |
| for (var i = 0; i < 2048; ++i) { | |
| if ((occ[i >>> 5] & 1 << (i & 31)) == 0) { | |
| setFlip(c, i); | |
| for (var s = 0; s < 16; s += 2) { | |
| EdgeConjugate(c, s, d); | |
| idx = getFlip(d); | |
| if (idx == i) { | |
| SymStateFlip[count] |= 1 << (s >> 1); | |
| } | |
| occ[idx >>> 5] |= 1 << (idx & 31); | |
| FlipR2S[idx] = count << 3 | s >>> 1; | |
| } | |
| FlipS2R[count++] = i; | |
| } | |
| } | |
| count = 0; | |
| for (var i = 0; i < 69; i++)occ[i]=0; | |
| TwistS2R = []; | |
| TwistR2S = []; | |
| SymStateTwist = createArray(324); | |
| for (var i = 0; i < 2187; ++i) { | |
| if ((occ[i >>> 5] & 1 << (i & 31)) == 0) { | |
| setTwist(c, i); | |
| for (var s = 0; s < 16; s += 2) { | |
| CornConjugate(c, s, d); | |
| idx = getTwist(d); | |
| if (idx == i) { | |
| SymStateTwist[count] |= 1 << (s >> 1); | |
| } | |
| occ[idx >>> 5] |= 1 << (idx & 31); | |
| TwistR2S[idx] = count << 3 | s >>> 1; | |
| } | |
| TwistS2R[count++] = i; | |
| } | |
| } | |
| merge = createArray(56, 56); | |
| for (var i=0; i<40320; i++) { | |
| set8Perm(c.ep, i); | |
| merge[~~(getURtoUL(c)/6)][~~(getDRtoDL(c)/6)] = 1; | |
| } | |
| for (var i=0; i<56; i++) { | |
| var count = 0; | |
| for (var j=0; j<56; j++) { | |
| if (merge[i][j] != 0) { | |
| merge[i][j] = count++; | |
| } | |
| } | |
| } | |
| count = 0; | |
| for (var i = 0; i < 1260; i++) occ[i] = 0; | |
| PermS2R = []; | |
| PermR2S = []; | |
| MtoEPerm = []; | |
| SymStatePerm = createArray(2768); | |
| for (var i = 0; i < 40320; ++i) { | |
| if ((occ[i >>> 5] & 1 << (i & 31)) == 0) { | |
| set8Perm(c.ep, i); | |
| for (var s = 0; s < 16; ++s) { | |
| EdgeConjugate(c, s, d); | |
| idx = get8Perm(d.ep); | |
| if (idx == i) { | |
| SymStatePerm[count] |= 1 << s; | |
| } | |
| occ[idx >>> 5] |= 1 << (idx & 31); | |
| a = getURtoUL(d); | |
| b = getDRtoDL(d); | |
| m = merge[~~(a/6)][~~(b/6)] * 4032 + a * 12 + b % 6 * 2 + getNParity(8,idx); | |
| MtoEPerm[m] = (count << 4 | s); | |
| PermR2S[idx] = (count << 4 | s); | |
| } | |
| PermS2R[count++] = i; | |
| } | |
| } | |
| } | |
| function set8Perm(arr, idx){ | |
| var val = 1985229328; | |
| for (var i = 0; i < 7; ++i) { | |
| var p = fact[7 - i]; | |
| var v = ~~(idx / p); | |
| var idx = idx - v * p; | |
| v <<= 2; | |
| arr[i] = (val >> v & 7); | |
| var m = (1 << v) - 1; | |
| val = (val & m) + (val >> 4 & ~m); | |
| } | |
| arr[7] = val; | |
| } | |
| function CubieCube(){ | |
| } | |
| var _ = CubieCube_3.prototype = CubieCube_2.prototype = CubieCube_0.prototype = CubieCube.prototype; | |
| _.temps = null; | |
| var initTime; | |
| function $Solve(obj, c){ | |
| initTime = new Date().getTime(); | |
| var i; | |
| c.temps = new CubieCube_0; | |
| for (i = 0; i < 6; ++i) { | |
| obj.twist[i] = getTwistSym(c); | |
| obj.tsym[i] = obj.twist[i] & 7; | |
| obj.twist[i] >>>= 3; | |
| obj.flip[i] = getFlipSym(c); | |
| obj.fsym[i] = obj.flip[i] & 7; | |
| obj.flip[i] >>>= 3; | |
| obj.slice_0[i] = getUDSlice(c); | |
| obj.corn0[i] = getCPermSym(c); | |
| obj.csym0[i] = obj.corn0[i] & 15; | |
| obj.corn0[i] >>>= 4; | |
| obj.mid30[i] = getMid3(c); | |
| obj.e10[i] = getURtoUL(c); | |
| obj.e20[i] = getDRtoDL(c); | |
| obj.prun[i] = Math.max(Math.max(UDSliceTwistPrun[obj.twist[i] * 495 + UDSliceConj[obj.slice_0[i]][obj.tsym[i]]], UDSliceFlipPrun[obj.flip[i] * 495 + UDSliceConj[obj.slice_0[i]][obj.fsym[i]]]), TwistFlipPrun[obj.twist[i] * 2688 + (obj.flip[i] << 3 | Sym8MultInv[obj.fsym[i]][obj.tsym[i]])]); | |
| CornMult(urf2, c, c.temps); | |
| CornMult(c.temps, urf1, c); | |
| EdgeMult(urf2, c, c.temps); | |
| EdgeMult(c.temps, urf1, c); | |
| i == 2 && $invCubieCube(c); | |
| } | |
| obj.solution = null; | |
| for (obj.length1 = 0; obj.length1 < obj.sol; ++obj.length1) { | |
| obj.maxlength2 = Math.min(~~(obj.sol / 2) + 1, obj.sol - obj.length1); | |
| for (obj.urfidx = 0; obj.urfidx < 6; ++obj.urfidx) { | |
| obj.corn[0] = obj.corn0[obj.urfidx]; | |
| obj.csym[0] = obj.csym0[obj.urfidx]; | |
| obj.mid3[0] = obj.mid30[obj.urfidx]; | |
| obj.e1[0] = obj.e10[obj.urfidx]; | |
| obj.e2[0] = obj.e20[obj.urfidx]; | |
| if (obj.prun[obj.urfidx] <= obj.length1 && $phase1(obj, obj.twist[obj.urfidx], obj.tsym[obj.urfidx], obj.flip[obj.urfidx], obj.fsym[obj.urfidx], obj.slice_0[obj.urfidx], obj.length1, 18)) { | |
| return obj.solution == null?'Error 8':obj.solution; | |
| } | |
| } | |
| } | |
| return obj.solution; | |
| } | |
| function $init2(obj){ | |
| if (obj.solution != null && new Date().getTime() - initTime > 50) { | |
| return true; | |
| } | |
| var cornx, edge, esym, ex, i, lm, m, mid, prun, s, sb, urf; | |
| obj.valid2 = Math.min(obj.valid2, obj.valid1); | |
| for (i = obj.valid1; i < obj.length1; ++i) { | |
| m = obj.move[i]; | |
| obj.corn[i + 1] = CPermMove[obj.corn[i]][SymMove[obj.csym[i]][m]]; | |
| obj.csym[i + 1] = SymMult[obj.corn[i + 1] & 15][obj.csym[i]]; | |
| obj.corn[i + 1] >>>= 4; | |
| obj.mid3[i + 1] = Mid3Move[obj.mid3[i]][m]; | |
| } | |
| obj.valid1 = obj.length1; | |
| mid = Mid32MPerm[obj.mid3[obj.length1] % 24]; | |
| prun = MCPermPrun[obj.corn[obj.length1] * 24 + MPermConj[mid][obj.csym[obj.length1]]]; | |
| if (prun >= obj.maxlength2) { | |
| return false; | |
| } | |
| for (i = obj.valid2; i < obj.length1; ++i) { | |
| obj.e1[i + 1] = Mid3Move[obj.e1[i]][obj.move[i]]; | |
| obj.e2[i + 1] = Mid3Move[obj.e2[i]][obj.move[i]]; | |
| } | |
| obj.valid2 = obj.length1; | |
| cornx = obj.corn[obj.length1]; | |
| ex = merge[~~(obj.e1[obj.length1]/6)][~~(obj.e2[obj.length1] / 6)] * 4032 + obj.e1[obj.length1] * 12 + obj.e2[obj.length1] % 6 * 2 + (CParity[cornx >>> 3] >>> (cornx & 7) & 1 ^ parity4[mid]); | |
| edge = MtoEPerm[ex]; | |
| esym = edge & 15; | |
| edge >>>= 4; | |
| prun = Math.max(MEPermPrun[edge * 24 + MPermConj[mid][esym]], prun); | |
| if (prun >= obj.maxlength2) { | |
| return false; | |
| } | |
| lm = obj.length1 == 0?10:std2ud[~~(obj.move[obj.length1 - 1] / 3) * 3 + 1]; | |
| for (i = prun; i < obj.maxlength2; ++i) { | |
| if ($phase2(obj, edge, esym, obj.corn[obj.length1], obj.csym[obj.length1], mid, i, obj.length1, lm)) { | |
| obj.sol = obj.length1 + i; | |
| sb = ""; | |
| urf = obj.urfidx; | |
| (urf = (urf + 3) % 6); | |
| if (urf < 3) { | |
| for (s = 0; s < obj.length1; ++s) { | |
| sb += move2str[urfMove[urf][obj.move[s]]]; | |
| sb += ' '; | |
| } | |
| obj.useSeparator && (sb.impl.string += '.' , sb); | |
| for (s = obj.length1; s < obj.sol; ++s) { | |
| sb += move2str[urfMove[urf][obj.move[s]]]; | |
| sb += ' '; | |
| } | |
| } | |
| else { | |
| for (s = obj.sol - 1; s >= obj.length1; --s) { | |
| sb += move2str[urfMove[urf][obj.move[s]]]; | |
| sb += ' '; | |
| } | |
| obj.useSeparator && (sb += '.' , sb); | |
| for (s = obj.length1 - 1; s >= 0; --s) { | |
| sb += move2str[urfMove[urf][obj.move[s]]]; | |
| sb += ' '; | |
| } | |
| } | |
| obj.solution = sb; | |
| if (new Date().getTime() - initTime < 50) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| function $phase1(obj, twist, tsym, flip, fsym, slice, maxl, lm){ | |
| var flipx, fsymx, m, slicex, tsymx, twistx; | |
| if (twist == 0 && flip == 0 && slice == 0 && maxl < 5) { | |
| return maxl == 0 && $init2(obj); | |
| } | |
| for (m = 0; m < 18; ++m) { | |
| if (ckmv[lm][m]) { | |
| m += 2; | |
| continue; | |
| } | |
| slicex = UDSliceMove[slice][m]; | |
| twistx = TwistMove[twist][Sym8Move[tsym][m]]; | |
| tsymx = Sym8Mult[twistx & 7][tsym]; | |
| twistx >>>= 3; | |
| if (UDSliceTwistPrun[twistx * 495 + UDSliceConj[slicex][tsymx]] >= maxl) { | |
| continue; | |
| } | |
| flipx = FlipMove[flip][Sym8Move[fsym][m]]; | |
| fsymx = Sym8Mult[flipx & 7][fsym]; | |
| flipx >>>= 3; | |
| if (TwistFlipPrun[twistx * 2688 + (flipx << 3 | Sym8MultInv[fsymx][tsymx])] >= maxl || UDSliceFlipPrun[flipx * 495 + UDSliceConj[slicex][fsymx]] >= maxl) { | |
| continue; | |
| } | |
| obj.move[obj.length1 - maxl] = m; | |
| obj.valid1 = Math.min(obj.valid1, obj.length1 - maxl); | |
| if ($phase1(obj, twistx, tsymx, flipx, fsymx, slicex, maxl - 1, m)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| function $phase2(obj, edge, esym, corn, csym, mid, maxl, depth, lm){ | |
| var cornx, csymx, edgex, esymx, m, midx; | |
| if (edge == 0 && corn == 0 && mid == 0) { | |
| return true; | |
| } | |
| for (m = 0; m < 10; ++m) { | |
| if (ckmv2[lm][m]) { | |
| continue; | |
| } | |
| midx = MPermMove[mid][m]; | |
| edgex = EPermMove[edge][SymMoveUD[esym][m]]; | |
| esymx = SymMult[edgex & 15][esym]; | |
| edgex >>>= 4; | |
| if (MEPermPrun[edgex * 24 + MPermConj[midx][esymx]] >= maxl) { | |
| continue; | |
| } | |
| cornx = CPermMove[corn][SymMove[csym][ud2std[m]]]; | |
| csymx = SymMult[cornx & 15][csym]; | |
| cornx >>>= 4; | |
| if (MCPermPrun[cornx * 24 + MPermConj[midx][csymx]] >= maxl) { | |
| continue; | |
| } | |
| obj.move[depth] = ud2std[m]; | |
| if ($phase2(obj, edgex, esymx, cornx, csymx, midx, maxl - 1, depth + 1, m)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| function $solution(obj, facelets){ | |
| var $e0, cc, i, s; | |
| init_0(); | |
| for (i = 0; i < 54; ++i) { | |
| switch (facelets.charCodeAt(i)) { | |
| case 85: | |
| obj.f[i] = 0; | |
| break; | |
| case 82: | |
| obj.f[i] = 1; | |
| break; | |
| case 70: | |
| obj.f[i] = 2; | |
| break; | |
| case 68: | |
| obj.f[i] = 3; | |
| break; | |
| case 76: | |
| obj.f[i] = 4; | |
| break; | |
| case 66: | |
| obj.f[i] = 5; | |
| break; | |
| default:return 'Error 1'; | |
| } | |
| } | |
| cc = toCubieCube(obj.f); | |
| obj.sol = 22; | |
| return $Solve(obj, cc); | |
| } | |
| function Search(){ | |
| this.move = []; | |
| this.corn = []; | |
| this.csym = []; | |
| this.mid3 = []; | |
| this.e1 = []; | |
| this.e2 = []; | |
| this.twist = []; | |
| this.tsym = []; | |
| this.flip = []; | |
| this.fsym = []; | |
| this.slice_0 = []; | |
| this.corn0 = []; | |
| this.csym0 = []; | |
| this.mid30 = []; | |
| this.e10 = []; | |
| this.e20 = []; | |
| this.prun = []; | |
| this.count = []; | |
| this.f = []; | |
| } | |
| _ = Search.prototype; | |
| _.inverse = false; | |
| _.length1 = 0; | |
| _.maxlength2 = 0; | |
| _.sol = 999; | |
| _.solution = null; | |
| _.urfidx = 0; | |
| _.useSeparator = false; | |
| _.valid1 = 0; | |
| _.valid2 = 0; | |
| function init_0(safeStatusCallback){ | |
| if (inited) | |
| return; | |
| 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]]; | |
| 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]]; | |
| cornerColor = [[0, 1, 2], [0, 2, 4], [0, 4, 5], [0, 5, 1], [3, 2, 1], [3, 4, 2], [3, 5, 4], [3, 1, 5]]; | |
| edgeColor = [[0, 1], [0, 2], [0, 4], [0, 5], [3, 1], [3, 2], [3, 4], [3, 5], [2, 1], [2, 4], [5, 4], [5, 1]]; | |
| fact = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600]; | |
| move2str = ['U ', 'U2', "U'", 'R ', 'R2', "R'", 'F ', 'F2', "F'", 'D ', 'D2', "D'", 'L ', 'L2', "L'", 'B ', 'B2', "B'"]; | |
| perm3 = [[11, 10, 9], [10, 11, 9], [11, 9, 10], [9, 11, 10], [10, 9, 11], [9, 10, 11]]; | |
| e2c = [0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 0, 0, 0, 0]; | |
| urf1 = new CubieCube_2(2531, 1373, 67026819, 1877); | |
| urf2 = new CubieCube_2(2089, 1906, 322752913, 255); | |
| 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]]; | |
| var i, j; | |
| ud2std = [0, 1, 2, 4, 7, 9, 10, 11, 13, 16]; | |
| std2ud = []; | |
| for (i = 0; i < 10; ++i) { | |
| std2ud[ud2std[i]] = i; | |
| } | |
| ckmv = createArray(19, 18); | |
| ckmv2 = createArray(11, 10); | |
| for (i = 0; i < 18; ++i) { | |
| for (j = 0; j < 18; ++j) { | |
| ckmv[i][j] = ~~(i/3) == ~~(j/3) || ~~(i/3) % 3 == ~~(j/3) % 3 && i >= j; | |
| } | |
| ckmv[18][i] = false; | |
| } | |
| for (i = 0; i < 10; ++i) { | |
| for (j = 0; j < 10; ++j) { | |
| ckmv2[i][j] = ckmv[ud2std[i]][ud2std[j]]; | |
| } | |
| ckmv2[10][i] = false; | |
| } | |
| Cnk = createArray(12, 12); | |
| for (i=0; i<12; ++i) | |
| for (j=0; j<12; ++j) | |
| Cnk[i][j] = 0; | |
| for (i = 0; i < 12; ++i) { | |
| Cnk[i][0] = 1; | |
| Cnk[i][i] = 1; | |
| for (j = 1; j < i; ++j) { | |
| Cnk[i][j] = Cnk[i - 1][j - 1] + Cnk[i - 1][j]; | |
| } | |
| } | |
| parity4 = [];//24); | |
| for (i = 0; i < 24; ++i) { | |
| parity4[i] = getNParity(4,i); | |
| } | |
| initMove(); | |
| initSym(); | |
| initSym2Raw(); | |
| initCPermMove(); | |
| initEPermMove(); | |
| initFlipMove(); | |
| initTwistMove(); | |
| initUDSliceMoveConj(); | |
| initMid3Move(); | |
| initMid32MPerm(); | |
| initCParity(); | |
| initMPermMoveConj(); | |
| initTwistFlipSlicePrun(safeStatusCallback); | |
| initMCEPermPrun(safeStatusCallback); | |
| inited = true; | |
| } | |
| var inited = false; | |
| function bitCount(i){ | |
| i = i - (i >>> 1 & 1431655765); | |
| i = (i & 858993459) + (i >>> 2 & 858993459); | |
| return i + (i >>> 8) + (i >>> 4) & 15; | |
| } | |
| function getNParity(n, idx){ | |
| var p = 0; | |
| for (var i = n-2; i >= 0; --i) { | |
| p ^= idx % (n - i); | |
| idx = ~~(idx / (n - i)); | |
| } | |
| p = (p & 1); | |
| return p; | |
| } | |
| function toCubieCube(f){ | |
| var ccRet, col1, col2, i, j, ori; | |
| ccRet = new CubieCube_0; | |
| for (i = 0; i < 8; ++i) | |
| ccRet.cp[i] = 0; | |
| for (i = 0; i < 12; ++i) | |
| ccRet.ep[i] = 0; | |
| for (i = 0; i < 8; ++i) { | |
| for (ori = 0; ori < 3; ++ori) | |
| if (f[cornerFacelet[i][ori]] == 0 || f[cornerFacelet[i][ori]] == 3) | |
| break; | |
| col1 = f[cornerFacelet[i][(ori + 1) % 3]]; | |
| col2 = f[cornerFacelet[i][(ori + 2) % 3]]; | |
| for (j = 0; j < 8; ++j) { | |
| if (col1 == cornerColor[j][1] && col2 == cornerColor[j][2]) { | |
| ccRet.cp[i] = j; | |
| ccRet.co[i] = ori % 3; | |
| break; | |
| } | |
| } | |
| } | |
| for (i = 0; i < 12; ++i) { | |
| for (j = 0; j < 12; ++j) { | |
| if (f[edgeFacelet[i][0]] == edgeColor[j][0] && f[edgeFacelet[i][1]] == edgeColor[j][1]) { | |
| ccRet.ep[i] = j; | |
| ccRet.eo[i] = 0; | |
| break; | |
| } | |
| if (f[edgeFacelet[i][0]] == edgeColor[j][1] && f[edgeFacelet[i][1]] == edgeColor[j][0]) { | |
| ccRet.ep[i] = j; | |
| ccRet.eo[i] = 1; | |
| break; | |
| } | |
| } | |
| } | |
| return ccRet; | |
| } | |
| function toFaceCube(cc){ | |
| var c, e, f, i, j, n, ori, ts; | |
| f = [];//54); | |
| ts = [85, 82, 70, 68, 76, 66]; | |
| for (i = 0; i < 54; ++i) { | |
| f[i] = ts[~~(i / 9)]; | |
| } | |
| for (c = 0; c < 8; ++c) { | |
| j = cc.cp[c]; | |
| ori = cc.co[c]; | |
| for (n = 0; n < 3; ++n) | |
| f[cornerFacelet[c][(n + ori) % 3]] = ts[cornerColor[j][n]]; | |
| } | |
| for (e = 0; e < 12; ++e) { | |
| j = cc.ep[e]; | |
| ori = cc.eo[e]; | |
| for (n = 0; n < 2; ++n) | |
| f[edgeFacelet[e][(n + ori) % 2]] = ts[edgeColor[j][n]]; | |
| } | |
| return String.fromCharCode.apply(null, f); | |
| } | |
| /* Methods added by Lucas. */ | |
| var randomSource = Math; | |
| var initialized = false; | |
| function ini(iniRandomSource, statusCallback) { | |
| if (typeof statusCallback != "function") { | |
| statusCallback = function() {}; | |
| } | |
| if (!initialized) { | |
| search = new Search; | |
| init_0(statusCallback); | |
| randomSource = iniRandomSource; | |
| initialized = true; | |
| } | |
| } | |
| // SCRAMBLERS | |
| function rn(n) { | |
| return ~~(randomSource.random() * n); | |
| } | |
| var search; | |
| function getRandomScramble() { | |
| ini(Math); | |
| var cperm, eperm = rn(479001600); | |
| do { | |
| cperm = rn(40320); | |
| } while ((getNParity(8,cperm) ^ getNParity(12,eperm)) != 0); | |
| var posit = toFaceCube(new CubieCube_2(cperm, rn(2187), eperm, rn(2048))); | |
| var solution = $solution(search, posit); | |
| return solution; | |
| } | |
| function cntU(b){for(var c=0,a=0;a<b.length;a++)-1==b[a]&&c++;return c}; | |
| function fixOri(arr, cntU, base) { | |
| var sum = 0; | |
| var idx = 0; | |
| for (var i=0; i<arr.length-1; i++) { | |
| if (arr[i] == -1) { | |
| if (cntU-- == 1) { | |
| arr[i] = ((base << 4) - sum) % base; | |
| } else { | |
| arr[i] = rn(base); | |
| } | |
| } | |
| sum += arr[i]; | |
| idx *= base; | |
| idx += arr[i]; | |
| } | |
| return idx; | |
| } | |
| function fixPerm(arr, cntU, parity) { | |
| var val = [0,1,2,3,4,5,6,7,8,9,10,11]; | |
| for (var i=0; i<arr.length; i++) { | |
| if (arr[i] != -1) { | |
| val[arr[i]] = -1; | |
| } | |
| } | |
| for (var i=0, j=0; i<val.length; i++) { | |
| if (val[i] != -1) { | |
| val[j++] = val[i]; | |
| } | |
| } | |
| var last; | |
| for (var i=0; i<arr.length && cntU>0; i++) { | |
| if (arr[i] == -1) { | |
| var r = rn(cntU); | |
| arr[i] = val[r]; | |
| for (var j=r; j<11; j++) { | |
| val[j] = val[j+1]; | |
| } | |
| if (cntU-- == 2) { | |
| last = i; | |
| } | |
| } | |
| } | |
| if (getNParity(arr.length, getNPerm(arr, arr.length)) == 1-parity) { | |
| var temp = arr[i-1]; | |
| arr[i-1] = arr[last]; | |
| arr[last] = temp; | |
| } | |
| return getNPerm(arr, arr.length); | |
| } | |
| function getAnyScramble(ep, eo, cp, co) { | |
| ini(Math); | |
| eo.reverse(); | |
| eo.push(eo.shift()); | |
| var neo = fixOri(eo, cntU(eo), 2); | |
| var nco = fixOri(co, cntU(co), 3); | |
| var nep, ncp; | |
| var ue = cntU(ep); | |
| var uc = cntU(cp); | |
| if (ue==0 && uc==0) { | |
| nep = getNPerm(ep, 12); | |
| ncp = getNPerm(cp, 8); | |
| } else if (ue!=0 && uc==0) { | |
| ncp = getNPerm(cp, 8); | |
| nep = fixPerm(ep, ue, getNParity(8, ncp)); | |
| } else if (ue==0 && uc!=0) { | |
| nep = getNPerm(ep, 12); | |
| ncp = fixPerm(cp, uc, getNParity(12, nep)); | |
| } else { | |
| nep = fixPerm(ep, ue, -1); | |
| ncp = fixPerm(cp, uc, getNParity(12, nep)); | |
| } | |
| var posit = toFaceCube(new CubieCube_2(ncp, nco, nep, neo)); | |
| var solution = $solution(search, posit); | |
| return solution; | |
| } | |
| function getEdgeScramble() { | |
| return getAnyScramble([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1], | |
| [-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]); | |
| } | |
| function getCornerScramble() { | |
| 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,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1]); | |
| } | |
| function getLLScramble() { | |
| 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],[-1,-1,-1,-1,4,5,6,7],[-1,-1,-1,-1,0,0,0,0]); | |
| } | |
| function getLSLLScramble() { | |
| return getAnyScramble([-1,-1,-1,-1,4,5,6,7,-1,9,10,11], | |
| [-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]); | |
| } | |
| function getF2LScramble() { | |
| return getAnyScramble([-1,-1,-1,-1,4,5,6,7,-1,-1,-1,-1], | |
| [-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]); | |
| } | |
| function getZBLLScramble() { | |
| return getAnyScramble([-1,-1,-1,-1,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]); | |
| } | |
| function getLSEScramble() { | |
| switch (rn(4)) { | |
| 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]); | |
| case 1: return getAnyScramble([-1,-1,-1,-1,8,-1,9,-1,0,2,6,4],[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'"; | |
| case 2: return getAnyScramble([-1,-1,-1,-1,0,-1,2,-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"; | |
| case 3: return getAnyScramble([-1,-1,-1,-1,11,-1,10,-1,4,6,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"; | |
| } | |
| } | |
| function getCMLLScramble() { | |
| switch (rn(4)) { | |
| 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]); | |
| case 1: return getAnyScramble([-1,-1,-1,-1,8,-1,9,-1,0,2,6,4],[0,-1,0,-1,0,-1,0,-1,0,0,-1,-1],[-1,-1,-1,-1,0,1,5,4],[2,1,-1,-1,1,2,-1,-1])+"x'"; | |
| case 2: return getAnyScramble([-1,-1,-1,-1,0,-1,2,-1,11,10,9,8],[0,-1,0,-1,-1,-1,-1,-1,0,0,0,0],[-1,-1,-1,-1,3,2,1,0],[0,0,0,0,-1,-1,-1,-1])+"x2"; | |
| case 3: return getAnyScramble([-1,-1,-1,-1,11,-1,10,-1,4,6,2,0],[0,-1,0,-1,0,-1,0,-1,-1,-1,0,0],[-1,-1,-1,-1,7,6,2,3],[-1,-1,2,1,-1,-1,1,2])+"x"; | |
| } | |
| } | |
| function getCLLScramble() { | |
| 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]); | |
| } | |
| function getELLScramble() { | |
| 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]); | |
| } | |
| return { | |
| /* mark2 interface */ | |
| getRandomScramble: getRandomScramble,//getRandomScramble, | |
| /* added methods */ | |
| getEdgeScramble: getEdgeScramble, | |
| getCornerScramble: getCornerScramble, | |
| getLLScramble: getLLScramble, | |
| getLSLLScramble: getLSLLScramble, | |
| getZBLLScramble: getZBLLScramble, | |
| getF2LScramble: getF2LScramble, | |
| getLSEScramble: getLSEScramble, | |
| getCMLLScramble: getCMLLScramble, | |
| getCLLScramble: getCLLScramble, | |
| getELLScramble: getELLScramble, | |
| getAnyScramble: getAnyScramble | |
| }; | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment