public static void InitRaw2Sym() { Edge3 e = new Edge3(); sbyte[] occ = new sbyte[11880 / 8]; int count = 0; for (int i = 0; i < 11880; i++) { if ((occ[(uint)i >> 3] & (1 << (i & 7))) == 0) { e.Set(i * factX[8]); for (int j = 0; j < 8; j++) { int idx = e.Get(4); if (idx == i) { symstate[count] |= (char)(1 << j); } occ[idx >> 3] |= (sbyte)(1 << (idx & 7)); Raw2sym[idx] = count << 3 | syminv[j]; e.Rot(0); if (j % 2 == 1) { e.Rot(1); e.Rot(2); } } sym2raw[count++] = i; } } }
public static int Getprun(int edge) { Edge3 e = new Edge3(); int depth = 0; int depm3 = GetPruning(eprun, edge); if (depm3 == 0x3) { return(MAX_DEPTH); } while (edge != 0) { if (depm3 == 0) { depm3 = 2; } else { depm3--; } int symcord1 = edge / N_RAW; int cord1 = sym2raw[symcord1]; int cord2 = edge % N_RAW; e.Set(cord1 * N_RAW + cord2); for (int m = 0; m < 17; m++) { int cord1x = Getmvrot(e.Edge, m << 3, 4); int symcord1x = Raw2sym[cord1x]; int symx = symcord1x & 0x7; symcord1x >>= 3; int cord2x = Getmvrot(e.Edge, m << 3 | symx, 10) % N_RAW; int idx = symcord1x * N_RAW + cord2x; if (GetPruning(eprun, idx) == depm3) { depth++; edge = idx; break; } } } return(depth); }
public static void InitMvrot() { Edge3 e = new Edge3(); for (int m = 0; m < 20; m++) { for (int r = 0; r < 8; r++) { e.Set(0); e.Move(m); e.Rotate(r); for (int i = 0; i < 12; i++) { mvrot[m << 3 | r][i] = e.Edge[i]; } e.Std(); for (int i = 0; i < 12; i++) { mvroto[m << 3 | r][i] = e.temp[i]; } } } }
private void DoSearch() { Init(); solution = ""; int ud = new Center1(cubeToSolve.GetCenter(), 0).Getsym(); int fb = new Center1(cubeToSolve.GetCenter(), 1).Getsym(); int rl = new Center1(cubeToSolve.GetCenter(), 2).Getsym(); int udprun = Center1.Csprun[ud >> 6]; int fbprun = Center1.Csprun[fb >> 6]; int rlprun = Center1.Csprun[rl >> 6]; p1SolsCnt = 0; arr2idx = 0; p1sols.Clear(); for (length1 = Math.Min(Math.Min(udprun, fbprun), rlprun); length1 < 100; length1++) { if (rlprun <= length1 && Search1((int)((uint)rl >> 6), rl & 0x3f, length1, -1, 0) || udprun <= length1 && Search1((int)((uint)ud >> 6), ud & 0x3f, length1, -1, 0) || fbprun <= length1 && Search1((int)((uint)fb >> 6), fb & 0x3f, length1, -1, 0)) { break; } } //FullCube[] p1SolsArr = p1sols.ToArray(new FullCube[0]); FullCube[] p1SolsArr = new FullCube[p1sols.Count]; p1sols.CopyTo(p1SolsArr, 0); Array.Sort(p1SolsArr, 0, p1SolsArr.Length); int MAX_LENGTH2 = 9; int length12; do { for (length12 = p1SolsArr[0].Value; length12 < 100; length12++) { for (int i = 0; i < p1SolsArr.Length; i++) { if (p1SolsArr[i].Value > length12) { break; } if (length12 - p1SolsArr[i].Length1 > MAX_LENGTH2) { continue; } c1.Copy(p1SolsArr[i]); ct2.Set(c1.GetCenter(), c1.GetEdge().GetParity()); int s2ct = ct2.Getct(); int s2rl = ct2.Getrl(); length1 = p1SolsArr[i].Length1; length2 = length12 - p1SolsArr[i].Length1; if (Search2(s2ct, s2rl, length2, 28, 0)) { goto OUT; } } } OUT: MAX_LENGTH2++; } while (length12 == 100); Array.Sort(arr2, 0, arr2idx); int length123, index = 0; int solcnt = 0; int MAX_LENGTH3 = 13; do { for (length123 = arr2[0].Value; length123 < 100; length123++) { for (int i = 0; i < Math.Min(arr2idx, PHASE3_ATTEMPTS); i++) { if (arr2[i].Value > length123) { break; } if (length123 - arr2[i].Length1 - arr2[i].Length2 > MAX_LENGTH3) { continue; } int eparity = e12.Set(arr2[i].GetEdge()); ct3.Set(arr2[i].GetCenter(), eparity ^ arr2[i].GetCorner().GetParity()); int ct = ct3.Getct(); int edge = e12.Get(10); int prun = Edge3.Getprun(e12.Getsym()); int lm = 20; if (prun <= length123 - arr2[i].Length1 - arr2[i].Length2 && Search3(edge, ct, prun, length123 - arr2[i].Length1 - arr2[i].Length2, lm, 0)) { solcnt++; index = i; goto OUT2; } } } OUT2: MAX_LENGTH3++; } while (length123 == 100); FullCube solcube = new FullCube(arr2[index]); length1 = solcube.Length1; length2 = solcube.Length2; int length = length123 - length1 - length2; for (int i = 0; i < length; i++) { solcube.Move(Move3std[move3[i]]); } string facelet = solcube.To333Facelet(); string sol = search333.Solution(facelet, 20, 100, 50, 0); if (sol.StartsWith("Error 8")) { sol = search333.Solution(facelet, 21, 1000000, 30, 0); } int len333 = sol.Length / 3; if (sol.StartsWith("Error")) { throw new Exception(); } int[] sol333 = Util.Tomove(sol); for (int i = 0; i < sol333.Length; i++) { solcube.Move(sol333[i]); } StringBuilder str = new StringBuilder(); str.Append(solcube.GetMoveString(InverseSolution, WithRotation)); solution = str.ToString(); totlen = length1 + length2 + length + len333; }
public static void CreatePrun() { Edge3 e = new Edge3(); Edge3 f = new Edge3(); Edge3 g = new Edge3(); ArrayExtension.Fill(eprun, -1); int depth = 0; done = 1; SetPruning(eprun, 0, 0); while (done != N_EPRUN) { bool inv = depth > 9; int depm3 = depth % 3; int dep1m3 = (depth + 1) % 3; int find = inv ? 0x3 : depm3; int chk = inv ? depm3 : 0x3; if (depth >= MAX_DEPTH - 1) { break; } for (int i_ = 0; i_ < N_EPRUN; i_ += 16) { int val = eprun[i_ >> 4]; if (!inv && val == -1) { continue; } for (int i = i_, end = i_ + 16; i < end; i++, val >>= 2) { if ((val & 0x3) != find) { continue; } int symcord1 = i / N_RAW; int cord1 = sym2raw[symcord1]; int cord2 = i % N_RAW; e.Set(cord1 * N_RAW + cord2); for (int m = 0; m < 17; m++) { int cord1x = Getmvrot(e.Edge, m << 3, 4); int symcord1x = Raw2sym[cord1x]; int symx = symcord1x & 0x7; symcord1x >>= 3; int cord2x = Getmvrot(e.Edge, m << 3 | symx, 10) % N_RAW; int idx = symcord1x * N_RAW + cord2x; if (GetPruning(eprun, idx) != chk) { continue; } SetPruning(eprun, inv ? i : idx, dep1m3); done++; if (inv) { break; } char symState = symstate[symcord1x]; if (symState == 1) { continue; } f.Set(e); f.Move(m); f.Rotate(symx); for (int j = 1; (symState >>= 1) != 0; j++) { if ((symState & 1) != 1) { continue; } g.Set(f); g.Rotate(j); int idxx = symcord1x * N_RAW + g.Get(10) % N_RAW; if (GetPruning(eprun, idxx) == chk) { SetPruning(eprun, idxx, dep1m3); done++; } } } } } depth++; } }