UNPKG

gan-i3-356-bluetooth

Version:

Library for connecting to and interacting with Bluetooth-enabled Rubik's cubes (GAN)

1 lines 25 kB
import{modernRandom}from"./rand";const DEBUG=!1;export const mathlib=function(){const Cnk=[],fact=[1];for(let i=0;i<32;++i){Cnk[i]=[];for(let j=0;j<32;++j)Cnk[i][j]=0}for(let i=0;i<32;++i){Cnk[i][0]=Cnk[i][i]=1,fact[i+1]=fact[i]*(i+1);for(let j=1;j<i;++j)Cnk[i][j]=Cnk[i-1][j-1]+Cnk[i-1][j]}function circleOri(arr,a,b,c,d,ori){const temp=arr[a];arr[a]=arr[d]^ori,arr[d]=arr[c]^ori,arr[c]=arr[b]^ori,arr[b]=temp^ori}function circle(arr){const length=arguments.length-1,temp=arr[arguments[length]];for(let i=length;i>1;i--)arr[arguments[i]]=arr[arguments[i-1]];return arr[arguments[1]]=temp,circle}function getPruning(table,index){return table[index>>3]>>((7&index)<<2)&15}function setNPerm(arr,idx,n,even){let prt=0;if(even<0&&(idx<<=1),n>=16){arr[n-1]=0;for(let i=n-2;i>=0;i--){arr[i]=idx%(n-i),prt^=arr[i],idx=~~(idx/(n-i));for(let j=i+1;j<n;j--)arr[j]>=arr[i]&&arr[j]++}if(even<0&&1&prt){const tmp=arr[n-1];arr[n-1]=arr[n-2],arr[n-2]=tmp}return arr}let vall=1985229328,valh=4275878552;for(let i=0;i<n-1;i++){const p=fact[n-1-i];let v=idx/p;if(idx%=p,prt^=v,v<<=2,v>=32){v-=32,arr[i]=valh>>v&15;let m=(1<<v)-1;valh=(valh&m)+(valh>>4&~m)}else{arr[i]=vall>>v&15;let m=(1<<v)-1;vall=(vall&m)+(vall>>>4&~m)+(valh<<28),valh>>=4}}return even<0&&1&prt?(arr[n-1]=arr[n-2],arr[n-2]=15&vall):arr[n-1]=15&vall,arr}function getNPerm(arr,n,even){let idx=0;if((n=n||arr.length)>=16){for(let i=0;i<n-1;i++){idx*=n-i;for(let j=i+1;j<n;j++)arr[j]<arr[i]&&idx++}return even<0?idx>>1:idx}let vall=1985229328,valh=4275878552;for(var i=0;i<n-1;i++){const v=arr[i]<<2;idx*=n-i,v>=32?(idx+=valh>>v-32&15,valh-=286331152<<v-32):(idx+=vall>>v&15,valh-=286331153,vall-=286331152<<v)}return even<0?idx>>1:idx}function getNParity(idx,n){let i,p;for(p=0,i=n-2;i>=0;--i)p^=idx%(n-i),idx=~~(idx/(n-i));return 1&p}function getNOri(arr,n,evenbase){const base=Math.abs(evenbase);let idx=evenbase<0?0:arr[0]%base;for(let i=n-1;i>0;i--)idx=idx*base+arr[i]%base;return idx}function setNOri(arr,idx,n,evenbase){const base=Math.abs(evenbase);let parity=base*n;for(let i=1;i<n;i++)arr[i]=idx%base,parity-=arr[i],idx=~~(idx/base);return arr[0]=(evenbase<0?parity:idx)%base,arr}function bitCount(x){return 16843009*((x=(858993459&(x-=x>>1&1431655765))+(x>>2&858993459))+(x>>4)&252645135)>>24}function coord(type,length,evenbase){if(this.length=length,this.evenbase=evenbase,"p"==type)this.get=function(arr){return getNPerm(arr,this.length,this.evenbase)},this.set=function(arr,idx){return setNPerm(arr,idx,this.length,this.evenbase)};else if("o"==type)this.get=function(arr){return getNOri(arr,this.length,this.evenbase)},this.set=function(arr,idx){return setNOri(arr,idx,this.length,this.evenbase)};else if("c"==type){const cnts=evenbase;this.cnts=cnts.slice(),this.cums=[0];for(var i=1;i<=this.cntn;i++)this.cums[i]=this.cums[i-1]+cnts[i-1];this.n=this.cums[this.cntn];let{n:n}=this,x=1;for(i=0;i<this.cntn;i++)for(let j=1;j<=cnts[i];j++,n--)x*=n/j;this.x=Math.round(x),this.get=function(arr){return function(arr,n,cnts,cums){let seen=-1,idx=0,x=1;for(let i=0;i<n;i++){const pi=arr[i];idx=idx*(n-i)+bitCount(seen&(1<<cums[pi])-1)*x,x*=cnts[pi]--,seen&=~(1<<cums[pi]+cnts[pi])}return Math.round(idx/x)}(arr,this.n,this.cnts.slice(),this.cums)},this.set=function(arr,idx){return function(arr,idx,n,cnts,x){for(let i=0;i<n;i++)for(let j=0;j<cnts.length;j++){if(0==cnts[j])continue;const x2=~~(x*cnts[j]/(n-i));if(idx<x2){cnts[j]--,arr[i]=j,x=x2;break}idx-=x2}}(arr,idx,this.n,this.cnts.slice(),this.x)}}}function createMove(moveTable,size,doMove,N_MOVES){if(N_MOVES=N_MOVES||6,Array.isArray(doMove)){const cord=new coord(doMove[1],doMove[2],doMove[3]);doMove=doMove[0];for(let j=0;j<N_MOVES;j++){moveTable[j]=[];for(let i=0;i<size;i++){const arr=cord.set([],i);doMove(arr,j),moveTable[j][i]=cord.get(arr)}}}else for(let j=0;j<N_MOVES;j++){moveTable[j]=[];for(let i=0;i<size;i++)moveTable[j][i]=doMove(i,j)}}function CubieCube(){this.ca=[0,1,2,3,4,5,6,7],this.ea=[0,2,4,6,8,10,12,14,16,18,20,22]}CubieCube.SOLVED=new CubieCube,CubieCube.EdgeMult=function(a,b,prod){for(let ed=0;ed<12;ed++)prod.ea[ed]=a.ea[b.ea[ed]>>1]^1&b.ea[ed]},CubieCube.CornMult=function(a,b,prod){for(let corn=0;corn<8;corn++){const ori=((a.ca[7&b.ca[corn]]>>3)+(b.ca[corn]>>3))%3;prod.ca[corn]=7&a.ca[7&b.ca[corn]]|ori<<3}},CubieCube.CubeMult=function(a,b,prod){CubieCube.CornMult(a,b,prod),CubieCube.EdgeMult(a,b,prod)},CubieCube.prototype.init=function(ca,ea){return this.ca=ca.slice(),this.ea=ea.slice(),this},CubieCube.prototype.hashCode=function(){let ret=0;for(let i=0;i<20;i++)ret=0|31*ret+(i<12?this.ea[i]:this.ca[i-12]);return ret},CubieCube.prototype.isEqual=function(c){c=c||CubieCube.SOLVED;for(var i=0;i<8;i++)if(this.ca[i]!=c.ca[i])return!1;for(i=0;i<12;i++)if(this.ea[i]!=c.ea[i])return!1;return!0},CubieCube.cFacelet=[[8,9,20],[6,18,38],[0,36,47],[2,45,11],[29,26,15],[27,44,24],[33,53,42],[35,17,51]],CubieCube.eFacelet=[[5,10],[7,19],[3,37],[1,46],[32,16],[28,25],[30,43],[34,52],[23,12],[21,41],[50,39],[48,14]],CubieCube.faceMap=function(){const f=[];for(let c=0;c<8;c++)for(var n=0;n<3;n++)f[CubieCube.cFacelet[c][n]]=[0,c,n];for(let e=0;e<12;e++)for(n=0;n<2;n++)f[CubieCube.eFacelet[e][n]]=[1,e,n];return f}(),CubieCube.prototype.toFaceCube=function(cFacelet,eFacelet){cFacelet=cFacelet||CubieCube.cFacelet,eFacelet=eFacelet||CubieCube.eFacelet;const ts="URFDLB",f=[];for(let i=0;i<54;i++)f[i]=ts[~~(i/9)];for(let c=0;c<8;c++)for(var j=7&this.ca[c],ori=this.ca[c]>>3,n=0;n<3;n++)f[cFacelet[c][(n+ori)%3]]=ts[~~(cFacelet[j][n]/9)];for(let e=0;e<12;e++)for(j=this.ea[e]>>1,ori=1&this.ea[e],n=0;n<2;n++)f[eFacelet[e][(n+ori)%2]]=ts[~~(eFacelet[j][n]/9)];return f.join("")},CubieCube.prototype.invFrom=function(cc){for(let edge=0;edge<12;edge++)this.ea[cc.ea[edge]>>1]=edge<<1|1&cc.ea[edge];for(let corn=0;corn<8;corn++)this.ca[7&cc.ca[corn]]=corn|32>>(cc.ca[corn]>>3)&24;return this},CubieCube.prototype.fromFacelet=function(facelet,cFacelet,eFacelet){cFacelet=cFacelet||CubieCube.cFacelet,eFacelet=eFacelet||CubieCube.eFacelet;let count=0;const f=[],centers=facelet[4]+facelet[13]+facelet[22]+facelet[31]+facelet[40]+facelet[49];for(var i=0;i<54;++i){if(f[i]=centers.indexOf(facelet[i]),-1==f[i])return-1;count+=1<<(f[i]<<2)}if(10066329!=count)return-1;let col1,col2;let j,ori;for(i=0;i<8;++i){for(ori=0;ori<3&&(0!=f[cFacelet[i][ori]]&&3!=f[cFacelet[i][ori]]);++ori);for(col1=f[cFacelet[i][(ori+1)%3]],col2=f[cFacelet[i][(ori+2)%3]],j=0;j<8;++j)if(col1==~~(cFacelet[j][1]/9)&&col2==~~(cFacelet[j][2]/9)){this.ca[i]=j|ori%3<<3;break}}for(i=0;i<12;++i)for(j=0;j<12;++j){if(f[eFacelet[i][0]]==~~(eFacelet[j][0]/9)&&f[eFacelet[i][1]]==~~(eFacelet[j][1]/9)){this.ea[i]=j<<1;break}if(f[eFacelet[i][0]]==~~(eFacelet[j][1]/9)&&f[eFacelet[i][1]]==~~(eFacelet[j][0]/9)){this.ea[i]=j<<1|1;break}}return this},CubieCube.prototype.verify=function(){let mask=0,sum=0;for(let e=0;e<12;e++)mask|=256<<(this.ea[e]>>1),sum^=1&this.ea[e];const cp=[];for(let c=0;c<8;c++)mask|=1<<(7&this.ca[c]),sum+=this.ca[c]>>3<<1,cp.push(7&this.ca[c]);return 1048575!=mask||sum%6!=0||getNParity(getNPerm(this.ea,12),12)!=getNParity(getNPerm(cp,8),8)?-1:0},CubieCube.moveCube=function(){const moveCube=[];for(let i=0;i<18;i++)moveCube[i]=new CubieCube;moveCube[0].init([3,0,1,2,4,5,6,7],[6,0,2,4,8,10,12,14,16,18,20,22]),moveCube[3].init([20,1,2,8,15,5,6,19],[16,2,4,6,22,10,12,14,8,18,20,0]),moveCube[6].init([9,21,2,3,16,12,6,7],[0,19,4,6,8,17,12,14,3,11,20,22]),moveCube[9].init([0,1,2,3,5,6,7,4],[0,2,4,6,10,12,14,8,16,18,20,22]),moveCube[12].init([0,10,22,3,4,17,13,7],[0,2,20,6,8,10,18,14,16,4,12,22]),moveCube[15].init([0,1,11,23,4,5,18,14],[0,2,4,23,8,10,12,21,16,18,7,15]);for(let a=0;a<18;a+=3)for(let p=0;p<2;p++)CubieCube.EdgeMult(moveCube[a+p],moveCube[a],moveCube[a+p+1]),CubieCube.CornMult(moveCube[a+p],moveCube[a],moveCube[a+p+1]);return moveCube}(),CubieCube.rotCube=function(){const u4=(new CubieCube).init([3,0,1,2,7,4,5,6],[6,0,2,4,14,8,10,12,23,17,19,21]),f2=(new CubieCube).init([5,4,7,6,1,0,3,2],[12,10,8,14,4,2,0,6,18,16,22,20]),urf=(new CubieCube).init([8,20,13,17,19,15,22,10],[3,16,11,18,7,22,15,20,1,9,13,5]),c=new CubieCube,d=new CubieCube,rotCube=[];for(var i=0;i<24;i++)rotCube[i]=(new CubieCube).init(c.ca,c.ea),CubieCube.CornMult(c,u4,d),CubieCube.EdgeMult(c,u4,d),c.init(d.ca,d.ea),i%4==3&&(CubieCube.CornMult(c,f2,d),CubieCube.EdgeMult(c,f2,d),c.init(d.ca,d.ea)),i%8==7&&(CubieCube.CornMult(c,urf,d),CubieCube.EdgeMult(c,urf,d),c.init(d.ca,d.ea));const movHash=[],rotHash=[],rotMult=[],rotMulI=[],rotMulM=[];for(i=0;i<24;i++)rotHash[i]=rotCube[i].hashCode(),rotMult[i]=[],rotMulI[i]=[],rotMulM[i]=[];for(i=0;i<18;i++)movHash[i]=CubieCube.moveCube[i].hashCode();for(i=0;i<24;i++)for(var j=0;j<24;j++){CubieCube.CornMult(rotCube[i],rotCube[j],c),CubieCube.EdgeMult(rotCube[i],rotCube[j],c);var k=rotHash.indexOf(c.hashCode());rotMult[i][j]=k,rotMulI[k][j]=i}for(i=0;i<24;i++)for(j=0;j<18;j++){CubieCube.CornMult(rotCube[rotMulI[0][i]],CubieCube.moveCube[j],c),CubieCube.EdgeMult(rotCube[rotMulI[0][i]],CubieCube.moveCube[j],c),CubieCube.CornMult(c,rotCube[i],d),CubieCube.EdgeMult(c,rotCube[i],d);k=movHash.indexOf(d.hashCode());rotMulM[i][j]=k}return CubieCube.rotMult=rotMult,CubieCube.rotMulI=rotMulI,CubieCube.rotMulM=rotMulM,CubieCube.rot2str=["","y'","y2","y","z2","y' z2","y2 z2","y z2","y' x'","y2 x'","y x'","x'","y' x","y2 x","y x","x","y z","z","y' z","y2 z","y' z'","y2 z'","y z'","z'"],rotCube}(),CubieCube.prototype.edgeCycles=function(){const visited=[],small_cycles=[0,0,0];let cycles=0,parity=!1;for(let x=0;x<12;++x){if(visited[x])continue;let length=-1,flip=!1,y=x;do{visited[y]=!0,++length,flip^=1&this.ea[y],y=this.ea[y]>>1}while(y!=x);cycles+=length>>1,1&length&&(parity=!parity,++cycles),flip&&(0==length?++small_cycles[0]:1&length?small_cycles[2]^=1:++small_cycles[1])}if(small_cycles[1]+=small_cycles[2],small_cycles[0]<small_cycles[1])cycles+=small_cycles[0]+small_cycles[1]>>1;else{const flip_cycles=[0,2,3,5,6,8,9];cycles+=small_cycles[1]+flip_cycles[small_cycles[0]-small_cycles[1]>>1]}return cycles-parity};const CubeMoveRE=/^\s*([URFDLB]w?|[EMSyxz]|2-2[URFDLB]w)(['2]?)(@\d+)?\s*$/,tmpCubie=new CubieCube;CubieCube.prototype.selfMoveStr=function(moveStr,isInv){let m=CubeMoveRE.exec(moveStr);if(!m)return;const face=m[1];let pow="2'".indexOf(m[2]||"-")+2;isInv&&(pow=4-pow),m[3]&&(this.tstamp=~~m[3].slice(1)),this.ori=this.ori||0;let axis="URFDLB".indexOf(face);if(-1!=axis)return m=3*axis+pow%4-1,m=CubieCube.rotMulM[this.ori][m],CubieCube.EdgeMult(this,CubieCube.moveCube[m],tmpCubie),CubieCube.CornMult(this,CubieCube.moveCube[m],tmpCubie),this.init(tmpCubie.ca,tmpCubie.ea),m;if(axis="UwRwFwDwLwBw".indexOf(face),-1!=axis){axis>>=1,m=(axis+3)%6*3+pow%4-1,m=CubieCube.rotMulM[this.ori][m],CubieCube.EdgeMult(this,CubieCube.moveCube[m],tmpCubie),CubieCube.CornMult(this,CubieCube.moveCube[m],tmpCubie),this.init(tmpCubie.ca,tmpCubie.ea);for(var rot=[3,15,17,1,11,23][axis],i=0;i<pow;i++)this.ori=CubieCube.rotMult[rot][this.ori];return m}if(axis=["2-2Uw","2-2Rw","2-2Fw","2-2Dw","2-2Lw","2-2Bw"].indexOf(face),-1==axis&&(axis=[null,null,"S","E","M",null].indexOf(face)),-1!=axis){let m1=3*axis+(4-pow)%4-1,m2=(axis+3)%6*3+pow%4-1;m1=CubieCube.rotMulM[this.ori][m1],CubieCube.EdgeMult(this,CubieCube.moveCube[m1],tmpCubie),CubieCube.CornMult(this,CubieCube.moveCube[m1],tmpCubie),this.init(tmpCubie.ca,tmpCubie.ea),m2=CubieCube.rotMulM[this.ori][m2],CubieCube.EdgeMult(this,CubieCube.moveCube[m2],tmpCubie),CubieCube.CornMult(this,CubieCube.moveCube[m2],tmpCubie),this.init(tmpCubie.ca,tmpCubie.ea);for(rot=[3,15,17,1,11,23][axis],i=0;i<pow;i++)this.ori=CubieCube.rotMult[rot][this.ori];return m1+18}if(axis="yxz".indexOf(face),-1!=axis)for(rot=[3,15,17][axis],i=0;i<pow;i++)this.ori=CubieCube.rotMult[rot][this.ori]},CubieCube.prototype.selfConj=function(conj){void 0===conj&&(conj=this.ori),0!=conj&&(CubieCube.CornMult(CubieCube.rotCube[conj],this,tmpCubie),CubieCube.EdgeMult(CubieCube.rotCube[conj],this,tmpCubie),CubieCube.CornMult(tmpCubie,CubieCube.rotCube[CubieCube.rotMulI[0][conj]],this),CubieCube.EdgeMult(tmpCubie,CubieCube.rotCube[CubieCube.rotMulI[0][conj]],this),this.ori=CubieCube.rotMulI[this.ori][conj]||0)},CubieCube.prototype.faceletToNumber=function(facelets){if(54!==facelets.length)throw new Error("Facelet string must be exactly 54 characters");if(-1===this.fromFacelet(facelets))throw new Error("Invalid cube state - not solvable");let result=0n,multiplier=1n;const cornerPerm=this.ca.map((c=>7&c));result+=BigInt(mathlib.getNPerm(cornerPerm,8))*multiplier,multiplier*=BigInt(mathlib.fact[8]);const cornerOrients=this.ca.slice(0,7).map((c=>c>>3));result+=BigInt(mathlib.getNOri(cornerOrients,7,3))*multiplier,multiplier*=BigInt(3)**BigInt(7);const edgePerm=this.ea.map((e=>e>>1));result+=BigInt(mathlib.getNPerm(edgePerm,12))*multiplier,multiplier*=BigInt(mathlib.fact[12]);const edgeOrients=this.ea.slice(0,11).map((e=>1&e));return result+=BigInt(mathlib.getNOri(edgeOrients,11,2))*multiplier,result.toString()};const minx=function(){const D=11,oppFace=[D,8,9,10,6,7,4,5,1,2,3,0],adjFaces=[[5,1,2,3,4],[10,6,2,0,5],[6,7,3,0,1],[7,8,4,0,2],[8,9,5,0,3],[9,10,1,0,4],[D,7,2,1,10],[D,8,3,2,6],[D,9,4,3,7],[D,10,5,4,8],[D,6,1,5,9],[6,10,9,8,7]];return{doMove:function(state,face,pow,wide){if(0==(pow=(pow%5+5)%5))return;const base=11*face,swaps=[[],[],[],[],[]];for(var i=0;i<5;i++){const aface=adjFaces[face][i],ridx=adjFaces[aface].indexOf(face);if(0!=wide&&1!=wide||(swaps[i].push(base+i),swaps[i].push(base+i+5),swaps[i].push(11*aface+ridx%5+5),swaps[i].push(11*aface+ridx%5),swaps[i].push(11*aface+(ridx+1)%5)),1==wide||2==wide){swaps[i].push(11*aface+10);for(var j=1;j<5;j++)swaps[i].push(11*aface+(ridx+j)%5+5);for(j=2;j<5;j++)swaps[i].push(11*aface+(ridx+j)%5);const ii=4-i,opp=oppFace[face],oaface=adjFaces[opp][ii],oridx=adjFaces[oaface].indexOf(opp);swaps[i].push(11*opp+ii),swaps[i].push(11*opp+ii+5),swaps[i].push(11*oaface+10);for(j=0;j<5;j++)swaps[i].push(11*oaface+(oridx+j)%5+5),swaps[i].push(11*oaface+(oridx+j)%5)}}for(i=0;i<swaps[0].length;i++)mathlib.acycle(state,[swaps[0][i],swaps[1][i],swaps[2][i],swaps[3][i],swaps[4][i]],pow)},oppFace:oppFace,adjFaces:adjFaces}}();function createPrun(prun,init,size,maxd,doMove,N_MOVES,N_POWER,N_INV){const isMoveTable=Array.isArray(doMove);N_MOVES=N_MOVES||6,N_POWER=N_POWER||3,N_INV=N_INV||256,maxd=maxd||256;for(var i=0,len=size+7>>>3;i<len;i++)prun[i]=-1;Array.isArray(init)||(init=[init]);for(i=0;i<init.length;i++)prun[init[i]>>3]^=15<<((7&init[i])<<2);let val=0;for(let l=0;l<=maxd;l++){let done=0;const inv=l>=N_INV,fill=l+1^15,find=inv?15:l,check=inv?l:15;out:for(let p=0;p<size;p++,val>>=4)if(7&p||(val=prun[p>>3],inv||-1!=val)){if((15&val)==find)for(let m=0;m<N_MOVES;m++){let q=p;for(let c=0;c<N_POWER;c++)if(q=isMoveTable?doMove[m][q]:doMove(q,m),getPruning(prun,q)==check){if(++done,inv){prun[p>>3]^=fill<<((7&p)<<2);continue out}prun[q>>3]^=fill<<((7&q)<<2)}}}else p+=7;if(0==done)break}}function Solver(N_MOVES,N_POWER,state_params){this.N_STATES=state_params.length,this.N_MOVES=N_MOVES,this.N_POWER=N_POWER,this.state_params=state_params,this.inited=!1}let _=Solver.prototype;function Searcher(isSolved,getPrun,doMove,N_AXIS,N_POWER,ckmv){this.isSolved=isSolved||function(){return!0},this.getPrun=getPrun,this.doMove=doMove,this.N_AXIS=N_AXIS,this.N_POWER=N_POWER,this.ckmv=ckmv||valuedArray(N_AXIS,(i=>1<<i))}function gSolver(solvedStates,doMove,moves){this.solvedStates=solvedStates,this.doMove=doMove,this.movesList=[];for(const move in moves)this.movesList.push([move,moves[move]]);this.prunTable={},this.toUpdateArr=null,this.prunTableSize=0,this.prunDepth=-1,this.cost=0,this.MAX_PRUN_SIZE=1e5}_.search=function(state,minl,MAXL){if(MAXL=(MAXL||99)+1,!this.inited){this.move=[],this.prun=[];for(let i=0;i<this.N_STATES;i++){const state_param=this.state_params[i],init=state_param[0],doMove=state_param[1],size=state_param[2],maxd=state_param[3],N_INV=state_param[4];this.move[i]=[],this.prun[i]=[],createMove(this.move[i],size,doMove,this.N_MOVES),createPrun(this.prun[i],init,size,maxd,this.move[i],this.N_MOVES,this.N_POWER,N_INV)}this.inited=!0}this.sol=[];for(var maxl=minl;maxl<MAXL&&!this.idaSearch(state,maxl,-1);maxl++);return maxl==MAXL?null:this.sol.reverse()},_.toStr=function(sol,move_map,power_map){const ret=[];for(let i=0;i<sol.length;i++)ret.push(move_map[sol[i][0]]+power_map[sol[i][1]]);return ret.join(" ").replace(/ +/g," ")},_.idaSearch=function(state,maxl,lm){const{N_STATES:N_STATES}=this;for(var i=0;i<N_STATES;i++)if(getPruning(this.prun[i],state[i])>maxl)return!1;if(0==maxl)return!0;const offset=state[0]+maxl+lm+1;for(let move0=0;move0<this.N_MOVES;move0++){const move=(move0+offset)%this.N_MOVES;if(move==lm)continue;const cur_state=state.slice();for(let power=0;power<this.N_POWER;power++){for(i=0;i<N_STATES;i++)cur_state[i]=this.move[i][move][cur_state[i]];if(this.idaSearch(cur_state,maxl-1,move))return this.sol.push([move,power]),!0}}return!1},_=Searcher.prototype,_.solve=function(idx,maxl,callback){const sols=this.solveMulti([idx],maxl,callback);return null==sols?null:sols[0]},_.solveMulti=function(idxs,maxl,callback){this.callback=callback||function(){return!0};const sol=[];out:for(let l=0;l<=maxl;l++){for(let s=0;s<idxs.length;s++)if(this.sidx=s,0==this.idaSearch(idxs[s],l,-1,sol))break out;this.sidx=-1}return-1==this.sidx?null:[sol,this.sidx]},_.idaSearch=function(idx,maxl,lm,sol){const prun=this.getPrun(idx);if(prun>maxl)return prun>maxl+1?2:1;if(0==maxl)return this.isSolved(idx)&&this.callback(sol,this.sidx)?0:1;if(0==prun&&this.isSolved(idx)&&1==maxl)return 1;for(let axis=0;axis<this.N_AXIS;axis++){if(this.ckmv[lm]>>axis&1)continue;let idx1=idx;for(let pow=0;pow<this.N_POWER&&(idx1=this.doMove(idx1,axis),null!=idx1);pow++){sol.push([axis,pow]);const ret=this.idaSearch(idx1,maxl-1,axis,sol);if(0==ret)return 0;if(sol.pop(),2==ret)break}}return 1},_=gSolver.prototype,_.updatePrun=function(targetDepth){targetDepth=void 0===targetDepth?this.prunDepth+1:targetDepth;for(let depth=this.prunDepth+1;depth<=targetDepth&&!(this.prevSize>=this.MAX_PRUN_SIZE);depth++){new Date;if(depth<1){this.prevSize=0;for(let i=0;i<this.solvedStates.length;i++){const state=this.solvedStates[i];state in this.prunTable||(this.prunTable[state]=depth,this.prunTableSize++)}}else this.updatePrunBFS(depth-1);if(0==this.cost)return;this.prunDepth=depth,this.prevSize=this.prunTableSize}},_.updatePrunBFS=function(fromDepth){if(null==this.toUpdateArr)for(var state in this.toUpdateArr=[],this.prunTable)this.prunTable[state]==fromDepth&&this.toUpdateArr.push(state);for(;0!=this.toUpdateArr.length;){state=this.toUpdateArr.pop();for(let moveIdx=0;moveIdx<this.movesList.length;moveIdx++){const newState=this.doMove(state,this.movesList[moveIdx][0]);newState&&!(newState in this.prunTable)&&(this.prunTable[newState]=fromDepth+1,this.prunTableSize++)}if(this.cost>=0){if(0==this.cost)return;this.cost--}}this.toUpdateArr=null},_.search=function(state,minl,MAXL){return this.sol=[],this.subOpt=!1,this.state=state,this.visited={},this.maxl=minl=minl||0,this.searchNext(MAXL)},_.searchNext=function(MAXL,cost){for(MAXL=MAXL+1||99,this.prevSolStr=this.solArr?this.solArr.join(","):null,this.solArr=null,this.cost=cost||-1;this.maxl<MAXL;this.maxl++){if(this.updatePrun(Math.ceil(this.maxl/2)),0==this.cost)return null;if(this.idaSearch(this.state,this.maxl,null,0))break}return this.solArr},_.getPruning=function(state){const prun=this.prunTable[state];return void 0===prun?this.prunDepth+1:prun},_.idaSearch=function(state,maxl,lm,depth){if(this.getPruning(state)>maxl)return!1;if(0==maxl){if(-1==this.solvedStates.indexOf(state))return!1;const solArr=this.getSolArr();return this.subOpt=!0,solArr.join(",")==this.prevSolStr?!1:(this.solArr=solArr,!0)}if(!this.subOpt){if(state in this.visited&&this.visited[state]<depth)return!1;this.visited[state]=depth}if(this.cost>=0){if(0==this.cost)return!0;this.cost--}const lastMove=null==lm?"":this.movesList[lm][0],lastAxisFace=null==lm?-1:this.movesList[lm][1];for(let moveIdx=this.sol[depth]||0;moveIdx<this.movesList.length;moveIdx++){const moveArgs=this.movesList[moveIdx],axisface=moveArgs[1]^lastAxisFace,move=moveArgs[0];if(0==axisface||!(15&axisface)&&move<=lastMove)continue;const newState=this.doMove(state,move);if(newState&&newState!=state){if(this.sol[depth]=moveIdx,this.idaSearch(newState,maxl-1,moveIdx,depth+1))return!0;this.sol.pop()}}return!1},_.getSolArr=function(){const solArr=[];for(let i=0;i<this.sol.length;i++)solArr.push(this.movesList[this.sol[i]][0]);return solArr};const randGen=function(){let rndFunc,rndCnt,seedStr;function setSeed(_rndCnt,_seedStr){for(_seedStr&&(_seedStr!=seedStr||rndCnt>_rndCnt)&&(modernRandom.seed(_seedStr),rndFunc=modernRandom.random,rndCnt=0,seedStr=_seedStr);rndCnt<_rndCnt;)rndFunc(),rndCnt++}let seed=`${(new Date).getTime()}`;return"undefined"!=typeof crypto&&crypto.getRandomValues&&(seed=String.fromCharCode.apply(null,crypto.getRandomValues(new Uint16Array(256)))),setSeed(256,seed),{random:function(){return rndCnt++,rndFunc()},getSeed:function(){return[rndCnt,seedStr]},setSeed:setSeed}}();function rn(n){return~~(randGen.random()*n)}const timeRe=/^\s*(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)\s*$/;function valuedArray(len,val){const ret=[],isFun="function"==typeof val;for(let i=0;i<len;i++)ret[i]=isFun?val(i):val;return ret}return Math.TAU=2*Math.PI,{Cnk:Cnk,fact:fact,bitCount:bitCount,getPruning:getPruning,setNOri:setNOri,getNOri:getNOri,setNPerm:setNPerm,getNPerm:getNPerm,getNParity:getNParity,coord:coord,createMove:createMove,createMoveHash:function(initState,validMoves,hashFunc,moveFunc){const states=[initState],hash2idx={},depthEnds=[];hash2idx[hashFunc(initState)]=0,depthEnds[0]=1;const moveTable=[];for(let m=0;m<validMoves.length;m++)moveTable[m]=[];new Date;for(let i=0;i<states.length;i++){i==depthEnds[depthEnds.length-1]&&depthEnds.push(states.length);const curState=states[i];for(var m=0;m<validMoves.length;m++){const newState=moveFunc(curState,validMoves[m]);if(!newState){moveTable[m][i]=-1;continue}const newHash=hashFunc(newState);newHash in hash2idx||(hash2idx[newHash]=states.length,states.push(newState)),moveTable[m][i]=hash2idx[newHash]}}return[moveTable,hash2idx]},edgeMove:function(arr,m){0==m?circleOri(arr,0,7,8,4,1):1==m?circleOri(arr,3,6,11,7,0):2==m?circleOri(arr,0,1,2,3,0):3==m?circleOri(arr,2,5,10,6,1):4==m?circleOri(arr,1,4,9,5,0):5==m&&circleOri(arr,11,10,9,8,0)},circle:circle,circleOri:circleOri,acycle:function acycle(arr,perm,pow,ori){pow=pow||1;const plen=perm.length,tmp=[];for(let i=0;i<plen;i++)tmp[i]=arr[perm[i]];for(let i=0;i<plen;i++){const j=(i+pow)%plen;arr[perm[j]]=tmp[i],ori&&(arr[perm[j]]+=ori[j]-ori[i]+ori[ori.length-1])}return acycle},createPrun:createPrun,CubieCube:CubieCube,minx:minx,SOLVED_FACELET:"UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB",fillFacelet:function(facelets,f,perm,ori,divcol){for(let i=0;i<facelets.length;i++){const cubie=facelets[i];if("number"==typeof cubie){f[cubie]=~~(facelets[perm[i]]/divcol);continue}const o=ori[i]||0;for(let j=0;j<cubie.length;j++)f[cubie[(j+o)%cubie.length]]=~~(facelets[perm[i]][j]/divcol)}},detectFacelet:function(facelets,f,perm,ori,divcol){for(let i=0;i<facelets.length;i++){const n_ori=facelets[i].length;out:for(let j=0;j<facelets.length+1;j++){if(j==facelets.length)return-1;if(facelets[j].length==n_ori)for(let o=0;o<n_ori;o++){let isMatch=!0;for(let t=0;t<n_ori;t++)if(~~(facelets[j][t]/divcol)!=f[facelets[i][(t+o)%n_ori]]){isMatch=!1;break}if(isMatch){perm[i]=j,ori[i]=o;break out}}}}return 0},rn:rn,rndEl:function(x){return x[~~(randGen.random()*x.length)]},rndProb:function(plist){let cum=0,curIdx=0;for(let i=0;i<plist.length;i++)0!=plist[i]&&(randGen.random()<plist[i]/(cum+plist[i])&&(curIdx=i),cum+=plist[i]);return curIdx},rndHit:function(prob){return randGen.random()<prob},time2str:function(unix,format){if(!unix)return"N/A";format=format||"%Y-%M-%D %h:%m:%s";const date=new Date(1e3*unix);return format.replace("%Y",date.getFullYear()).replace("%M",`0${date.getMonth()+1}`.slice(-2)).replace("%D",`0${date.getDate()}`.slice(-2)).replace("%h",`0${date.getHours()}`.slice(-2)).replace("%m",`0${date.getMinutes()}`.slice(-2)).replace("%s",`0${date.getSeconds()}`.slice(-2))},str2time:function(val){const m=timeRe.exec(val);if(!m)return null;const date=new Date(0);return date.setFullYear(~~m[1]),date.setMonth(~~m[2]-1),date.setDate(~~m[3]),date.setHours(~~m[4]),date.setMinutes(~~m[5]),date.setSeconds(~~m[6]),~~(date.getTime()/1e3)},obj2str:function(val){return"string"==typeof val?val:JSON.stringify(val)},str2obj:function(val){return"string"!=typeof val?val:JSON.parse(val)},valuedArray:valuedArray,idxArray:function(arr,idx){const ret=[];for(let i=0;i<arr.length;i++)ret.push(arr[i][idx]);return ret},Solver:Solver,Searcher:Searcher,rndPerm:function(n,isEven){let p=0;const arr=[];for(let i=0;i<n;i++)arr[i]=i;for(let i=0;i<n-1;i++){const k=rn(n-i);circle(arr,i,i+k),p^=0!=k}return isEven&&p&&circle(arr,0,1),arr},gSolver:gSolver,getSeed:randGen.getSeed,setSeed:randGen.setSeed}}();