Advertisement
campos20

Long solution for Rubik's Cube

Sep 7th, 2018
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.90 KB | None | 0 0
  1. import copy
  2.  
  3. class Rubik:
  4.     """The cube."""
  5.  
  6.     def __init__(self):
  7.    
  8.         self.reset()
  9.    
  10.     def reset(self, cube = None):
  11.         """Resets cube to solved one or given status."""
  12.  
  13.         if cube:
  14.             self.cube = copy.deepcopy(cube) # independent copy of the given list. Helpful in bruteforce.
  15.  
  16.         else:
  17.             self.cube = [   [["W", "W", "W"], ["W", "W", "W"], ["W", "W", "W"]], # six faces, in each face a 3x3 matrix.
  18.                             [["O", "O", "O"], ["O", "O", "O"], ["O", "O", "O"]],
  19.                             [["G", "G", "G"], ["G", "G", "G"], ["G", "G", "G"]],
  20.                             [["R", "R", "R"], ["R", "R", "R"], ["R", "R", "R"]],
  21.                             [["B", "B", "B"], ["B", "B", "B"], ["B", "B", "B"]],
  22.                             [["Y", "Y", "Y"], ["Y", "Y", "Y"], ["Y", "Y", "Y"]] ]
  23.  
  24.     def move_perm(self, perm, d=1):
  25.         """Moves the cube given a permutation of pieces."""
  26.  
  27.         temp = []
  28.         for x in perm:
  29.             temp2 = []
  30.             for y in x: temp2.append( self.cube[y[0]][y[1]][y[2]] )
  31.             temp.append(temp2)
  32.  
  33.         for i in xrange(len(perm)):
  34.             for j in xrange(len(perm[i])):
  35.                 self.cube[perm[i][j][0]][perm[i][j][1]][perm[i][j][2]] = temp[i][j-d]
  36.    
  37.     def move_sequence(self, seq):
  38.         self.move_perm(seq.split())
  39.  
  40.     def move(self, face):
  41.         """Moves a face of the cube."""
  42.  
  43.         d = 1
  44.         if face[-1] == "'": d = 3
  45.         elif face[-1] == "2": d = 2
  46.    
  47.         if face[0] == "U": self.move_perm(U_move, d)
  48.         elif face[0] == "L": self.move_perm(L_move, d)
  49.         elif face[0] == "F": self.move_perm(F_move, d)
  50.         elif face[0] == "R": self.move_perm(R_move, d)
  51.         elif face[0] == "B": self.move_perm(B_move, d)
  52.         elif face[0] == "D": self.move_perm(D_move, d)
  53.  
  54.     def move_sequence(self, sequence):
  55.         """Performs moves given a sequence of turns. Like scramble."""
  56.  
  57.         for turn in sequence.split(): self.move(turn)
  58.        
  59.     def show(self):
  60.         for x in self.cube:
  61.             for y in x: print y
  62.             print
  63.    
  64.     def is_solved(self):
  65.         for i in range(6):
  66.             for j in range(3):
  67.                 for k in range(3):
  68.                     if self.cube[i][j][k] != self.cube[i][2][2]:
  69.                         return False
  70.         return True
  71.  
  72. # permutations OK
  73. U_move = [ [ [1, 0, 0], [4, 0, 0], [3, 0, 0], [2, 0, 0] ], [ [1, 0, 1], [4, 0, 1], [3, 0, 1], [2, 0, 1] ], [ [1, 0, 2], [4, 0, 2], [3, 0, 2], [2, 0, 2] ], [[0, 0, 0], [0, 0, 2], [0, 2, 2], [0, 2, 0]], [[0, 0, 1], [0, 1, 2], [0, 2, 1], [0, 1, 0]] ]
  74. L_move = [ [ [0, 0, 0], [2, 0, 0], [5, 0, 0], [4, 2, 2] ], [ [0, 1, 0], [2, 1, 0], [5, 1, 0], [4, 1, 2] ], [ [0, 2, 0], [2, 2, 0], [5, 2, 0], [4, 0, 2] ], [[1, 0, 0], [1, 0, 2], [1, 2, 2], [1, 2, 0]], [[1, 0, 1], [1, 1, 2], [1, 2, 1], [1, 1, 0]] ]
  75. F_move = [ [ [0, 2, 0], [3, 0, 0], [5, 0, 2], [1, 2, 2] ], [ [0, 2, 1], [3, 1, 0], [5, 0, 1], [1, 1, 2] ], [ [0, 2, 2], [3, 2, 0], [5, 0, 0], [1, 0, 2] ], [[2, 0, 0], [2, 0, 2], [2, 2, 2], [2, 2, 0]], [[2, 0, 1], [2, 1, 2], [2, 2, 1], [2, 1, 0]] ]
  76. R_move = [ [ [0, 2, 2], [4, 0, 0], [5, 2, 2], [2, 2, 2] ], [ [0, 1, 2], [4, 1, 0], [5, 1, 2], [2, 1, 2] ], [ [0, 0, 2], [4, 2, 0], [5, 0, 2], [2, 0, 2] ], [[3, 0, 0], [3, 0, 2], [3, 2, 2], [3, 2, 0]], [[3, 0, 1], [3, 1, 2], [3, 2, 1], [3, 1, 0]] ]
  77. B_move = [ [ [0, 0, 2], [1, 0, 0], [5, 2, 0], [3, 2, 2] ], [ [0, 0, 1], [1, 1, 0], [5, 2, 1], [3, 1, 2] ], [ [0, 0, 0], [1, 2, 0], [5, 2, 2], [3, 0, 2] ], [[4, 0, 0], [4, 0, 2], [4, 2, 2], [4, 2, 0]], [[4, 0, 1], [4, 1, 2], [4, 2, 1], [4, 1, 0]] ]
  78. D_move = [ [ [2, 2, 0], [3, 2, 0], [4, 2, 0], [1, 2, 0] ], [ [2, 2, 1], [3, 2, 1], [4, 2, 1], [1, 2, 1] ], [ [2, 2, 2], [3, 2, 2], [4, 2, 2], [1, 2, 2] ], [[5, 0, 0], [5, 0, 2], [5, 2, 2], [5, 2, 0]], [[5, 0, 1], [5, 1, 2], [5, 2, 1], [5, 1, 0]] ]
  79.  
  80. def invert_move(face):
  81.  
  82.     if face[-1] == "2": return face
  83.     if face[-1] == "'": return face[0]
  84.     return face+"'"
  85.  
  86. def invert_sequence(sequence):
  87.  
  88.     out = []
  89.     for x in sequence.split()[::-1]:
  90.         out.append(invert_move(x))
  91.     return " ".join(out)
  92.  
  93. def setup_corners(letter):
  94.  
  95.     out = []
  96.     if letter == "B": out += ["R", "D'"]
  97.     elif letter == "C": out += ["F", "R'"]
  98.     elif letter == "D": out += ["F"]
  99.     elif letter == "E": out += ["F'"]
  100.     elif letter == "F": out += ["R'", "D'"]
  101.     elif letter == "G": out += ["D", "F'"]
  102.     elif letter == "H": out += ["R2", "F"]
  103. #   elif letter == "I": out += []
  104.     elif letter == "J": out += ["F2"]
  105.     elif letter == "K": out += ["D2"]
  106.     elif letter == "L": out += ["F2", "R'"]
  107.     elif letter == "M": out += ["F'", "D"]
  108.     elif letter == "N": out += ["F2", "D"]
  109.     elif letter == "O": out += ["D"]
  110.     elif letter == "P": out += ["R", "F"]
  111.     elif letter == "Q": out += ["R'"]
  112.     elif letter == "R": out += ["R2"]
  113. #   elif letter == "S": out += []
  114.     elif letter == "T": out += ["R"]
  115.     elif letter == "U": out += ["R'", "F"]
  116. #   elif letter == "V": out += []
  117.     elif letter == "W": out += ["D'"]
  118.     elif letter == "X": out += ["D'", "R"]
  119.    
  120.     return out
  121.  
  122. def setup_edges(letter):
  123.    
  124.     out = []
  125.     if letter == "A": out += ["R2", "U'", "R2"]
  126. #   elif letter == "B": out += []
  127.     elif letter == "D": out += ["R2", "U", "R2"]
  128.     elif letter == "E": out += ["D'", "L2"]
  129.     elif letter == "F": out += ["L2"]
  130.     elif letter == "G": out += ["D2", "L2"]
  131.     elif letter == "H": out += ["D", "L2"]
  132.     elif letter == "I": out += ["L", "R", "F", "R", "U", "R2"]
  133.     elif letter == "J": out += ["R'", "B'", "R'", "U'", "R2"]
  134.     elif letter == "K": out += ["R", "F", "R", "U", "R2"]
  135.     elif letter == "L": out += ["D", "R", "F", "R'", "L'"]
  136.     elif letter == "M": out += ["R", "F'", "L'", "R'"]
  137.     elif letter == "N": out += ["L'"]
  138.     elif letter == "O": out += ["U2", "R", "U2"]
  139.     elif letter == "P": out += ["R", "F", "L'", "R'"]
  140. #   elif letter == "Q": out += []
  141.     elif letter == "R": out += ["U'", "F'", "U"]
  142.     elif letter == "S": out += ["U", "B", "U'"]
  143.     elif letter == "T": out += ["R", "F'", "R", "U", "R2"]
  144.     elif letter == "U": out += ["R'", "B", "L", "R"]
  145.     elif letter == "V": out += ["U2", "R'", "U2"]
  146.     elif letter == "W": out += ["L"]
  147.     elif letter == "X": out += ["R'", "B'", "L", "R"]
  148.    
  149.     return out
  150.  
  151. def next_edge(cube):
  152.  
  153.     letters = "ABCDIJKLMNOPQRSTUVWXEFGH"
  154.  
  155.     for i in xrange(6):
  156.         face_color = cube.cube[i][1][1]
  157.  
  158.         if cube.cube[i][0][1] != face_color:
  159.             if i != 3:
  160.                 return letters[4*i]
  161.         if cube.cube[i][1][0] != face_color:
  162.             return letters[4*i+1]
  163.         if cube.cube[i][1][2] != face_color:
  164.             if i != 0:
  165.                 return letters[4*i+2]
  166.         if cube.cube[i][2][1] != face_color:
  167.             return letters[4*i+3]
  168.    
  169.     return ""
  170.  
  171. def edge(cube):
  172.     """Current edge to throw."""
  173.  
  174.     c1 = cube.cube[0][1][2] # color1
  175.     c2 = cube.cube[3][0][1] # color2
  176.    
  177.     if c1 == "W":
  178.         if c2 == "B": return "A"
  179.         if c2 == "O": return "B"
  180.         if c2 == "R": return next_edge(cube)
  181.         if c2 == "G": return "D"
  182.     if c1 == "Y":
  183.         if c2 == "G": return "E"
  184.         if c2 == "O": return "F"
  185.         if c2 == "R": return "G"
  186.         if c2 == "B": return "H"
  187.     if c1 == "O":
  188.         if c2 == "W": return "I"
  189.         if c2 == "B": return "J"
  190.         if c2 == "G": return "K"
  191.         if c2 == "Y": return "L"
  192.     if c1 == "G":
  193.         if c2 == "W": return "M"
  194.         if c2 == "O": return "N"
  195.         if c2 == "R": return "O"
  196.         if c2 == "Y": return "P"
  197.     if c1 == "R":
  198.         if c2 == "W": return next_edge(cube)
  199.         if c2 == "G": return "R"
  200.         if c2 == "B": return "S"
  201.         if c2 == "Y": return "T"
  202.     if c1 == "B":
  203.         if c2 == "W": return "U"
  204.         if c2 == "R": return "V"
  205.         if c2 == "O": return "W"
  206.         if c2 == "Y": return "X"
  207.     else: return ""
  208.  
  209. def next_corner(cube):
  210.     letters = "ABCDIJKLMNOPQRSTUVWXEFGH"
  211.  
  212.     for i in xrange(6):
  213.         face_color = cube.cube[i][1][1]
  214.  
  215.         if cube.cube[i][0][0] != face_color:
  216.             if i != 0 and i != 1:
  217.                 return letters[4*i]
  218.         if cube.cube[i][0][2] != face_color:
  219.             if i!=4:
  220.                 return letters[4*i+1]
  221.         if cube.cube[i][2][0] != face_color:
  222.             return letters[4*i+2]
  223.         if cube.cube[i][2][2] != face_color:
  224.             return letters[4*i+3]
  225.    
  226.     return ""
  227.  
  228. def corner(cube):
  229.  
  230.     c1 = cube.cube[0][0][0]
  231.     c2 = cube.cube[1][0][0]
  232.     c3 = cube.cube[4][0][2]
  233.    
  234.     if c1 == "W":
  235.         if c2 == "O" and c3 == "B": return next_corner(cube)
  236.         if c2 == "B" and c3 == "R": return "B"
  237.         if c2 == "G" and c3 == "O": return "C"
  238.         if c2 == "R" and c3 == "G": return "D"
  239.     if c1 == "Y":
  240.         if c2 == "O" and c3 == "G": return "E"
  241.         if c2 == "G" and c3 == "R": return "F"
  242.         if c2 == "B" and c3 == "O": return "G"
  243.         if c2 == "R" and c3 == "B": return "H"
  244.     if c1 == "O":
  245.         if c2 == "B" and c3 == "W": return next_corner(cube)
  246.         if c2 == "W" and c3 == "G": return "J"
  247.         if c2 == "Y" and c3 == "B": return "K"
  248.         if c2 == "G" and c3 == "Y": return "L"
  249.     if c1 == "G":
  250.         if c2 == "O" and c3 == "W": return "M"
  251.         if c2 == "W" and c3 == "R": return "N"
  252.         if c2 == "Y" and c3 == "O": return "O"
  253.         if c2 == "R" and c3 == "Y": return "P"
  254.     if c1 == "R":
  255.         if c2 == "G" and c3 == "W": return "Q"
  256.         if c2 == "W" and c3 == "B": return "R"
  257.         if c2 == "Y" and c3 == "G": return "S"
  258.         if c2 == "B" and c3 == "Y": return "T"
  259.     if c1 == "B":
  260.         if c2 == "R" and c3 == "W": return "U"
  261.         if c2 == "W" and c3 == "O": return next_corner(cube)
  262.         if c2 == "Y" and c3 == "R": return "W"
  263.         if c2 == "O" and c3 == "Y": return "X"
  264.    
  265.     return ""
  266.    
  267.  
  268. def old_pochmann(cube): # very bad list deal. split and join. need standard
  269.  
  270.     y_perm = "R U' R' U' R U R' F' R U R' U' R' F R" # corners
  271.     t_perm = "R U R' U' R' F R2 U' R' U' R U R' F'" # edges
  272.    
  273.     solution = []
  274.    
  275.     while next_edge(cube) != "": # fix edges
  276.  
  277.         setup = " ".join(setup_edges(edge(cube)))
  278.  
  279.         temp = []
  280.         temp += setup.split()
  281.         temp += t_perm.split()
  282.         temp += invert_sequence(setup).split()
  283.        
  284.         cube.move_sequence(" ".join(temp))
  285.         solution += temp
  286.  
  287.     while next_corner(cube) != "": # fix corner
  288.  
  289.         setup = " ".join(setup_corners(corner(cube)))
  290.  
  291.         temp = []
  292.         temp += setup.split()
  293.         temp += y_perm.split()
  294.         temp += invert_sequence(setup).split()
  295.        
  296.         cube.move_sequence(" ".join(temp))
  297.         solution += temp
  298.  
  299.     return solution
  300.  
  301. def program():
  302.     sequence = "D' L2 B2 D F2 U2 F2 U R2 F2 R2 L' U' B D U2 R D2 F U'"
  303.     cube = Rubik()
  304.     cube.move_sequence(sequence)
  305.     solution = " ".join(old_pochmann(cube))
  306.     inverse = invert_sequence(solution)
  307.    
  308.     cube.reset()
  309.     cube.move_sequence(inverse)
  310.    
  311.     count = 0
  312.     while not cube.is_solved():
  313.         cube.move_sequence(inverse)
  314.         count += 1
  315.    
  316.     solution = inverse.split()*count
  317.    
  318.     print " ".join(solution)
  319.     print len(solution)
  320.  
  321. program()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement