private String solve() { calcadj(); JavascriptArray<Integer> opp = new JavascriptArray<Integer>(); for (int a = 0; a < 6; a++) { for (int b = 0; b < 6; b++) { if (a != b && adj.get(a).get(b) + adj.get(b).get(a) == 0) { opp.set(a, b); opp.set(b, a); } } } // Each piece is determined by which of each pair of opposite colours it uses. JavascriptArray<Integer> ps = new JavascriptArray<Integer>(); JavascriptArray<Integer> tws = new JavascriptArray<Integer>(); int a = 0; for (int d = 0; d < 7; d++) { int p = 0; for (int b = a; b < a + 6; b += 2) { if (posit.get(piece.get(b)) == posit.get(piece.get(42))) p += 4; if (posit.get(piece.get(b)) == posit.get(piece.get(44))) p += 1; if (posit.get(piece.get(b)) == posit.get(piece.get(46))) p += 2; } ps.set(d, p); if (posit.get(piece.get(a)) == posit.get(piece.get(42)) || posit.get(piece.get(a)) == opp.get(posit.get(piece.get(42)))) tws.set(d, 0); else if (posit.get(piece.get(a + 2)) == posit.get(piece.get(42)) || posit.get(piece.get(a + 2)) == opp.get(posit.get(piece.get(42)))) tws.set(d, 1); else tws.set(d, 2); a += 6; } // convert position to numbers int q = 0; for (a = 0; a < 7; a++) { int b = 0; for (int c = 0; c < 7; c++) { if (ps.get(c) == a) break; if (ps.get(c) > a) b++; } q = q * (7 - a) + b; } int t = 0; for (a = 5; a >= 0; a--) { t = (int) (t * 3 + tws.get(a) - 3 * Math.floor(tws.get(a) / 3)); } if (q != 0 || t != 0) { sol.clear(); for (int l = seq.size(); l < 100; l++) { if (search(0, q, t, l, -1)) break; } String tt = ""; for (q = 0; q < sol.size(); q++) { tt = "URF".charAt(sol.get(q) / 10) + "" + "\'2 ".charAt(sol.get(q) % 10) + " " + tt; } return tt; } return null; }
private void domove(int y) { int q = 1 + (y >> 4); int f = y & 15; while (q > 0) { for (int i = 0; i < mov2fc.get(f).size(); i += 4) { int c = posit.get(mov2fc.get(f).get(i)); posit.set(mov2fc.get(f).get(i), posit.get(mov2fc.get(f).get(i + 3))); posit.set(mov2fc.get(f).get(i + 3), posit.get(mov2fc.get(f).get(i + 2))); posit.set(mov2fc.get(f).get(i + 2), posit.get(mov2fc.get(f).get(i + 1))); posit.set(mov2fc.get(f).get(i + 1), c); } q--; } }
private boolean search(int d, int q, int t, int l, int lm) { // searches for solution, from position q|t, in l moves exactly. last move was lm, current // depth=d if (l == 0) { if (q == 0 && t == 0) { return true; } } else { if (perm.get(q) > l || twst.get(t) > l) return false; int p, s, a, m; for (m = 0; m < 3; m++) { if (m != lm) { p = q; s = t; for (a = 0; a < 3; a++) { p = permmv.get(p).get(m); s = twstmv.get(s).get(m); sol.set(d, 10 * m + a); if (search(d + 1, p, s, l - 1, m)) { return true; } } } } } return false; }
private void mix() { // Modified to choose a random state, rather than apply 500 random turns // -Jeremy Fleischman ArrayList<Integer> remaining = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4, 5, 6)); ArrayList<Integer> cp = new ArrayList<Integer>(); while (remaining.size() > 0) cp.add(remaining.remove((int) Math.floor(Math.random() * remaining.size()))); // it would appear that the solver only works if the BLD piece is fixed, which is fine cp.add(7); initbrd(); ArrayList<Integer> co = new ArrayList<Integer>(); int sum = 0; for (int i = 0; i < cp.size(); i++) { int orientation; if (i == cp.size() - 1) orientation = 0; else if (i == cp.size() - 2) orientation = (3 - sum) % 3; else orientation = (int) Math.floor(Math.random() * 3); co.add(orientation); sum = (sum + orientation) % 3; for (int j = 0; j < 3; j++) { int jj = (j + orientation) % 3; posit.set(cornerIndices[i][j], faceToIndex.get(cornerNames[cp.get(i)].charAt(jj))); } } }
private void calcadj() { // count all adjacent pairs (clockwise around corners) int a, b; for (a = 0; a < 6; a++) for (b = 0; b < 6; b++) adj.get(a).set(b, 0); for (a = 0; a < 48; a += 2) { if (posit.get(piece.get(a)) <= 5 && posit.get(piece.get(a + 1)) <= 5) { JavascriptArray<Integer> temp = adj.get(posit.get(piece.get(a))); int index = posit.get(piece.get(a + 1)); temp.set(index, temp.get(index) + 1); } } }
private void calcperm() { // calculate solving arrays // first permutation for (int p = 0; p < 5040; p++) { perm.set(p, -1); permmv.set(p, new JavascriptArray<Integer>()); for (int m = 0; m < 3; m++) { permmv.get(p).set(m, getprmmv(p, m)); } } perm.set(0, 0); for (int l = 0; l <= 6; l++) { int n = 0; for (int p = 0; p < 5040; p++) { if (perm.get(p) == l) { for (int m = 0; m < 3; m++) { int q = p; for (int c = 0; c < 3; c++) { q = permmv.get(q).get(m); if (perm.get(q) == -1) { perm.set(q, l + 1); n++; } } } } } } // then twist for (int p = 0; p < 729; p++) { twst.set(p, -1); twstmv.set(p, new JavascriptArray<Integer>()); for (int m = 0; m < 3; m++) { twstmv.get(p).set(m, gettwsmv(p, m)); } } twst.set(0, 0); for (int l = 0; l <= 5; l++) { int n = 0; for (int p = 0; p < 729; p++) { if (twst.get(p) == l) { for (int m = 0; m < 3; m++) { int q = p; for (int c = 0; c < 3; c++) { q = twstmv.get(q).get(m); if (twst.get(q) == -1) { twst.set(q, l + 1); n++; } } } } } } // remove wait sign }
private int gettwsmv(int p, int m) { // given orientation p<729 and move m<3, return new orientation number int a, b, c, d, q; // convert number into array; JavascriptArray<Integer> ps = new JavascriptArray<Integer>(); q = p; d = 0; for (a = 0; a <= 5; a++) { c = (int) Math.floor(q / 3); b = q - 3 * c; q = c; ps.set(a, b); d -= b; if (d < 0) d += 3; } ps.set(6, d); // perform move on array if (m == 0) { // U c = ps.get(0); ps.set(0, ps.get(1)); ps.set(1, ps.get(3)); ps.set(3, ps.get(2)); ps.set(2, c); } else if (m == 1) { // R c = ps.get(0); ps.set(0, ps.get(4)); ps.set(4, ps.get(5)); ps.set(5, ps.get(1)); ps.set(1, c); ps.set(0, ps.get(0) + 2); ps.set(1, ps.get(1) + 1); ps.set(5, ps.get(5) + 2); ps.set(4, ps.get(4) + 1); } else if (m == 2) { // F c = ps.get(0); ps.set(0, ps.get(2)); ps.set(2, ps.get(6)); ps.set(6, ps.get(4)); ps.set(4, c); ps.set(2, ps.get(2) + 2); ps.set(0, ps.get(0) + 1); ps.set(4, ps.get(4) + 2); ps.set(6, ps.get(6) + 1); } // convert array back to number q = 0; for (a = 5; a >= 0; a--) { q = q * 3 + (ps.get(a) % 3); } return q; }
private int getprmmv(int p, int m) { // given position p<5040 and move m<3, return new position number int a, b, c, q; // convert number into array; JavascriptArray<Integer> ps = new JavascriptArray<Integer>(); q = p; for (a = 1; a <= 7; a++) { b = q % a; q = (q - b) / a; for (c = a - 1; c >= b; c--) { Integer ii = null; try { ii = ps.get(c); } catch (Exception e) { } ps.set(c + 1, ii); } ps.set(b, 7 - a); } // perform move on array if (m == 0) { // U c = ps.get(0); ps.set(0, ps.get(1)); ps.set(1, ps.get(3)); ps.set(3, ps.get(2)); ps.set(2, c); } else if (m == 1) { // R c = ps.get(0); ps.set(0, ps.get(4)); ps.set(4, ps.get(5)); ps.set(5, ps.get(1)); ps.set(1, c); } else if (m == 2) { // F c = ps.get(0); ps.set(0, ps.get(2)); ps.set(2, ps.get(6)); ps.set(6, ps.get(4)); ps.set(4, c); } // convert array back to number q = 0; for (a = 0; a < 7; a++) { b = 0; for (c = 0; c < 7; c++) { if (ps.get(c) == a) break; if (ps.get(c) > a) b++; } q = q * (7 - a) + b; } return q; }
private void calctot() { // count how many of each colour tot = new JavascriptArray<Integer>(0, 0, 0, 0, 0, 0, 0); for (int e = 0; e < 24; e++) tot.set(posit.get(e), tot.get(posit.get(e)) + 1); }