Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Interface to several Rubik's cube solvers.
The first is by Michael Reid, and tries to find an optimal solution given the cube's state, and may take a long time. See http://www.math.ucf.edu/~reid/Rubik/optimal_solver.html
The second is by Eric Dietz, and uses a standard (?) algorithm to solve the cube one level at a time. It is extremely fast, but often returns a far from optimal solution. See http://wrongway.org/?rubiksource
The third is by Dik Winter and implements Kociemba's algorithm which finds reasonable solutions relatively quickly, and if it is kept running will eventually find the optimal solution.
AUTHOR: -- Optimal was written by Michael Reid <reid@math.ucf.edu> (2004) -- Cubex was written by Eric Dietz <root@wrongway.org> (2003) -- Kociemba was written by Dik T. Winter <dik.winter@cwi.nl> (1993) -- Initial interface by Robert Bradshaw (2007-08) """
######################################################################## # Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu> # # Distributed under the terms of the GNU General Public License (GPL) # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ ########################################################################
# Can't seem to find consistency in letter ordering # between us and them... These are copied from the source. "DF", "DR", "DB", "DL", \ "FR", "FL", "BR", "BL", \ "FU", "RU", "BU", "LU", \ "FD", "RD", "BD", "LD", \ "RF", "LF", "RB", "LB", \ "UFR", "URB", "UBL", "ULF", \ "DRF", "DFL", "DLB", "DBR", \ "FRU", "RBU", "BLU", "LFU", \ "RFD", "FLD", "LBD", "BRD", \ "RUF", "BUR", "LUB", "FUL", \ "FDR", "LDF", "BDL", "RDB"]
# The input format.
""" This class is to resolve difference between various Singmaster notation. Case is ignored, and the second and third letters may be swapped.
EXAMPLES::
sage: from sage.interfaces.rubik import SingNot sage: SingNot("acb") == SingNot("ACB") True sage: SingNot("acb") == SingNot("bca") False """ return self.rep return hash(self.canonical)
# This is our list
""" Interface to Michael Reid's optimal Rubik's Cube solver. """
self.verbose = verbose self.start() if wait: print("Initializing tables...") self.ready() print("Done.")
child = pexpect.spawn(self.__cmd) cleaner.cleaner(child.pid, self.__cmd) child.timeout = None self.child = child self._ready = False
if self.child: self.child.sendline(chr(3)) # send ctrl-c self.child.sendline(chr(4)) # send ctrl-d self.child.close(True) self.child = None
if not self._ready: self.child.expect('enter cube') self._ready = True
return self.solve(facets)
""" The initial startup and precomputation are substantial...
TODO: Let it keep searching once it found a solution?
EXAMPLES::
sage: from sage.interfaces.rubik import * sage: solver = DikSolver() sage: solver = OptimalSolver() # long time (28s on sage.math, 2012) Initializing tables... Done. sage: C = RubiksCube("R U") sage: solver.solve(C.facets()) 'R U' sage: C = RubiksCube("R U F L B D") sage: solver.solve(C.facets()) 'R U F L B D' sage: C = RubiksCube("R2 D2") sage: solver.solve(C.facets()) 'R2 D2' """ self.ready() self.child.sendline(self.format_cube(facets)) self.child.expect(r"([LRUDBF'2 ]+)\s+\((\d+)q\*?, (\d+)f\*?\)") self.child.sendline(chr(3)) # send ctrl-c return self.child.match.groups()[0].strip()
L = [] optimal_solver_list = [SingNot(x) for x in optimal_solver_tokens] for f in optimal_solver_format.split(" "): ix = facets[singmaster_list.index(SingNot(f))-1] facet = singmaster_list[ix] L.append(optimal_solver_list[optimal_solver_list.index(facet)]) return " ".join([str(f) for f in L])
"LD":"L'", "LU":"L", "RD":"R", "RU":"R'", "FA":"F", "FC":"F'", "BA":"B'", "BC":"B", "UR":"U", "UL":"U'", "DR":"D'", "DL":"D" }
return self.solve(facets)
""" EXAMPLES::
sage: from sage.interfaces.rubik import * sage: C = RubiksCube("R U") sage: CubexSolver().solve(C.facets()) 'R U' sage: C = RubiksCube("R U F L B D") sage: sol = CubexSolver().solve(C.facets()); sol "U' L' L' U L U' L U D L L D' L' D L' D' L D L' U' L D' L' U L' B' U' L' U B L D L D' U' L' U L B L B' L' U L U' L' F' L' F L' F L F' L' D' L' D D L D' B L B' L B' L B F' L F F B' L F' B D' D' L D B' B' L' D' B U' U' L' B' D' F' F' L D F'" sage: RubiksCube(sol) == C True sage: C = RubiksCube("R2 F'") sage: CubexSolver().solve(C.facets()) "R' R' F'" sage: C = RubiksCube().scramble() sage: sol = CubexSolver().solve(C.facets()) sage: C == RubiksCube(sol) True """ else: s = child.after while child.expect(['^5\d+', pexpect.EOF]) == 0: s += child.after raise ValueError(bytes_to_str(s))
return self.solve(facets)
""" EXAMPLES::
sage: from sage.interfaces.rubik import * sage: C = RubiksCube().move("R U") sage: DikSolver().solve(C.facets()) 'R U' sage: C = RubiksCube().move("R U F L B D") sage: DikSolver().solve(C.facets()) 'R U F L B D' sage: C = RubiksCube().move("R2 F'") sage: DikSolver().solve(C.facets()) "R2 F'" """
# We use send(chr(4)) instead of sendeof in this case, since # child.sendoef() when run in the background with the Dik solver # sends a SIGTTOU which suspends the process -- this is very bad. # This is only a temporary workaround, and does not fix the problem # on OS X. The Dik C program itself will need to be fixed. # See trac #1683. (TODO) -- willem jp, wstein, mabshoff #child.sendeof()
else: # format the string into our notation elif ix == 1: # invalid format child.close(True) raise ValueError(bytes_to_str(child.before)) else: child.close(True) raise RuntimeError("timeout")
# now do the centers
4, 0, 5, \ 6, 7, 8, \ 9, 10, 11, 17, 18, 19, 25, 26, 27, 33, 34, 35, \ 12, 0, 13, 20, 0, 21, 28, 0, 29, 36, 0, 37, \ 14, 15, 16, 22, 23, 24, 30, 31, 32, 38, 39, 40, \ 41, 42, 43, \ 44, 0, 45, \ 46, 47, 48, \ ]
# to compensate for different face naming
# facet_map = [ # 1, 2, 3, # 4, 6, # 7, 8, 9, # 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, # 23, 25, 26, 28, 29, 30, 31, 33, # 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, # 46, 47, 48, # 49, 51, # 52, 53, 54, # ]
|