Guest User

Untitled

a guest
Sep 22nd, 2016
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.91 KB | None | 0 0
  1. import copy
  2.  
  3. # permutations
  4. 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]] ]
  5. 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]] ]
  6. 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]] ]
  7. 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]] ]
  8. 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]] ]
  9. 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]] ]
  10.  
  11. # 0 U
  12. # 1 2 3 4 L F R B
  13. # 5 D
  14.  
  15. moves = ["U", "U2", "U'", "L", "L'", "L2", "F", "F'", "F2", "R", "R'", "R2", "B", "B'", "B2", "D", "D'", "D2"]
  16.  
  17. class Rubik:
  18. """The cube."""
  19.  
  20. def __init__(self):
  21.  
  22. self.reset()
  23. self.save() # previous is a independent copy of the cube. This is helpful in bruteforce.
  24.  
  25. def reset(self, cube = None):
  26. """Resets cube to solved one or given status."""
  27.  
  28. if cube:
  29. self.cube = copy.deepcopy(cube) # independent copy of the given list. Helpful in bruteforce.
  30.  
  31. else:
  32. self.cube = [ [["W", "W", "W"], ["W", "W", "W"], ["W", "W", "W"]], # six faces, in each face a 3x3 matrix.
  33. [["O", "O", "O"], ["O", "O", "O"], ["O", "O", "O"]],
  34. [["G", "G", "G"], ["G", "G", "G"], ["G", "G", "G"]],
  35. [["R", "R", "R"], ["R", "R", "R"], ["R", "R", "R"]],
  36. [["B", "B", "B"], ["B", "B", "B"], ["B", "B", "B"]],
  37. [["Y", "Y", "Y"], ["Y", "Y", "Y"], ["Y", "Y", "Y"]] ]
  38.  
  39. def move_perm(self, perm, d=1):
  40. """Moves the cube given a permutation of pieces."""
  41.  
  42. for x in perm:
  43. temp = []
  44. for y in x: temp.append( self.cube[y[0]][y[1]][y[2]] )
  45. for j in xrange(len(x)): self.cube[x[j][0]][x[j][1]][x[j][2]] = temp[j-d]
  46.  
  47. def move(self, face):
  48. """Moves a face of the cube."""
  49.  
  50. d = 1
  51. if face[-1] == "'": d = 3
  52. elif face[-1] == "2": d = 2
  53.  
  54. if face[0] == "U": self.move_perm(U_move, d)
  55. elif face[0] == "L": self.move_perm(L_move, d)
  56. elif face[0] == "F": self.move_perm(F_move, d)
  57. elif face[0] == "R": self.move_perm(R_move, d)
  58. elif face[0] == "B": self.move_perm(B_move, d)
  59. elif face[0] == "D": self.move_perm(D_move, d)
  60.  
  61. def move_sequence(self, sequence):
  62. """Performs moves given a sequence of turns. Like scramble."""
  63.  
  64. for turn in sequence.split(): self.move(turn)
  65.  
  66. def face_solved(self, nro):
  67. """Checks if the face nro of the cube is solved."""
  68. a = self.cube[nro][0][0]
  69.  
  70. for i in xrange(3):
  71. for j in xrange(3):
  72. if self.cube[nro][i][j] != a:
  73. return False
  74.  
  75. return True
  76.  
  77. def is_solved(self):
  78. """Checks if a cube is solved."""
  79.  
  80. for i in xrange(6):
  81. if not self.face_solved(i): return False
  82.  
  83. return True
  84.  
  85. def save(self):
  86. self.previous = copy.deepcopy(self.cube)
  87.  
  88. def same(move1, move2):
  89. """Checks if two moves are of the same type. This is to avoid sequences like "U U2" or "D' D"."""
  90.  
  91. return move1[0] == move2[0]
  92.  
  93. def intersection(move1, move2):
  94. """Returns true if move1 and move2 intersects and false if they don't. This is to avoid sequence like "U D U" or "F B' F2."""
  95.  
  96. x = move1[0]
  97. y = move2[0]
  98.  
  99. if x in "UD": return y not in "UD"
  100. elif x in "LR": return y not in "LR"
  101. elif x in "FB": return y not in "FB"
  102.  
  103. return False
  104.  
  105. def count_cycle(com):
  106.  
  107. cubo=Rubik()
  108.  
  109. c=0
  110. while 1:
  111. cubo.move_sequence(com)
  112. c+=1
  113. if cubo.is_solved(): break
  114. return max(1,c)
  115.  
  116. def increment(seq, pos = None, mov = moves):
  117. """Brute force for movements."""
  118.  
  119. if pos is None:
  120. pos = len(seq)-1
  121.  
  122. seq[pos] += 1
  123.  
  124. if seq[pos] == len(mov):
  125. seq[pos] = 0
  126.  
  127. if pos == 0:
  128. seq.append(0)
  129. print "Size", len(seq) # control how much moves we have
  130.  
  131. else: increment(seq, pos-1, mov)
  132.  
  133. check(seq, mov)
  134.  
  135. def check(seq, mov = moves):
  136.  
  137. for i in xrange(len(seq) - 1):
  138.  
  139. if same(mov[seq[i]], mov[seq[i+1]]) or (len(seq)>2 and i>0 and (not intersection(mov[seq[i-1]], mov[seq[i]]) and not intersection(mov[seq[i]], mov[seq[i+1]])) ): # consecutives moves are of the same type, like U' U2.
  140.  
  141. increment(seq, i+1, mov) # increments the next one
  142.  
  143. j = i+2
  144. while j < len(seq):
  145. seq[j] = 0 # zeroes to the rest to begin again
  146. j += 1
  147.  
  148. if j>i+2: check(seq, mov) # if zero at some part, check the rest of the sequence
  149.  
  150. break # as the rest of the sequence is checked, there's no need to continue with i
  151.  
  152. def main():
  153.  
  154. maximo = 0
  155. result = ""
  156.  
  157. possible_cycles = [0, 1] #lazy way to avoid some moves. this explais the [2:] below
  158. corresponding_sequences = ["", ""]
  159.  
  160. temp = [0]
  161.  
  162. while 1:
  163.  
  164. sequence = []
  165.  
  166. for x in temp: sequence.append(moves[x]) # prints the sequence that leads to 2x2x2 block
  167.  
  168. seq = " ".join(sequence)
  169.  
  170. cycle = count_cycle(seq)
  171.  
  172. if cycle not in possible_cycles:
  173. possible_cycles.append(cycle)
  174. corresponding_sequences.append(seq)
  175.  
  176. print cycle, "-", seq
  177.  
  178. increment(temp)
  179. while temp[0] > 1: # cheat. always start with U or U2 moves.
  180. increment(temp)
  181.  
  182. main()
Advertisement
Add Comment
Please, Sign In to add comment