Of solving the rubik's from scratch [Python]

Internet is full of solution for the rubik’s cube. However, it is seldom described how these solutions were discovered. In this post I’ll try to detail how one can solve the rubik’s cube from scratch.

**Disclaimer : ** The solution presented here is by no mean the fastest… It is actually very long to solve the Rubix Cube using this algorithm. It is just the one I came up with, so I guess it is probably in some sense one of the simplest. Though I am very proud of having cracked it up, there isn’t much to be proud about : it took me about a year to come up with a solution. At that time, I was always carrying a rubik’s cube and a notebook to search for the magic moves in the train like a lunatic.

At that time, I was kind of making a point of using a computer as little as possible. It was years ago and I forgot the moves I came up with. So in this post I try to find these moves again, but in python.

What is a rubik’s cube anyway?

A fixed referential and six possible moves.

I’m pretty sure you know what a rubik’s cube is. Let’s still make a couple of obvious statements.

We’ll assuming that the rubik’s cube’s faces center are fixed, and that we never rotate the whole thing. Which such as setting, there is 6 atomic move you can make with a rubik’s cube. They each consists of turning one of its faces one way or the other.

Each operation will be named after the face that we are turning, and the sens of rotation will be the so-called positive sens, more commonly called counterclockwise.

We will associate a 3D-referential to the rubik’s to easily code the rotation operations. The referential will be so-called direct. The normal vector for the right face, the upper face and the front face will respectively be (1,0,0), (0,1,0), and (0,0,1).

Clockwise turn can be obtained by repeating a turn three times.

Two different sets of blocks

The rubik’s cube is made of smaller blocks. Let alone the block at the very center of the rubik’s cube, and the center of the faces, we have 3x3x3 - 1 - 6 = 20 blocks. They are of two types. Corners (8 blocks) and side blocks (12 blocks), showing respectively 3 and 2 faces. While moving the rubik’s cube, corners will not become side blocks and side blocks will not become corner blocks (obvious statements remember?). Everything happens as if they are living independant lives. That will be the root of the method I’m presenting here.

What’s the plan then?

We will solve the rubik’s cube the following way.

Step 1

Place the side blocks at the correct position with their correct orientation.

Step 2

Place the corners blocks at their correct location regardless of their orientation.

** Step 3 ** Fix the orientation of the corners.

Reaching step 1 is a very nice and cute puzzle that does not require much crunching. I will not detail its solution here.

Step 2 and step 3 however are very difficult.

The trick to achieve step 2 will be to find some simple sequences of moves that makes it possible to move corner blocks without moving the side blocks.

The trick to achieve step 3 will be to find some simple sequence of moves that leaves all blocks at the same place, but change the orientation of some of the corners.

We also want to find movements that can generates all the possible positions of the rubik’s cube.

A bit of math

For step two we ideally would want to generate all permutations on the corner, while letting the side in place. However this is not quite reasonable. Let’s proof that it is not possible to apply any permutation on corners, while letting sides unchanged..

The proof relies on letting alone the orientations of the cube of the rubik’s cubes, and consider only the effect of the basic moves on the permutation of the side blocks on one hand, and the permutations of the corners on the other hand. The basic moves are a cycle of length 4 in both case. That’s an odd signature. The identity has an even signature. In other words, any sequence of basic operation letting the sides untouched has an even number of operation. Hence, the permutations applied on the corners for any sequence of moves letting sides untouched must have an even signature. A transposition for instance, is not possible.

For step 2, we’ll be happy if we find a move that generates all the permutations with a even signature. A cycle of length 3 of corners belonging all on one face should do the trick.

For similar reasons, it is not possible to turn only one corner as well. For step 3, the move we will be looking for is a move that changes the orientation of at most 3 corners belonging to the same face.

Let’s bruteforce finding these movements.

Coding a rubik’s cube in python

We will need to be able to handle very simple geometry operations. Considering numpy as a bit overkill, let’s just recode a couple of 3D vector operation.

Representing the rubik’s cube by a data structure is actually pretty tricky. To keep code small and cute, I chose to avoid implementing a rubik’s cube class, but instead represent the rubik’s cube state as a simple dictionary.

In order to solve step 2 or step 3, we will also need to be able to consider a rubik’s cube with only side cubes, a rubik’s cube with only corner cubes, a rubik’s cube for which corners are not oriented but are different one to each other (as if they had a number associated) and finally a full rubik’s cube.

In the following piece of code, the rubik’s cube will just be a dictionary having for key coordinates in the 3x3x3 3D grid, and for value an object describe the part of the rubik’s cube associated (simply called cube in the code).

We use alternatively different implementation of a cube. One storing orientation information while the other does not.

Note that it would have been possible to use much a much more abstract and efficient way to describe the rubik’s cube, but I prefer to keep things as explicit as possible here.

All the difficulty left here is to find a magic move which leaves sides untouched and yet have some effect on the corners. Let’s call such a combination a magic move!

When trying to find a magic move, especially without a computer, a good trick is to test many moves and consider for each of them what happens if you repeat this moves over and over. The images obtained by repeating the operation is also called an orbit.

When doing that by hand, it can be tested very rapidly by representing the underlying permutations as a union of cycles.

But with a computer we can do all this very simply.

We gat da moves!

The code is available here, and should take a couple of minutes to run on your computer.

The output you should get is

Step 2

Searching for a move letting sides
untouched, letting all but three corners belonging to the
same face at the same place.

right-left-left-up-down-down x4
[(-1, 1, 1), (-1, -1, 1), (1, -1, 1)]

---------------

Step 3

Searching a sequence that only change the orientation
of three corners.

right-up-right-right-right-front-front-up-up-up x6
[(-1, 1, 1), (-1, -1, 1), (1, 1, 1)]


Let’s what these operation look like when applied on a resolved rubik’s cube.

The operation returned for step 2 is permuting 3 cubes on the back of the rubik’s cube.

The operation returned for step 3 is changing the orientation on 3 cubes on the front face.