11/**
22 Copyright (C) 2012 Shuang Chen
3-
3+
44 This program is free software: you can redistribute it and/or modify
55 it under the terms of the GNU General Public License as published by
66 the Free Software Foundation, either version 3 of the License, or
77 (at your option) any later version.
8-
8+
99 This program is distributed in the hope that it will be useful,
1010 but WITHOUT ANY WARRANTY; without even the implied warranty of
1111 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212 GNU General Public License for more details.
13-
13+
1414 You should have received a copy of the GNU General Public License
1515 along with this program. If not, see <http://www.gnu.org/licenses/>.
1616 */
2525 */
2626public class Search {
2727
28+ static final boolean USE_TWIST_FLIP_PRUN = true ;
29+
30+ static boolean inited = false ;
31+
2832 private int [] move = new int [31 ];
2933
3034 private int [] corn = new int [20 ];
@@ -34,7 +38,7 @@ public class Search {
3438 private int [] twist = new int [6 ];
3539 private int [] flip = new int [6 ];
3640 private int [] slice = new int [6 ];
37-
41+
3842 private int [] corn0 = new int [6 ];
3943 private int [] ud8e0 = new int [6 ];
4044 private int [] prun = new int [6 ];
@@ -52,7 +56,7 @@ public class Search {
5256 private long timeMin ;
5357 private int verbose ;
5458 private CubieCube cc = new CubieCube ();
55-
59+
5660 /**
5761 * Verbose_Mask determines if a " . " separates the phase1 and phase2 parts of the solver string like in F' R B R L2 F .
5862 * U2 U D for example.<br>
@@ -118,7 +122,7 @@ public class Search {
118122 *
119123 * @param verbose
120124 * determins the format of the solution(s). see USE_SEPARATOR, INVERSE_SOLUTION, APPEND_LENGTH
121- *
125+ *
122126 * @return The solution string or an error code:<br>
123127 * Error 1: There is not exactly one facelet of each colour<br>
124128 * Error 2: Not all 12 edges exist exactly once<br>
@@ -141,16 +145,48 @@ public synchronized String solution(String facelets, int maxDepth, long timeOut,
141145 this .solution = null ;
142146 return solve (cc );
143147 }
144-
148+
149+ public static boolean isInited () {
150+ return inited ;
151+ }
152+
153+ public synchronized static void init () {
154+ if (inited ) {
155+ return ;
156+ }
157+ CubieCube .initMove ();
158+ CubieCube .initSym ();
159+ CubieCube .initFlipSym2Raw ();
160+ CubieCube .initTwistSym2Raw ();
161+ CubieCube .initPermSym2Raw ();
162+
163+ CoordCube .initFlipMove ();
164+ CoordCube .initTwistMove ();
165+ CoordCube .initUDSliceMoveConj ();
166+
167+ CoordCube .initCPermMove ();
168+ CoordCube .initEPermMove ();
169+ CoordCube .initMPermMoveConj ();
170+
171+ if (USE_TWIST_FLIP_PRUN ) {
172+ CoordCube .initTwistFlipPrun ();
173+ }
174+ CoordCube .initSliceTwistPrun ();
175+ CoordCube .initSliceFlipPrun ();
176+ CoordCube .initMEPermPrun ();
177+ CoordCube .initMCPermPrun ();
178+ inited = true ;
179+ }
180+
145181 int verify (String facelets ) {
146182 int count = 0x000000 ;
147183 try {
148184 String center = new String (new char [] {
149- facelets .charAt (4 ),
150- facelets .charAt (13 ),
151- facelets .charAt (22 ),
152- facelets .charAt (31 ),
153- facelets .charAt (40 ),
185+ facelets .charAt (4 ),
186+ facelets .charAt (13 ),
187+ facelets .charAt (22 ),
188+ facelets .charAt (31 ),
189+ facelets .charAt (40 ),
154190 facelets .charAt (49 )
155191 });
156192 for (int i =0 ; i <54 ; i ++) {
@@ -171,16 +207,16 @@ int verify(String facelets) {
171207 }
172208
173209 private String solve (CubieCube c ) {
174- Tools . init ();
210+ init ();
175211 int conjMask = 0 ;
176212 for (int i =0 ; i <6 ; i ++) {
177213 twist [i ] = c .getTwistSym ();
178214 flip [i ] = c .getFlipSym ();
179215 slice [i ] = c .getUDSlice ();
180216 corn0 [i ] = c .getCPermSym ();
181217 ud8e0 [i ] = c .getU4Comb () << 16 | c .getD4Comb ();
182-
183- for (int j =0 ; j <i ; j ++) { //If S_i^-1 * C * S_i == C, It's unnecessary to compute it again.
218+
219+ for (int j =0 ; j <i ; j ++) { //If S_i^-1 * C * S_i == C, It's unnecessary to compute it again.
184220 if (twist [i ] == twist [j ] && flip [i ] == flip [j ] && slice [i ] == slice [j ]
185221 && corn0 [i ] == corn0 [j ] && ud8e0 [i ] == ud8e0 [j ]) {
186222 conjMask |= 1 << i ;
@@ -189,11 +225,11 @@ private String solve(CubieCube c) {
189225 }
190226 if ((conjMask & (1 << i )) == 0 ) {
191227 prun [i ] = Math .max (Math .max (
192- CoordCube .getPruning (CoordCube .UDSliceTwistPrun ,
228+ CoordCube .getPruning (CoordCube .UDSliceTwistPrun ,
193229 (twist [i ]>>>3 ) * 495 + CoordCube .UDSliceConj [slice [i ]&0x1ff ][twist [i ]&7 ]),
194- CoordCube .getPruning (CoordCube .UDSliceFlipPrun ,
230+ CoordCube .getPruning (CoordCube .UDSliceFlipPrun ,
195231 (flip [i ]>>>3 ) * 495 + CoordCube .UDSliceConj [slice [i ]&0x1ff ][flip [i ]&7 ])),
196- Tools . USE_TWIST_FLIP_PRUN ? CoordCube .getPruning (CoordCube .TwistFlipPrun ,
232+ USE_TWIST_FLIP_PRUN ? CoordCube .getPruning (CoordCube .TwistFlipPrun ,
197233 (twist [i ]>>>3 ) * 2688 + (flip [i ] & 0xfff8 | CubieCube .Sym8MultInv [flip [i ]&7 ][twist [i ]&7 ])) : 0 );
198234 }
199235 c .URFConjugate ();
@@ -220,7 +256,7 @@ && phase1(twist[urfIdx]>>>3, twist[urfIdx]&7, flip[urfIdx]>>>3, flip[urfIdx]&7,
220256 }
221257 return solution == null ? "Error 7" : solution ;
222258 }
223-
259+
224260 /**
225261 * @return
226262 * 0: Found or Timeout
@@ -237,12 +273,12 @@ private int phase1(int twist, int tsym, int flip, int fsym, int slice, int maxl,
237273 }
238274 for (int power =0 ; power <3 ; power ++) {
239275 int m = axis + power ;
240-
276+
241277 int slicex = CoordCube .UDSliceMove [slice ][m ] & 0x1ff ;
242278 int twistx = CoordCube .TwistMove [twist ][CubieCube .Sym8Move [tsym ][m ]];
243279 int tsymx = CubieCube .Sym8Mult [twistx & 7 ][tsym ];
244280 twistx >>>= 3 ;
245- int prun = CoordCube .getPruning (CoordCube .UDSliceTwistPrun ,
281+ int prun = CoordCube .getPruning (CoordCube .UDSliceTwistPrun ,
246282 twistx * 495 + CoordCube .UDSliceConj [slicex ][tsymx ]);
247283 if (prun > maxl ) {
248284 break ;
@@ -252,16 +288,16 @@ private int phase1(int twist, int tsym, int flip, int fsym, int slice, int maxl,
252288 int flipx = CoordCube .FlipMove [flip ][CubieCube .Sym8Move [fsym ][m ]];
253289 int fsymx = CubieCube .Sym8Mult [flipx & 7 ][fsym ];
254290 flipx >>>= 3 ;
255- if (Tools . USE_TWIST_FLIP_PRUN ) {
256- prun = CoordCube .getPruning (CoordCube .TwistFlipPrun ,
291+ if (USE_TWIST_FLIP_PRUN ) {
292+ prun = CoordCube .getPruning (CoordCube .TwistFlipPrun ,
257293 (twistx * 336 + flipx ) << 3 | CubieCube .Sym8MultInv [fsymx ][tsymx ]);
258294 if (prun > maxl ) {
259295 break ;
260296 } else if (prun == maxl ) {
261297 continue ;
262298 }
263299 }
264- prun = CoordCube .getPruning (CoordCube .UDSliceFlipPrun ,
300+ prun = CoordCube .getPruning (CoordCube .UDSliceFlipPrun ,
265301 flipx * 495 + CoordCube .UDSliceConj [slicex ][fsymx ]);
266302 if (prun > maxl ) {
267303 break ;
@@ -274,11 +310,11 @@ private int phase1(int twist, int tsym, int flip, int fsym, int slice, int maxl,
274310 if (ret != 1 ) {
275311 return ret >> 1 ;
276312 }
277- }
313+ }
278314 }
279315 return 1 ;
280316 }
281-
317+
282318 /**
283319 * @return
284320 * 0: Found or Timeout
@@ -298,7 +334,7 @@ private int initPhase2() {
298334 csym = CubieCube .SymMult [cidx & 0xf ][csym ];
299335 cidx >>>= 4 ;
300336 corn [i +1 ] = cidx << 4 | csym ;
301-
337+
302338 int cx = CoordCube .UDSliceMove [mid4 [i ] & 0x1ff ][m ];
303339 mid4 [i +1 ] = Util .permMult [mid4 [i ]>>>9 ][cx >>>9 ]<<9 |cx &0x1ff ;
304340 }
@@ -308,18 +344,18 @@ private int initPhase2() {
308344 if (prun >= maxDep2 ) {
309345 return prun > maxDep2 ? 2 : 1 ;
310346 }
311-
347+
312348 int u4e = ud8e [valid2 ] >>> 16 ;
313349 int d4e = ud8e [valid2 ] & 0xffff ;
314350 for (int i =valid2 ; i <depth1 ; i ++) {
315351 int m = move [i ];
316-
352+
317353 int cx = CoordCube .UDSliceMove [u4e & 0x1ff ][m ];
318354 u4e = Util .permMult [u4e >>>9 ][cx >>>9 ]<<9 |cx &0x1ff ;
319-
355+
320356 cx = CoordCube .UDSliceMove [d4e & 0x1ff ][m ];
321357 d4e = Util .permMult [d4e >>>9 ][cx >>>9 ]<<9 |cx &0x1ff ;
322-
358+
323359 ud8e [i +1 ] = u4e << 16 | d4e ;
324360 }
325361 valid2 = depth1 ;
@@ -357,14 +393,14 @@ private boolean phase2(int eidx, int esym, int cidx, int csym, int mid, int maxl
357393 int cidxx = CoordCube .CPermMove [cidx ][CubieCube .SymMove [csym ][Util .ud2std [m ]]];
358394 int csymx = CubieCube .SymMult [cidxx & 15 ][csym ];
359395 cidxx >>>= 4 ;
360- if (CoordCube .getPruning (CoordCube .MCPermPrun ,
396+ if (CoordCube .getPruning (CoordCube .MCPermPrun ,
361397 cidxx * 24 + CoordCube .MPermConj [midx ][csymx ]) >= maxl ) {
362398 continue ;
363399 }
364400 int eidxx = CoordCube .EPermMove [eidx ][CubieCube .SymMoveUD [esym ][m ]];
365401 int esymx = CubieCube .SymMult [eidxx & 15 ][esym ];
366402 eidxx >>>= 4 ;
367- if (CoordCube .getPruning (CoordCube .MEPermPrun ,
403+ if (CoordCube .getPruning (CoordCube .MEPermPrun ,
368404 eidxx * 24 + CoordCube .MPermConj [midx ][esymx ]) >= maxl ) {
369405 continue ;
370406 }
@@ -375,7 +411,7 @@ private boolean phase2(int eidx, int esym, int cidx, int csym, int mid, int maxl
375411 }
376412 return false ;
377413 }
378-
414+
379415 private String solutionToString () {
380416 StringBuffer sb = new StringBuffer ();
381417 int urf = (verbose & INVERSE_SOLUTION ) != 0 ? (urfIdx + 3 ) % 6 : urfIdx ;
0 commit comments