7.1. Rubik's cube

Let us suppose that we number from 1 to 48 the non-central coloured squares of a Rubik's cube. There are six basic rotations, corresponding to each of the six faces:

[Graphics:../HTMLFiles/xPermDoc.nb_316.gif]

We introduce the following notation for quarter-turns, with clockwise rotations:

In[146]:=

rot1 = Cycles[{1, 3, 8, 6}, {2, 5, 7, 4}, {9, 48, 15, 12}, {10, 47, 16, 13}, {11, 46, 17, 14}] ;

rot2 = Cycles[{6, 15, 35, 26}, {7, 22, 34, 19}, {8, 30, 33, 11}, {12, 14, 29, 27}, {13, 21, 28, 20}] ;

rot3 = Cycles[{1, 12, 33, 41}, {4, 20, 36, 44}, {6, 27, 38, 46}, {9, 11, 26, 24}, {10, 19, 25, 18}] ;

rot4 = Cycles[{1, 24, 40, 17}, {2, 18, 39, 23}, {3, 9, 38, 32}, {41, 43, 48, 46}, {42, 45, 47, 44}] ;

rot5 = Cycles[{3, 43, 35, 14}, {5, 45, 37, 21}, {8, 48, 40, 29}, {15, 17, 32, 30}, {16, 23, 31, 22}] ;

rot6 = Cycles[{24, 27, 30, 43}, {25, 28, 31, 42}, {26, 29, 32, 41}, {33, 35, 40, 38}, {34, 37, 39, 36}] ;

RubikGS = GenSet[rot1, rot2, rot3, rot4, rot5, rot6] ;

It is customary to define the following face-turns (the initials stand for Front, Down, Left, Up, Right, Back for obvious reasons):

In[153]:=

In[154]:=

RubikPoints = {f, f, f, f, f, f, f, f, l, l, l, d, d, d, r, r, r, l, l, d, d, r, r, l, l, l, d, d, d, r, r, r, b, b, b, b, b, b, b, b, u, u, u, u, u, u, u, u} ;

With a normal Linux box we can compute a strong generating set in a few seconds:

In[155]:=

myTiming[RubikSGS = SchreierSims[{}, RubikGS, 48] ;]

4.070369 Second

We translate it to Cycles notation. We see that there are 18 points in the base and 99 generators (a SGS with only 19 generators is known for the Rubik's group):

In[156]:=

RubikSGS = TranslatePerm[RubikSGS, Cycles] ;

In[157]:=

Length/@RubikSGS

Out[157]=

StrongGenSet[18, 99]

Reordering the base we can get this reduced SGS (this is taken from Butler's book):

In[158]:=

Rubikbase2 = {1, 6, 3, 8, 21, 23, 26, 5, 29, 19, 7, 24, 25, 28, 31, 18, 4, 2} ;

We check that it is a strong generating set indeed:

In[160]:=

myTiming[RubikSGS2 = SchreierSims[Rubikbase2, RubikGS2, 48] ;]

0.939531 Second

In[161]:=

RubikSGS2 = TranslatePerm[RubikSGS2, Cycles] ;

In[162]:=

Length/@RubikSGS2

Out[162]=

StrongGenSet[18, 19]

As we said, it is a huge group:

In[163]:=

order = OrderOfGroup[RubikSGS2]

Out[163]=

43252003274489856000

In[164]:=

FactorInteger[order]

Out[164]=

{{2, 27}, {3, 14}, {5, 3}, {7, 2}, {11, 1}}

Orders of the chain of stabilizers:

In[165]:=

RubikSGS2Chain = StabilizerChain[RubikSGS2] ;

In[166]:=

OrderOfGroup/@RubikSGS2Chain

Out[166]=

In[167]:=

basicindices = Drop[%/RotateLeft[%], -1]

Out[167]=

{24, 21, 18, 15, 24, 22, 12, 20, 9, 18, 16, 6, 14, 12, 10, 8, 6, 2}

Now we can check potential configurations:

A rotation in a single corner or the exchange of two side-neighbours are not possible:

In[168]:=

PermMemberQ[Cycles[{8, 15, 14}], RubikSGS]

Out[168]=

False

In[169]:=

PermMemberQ[Cycles[{10, 4}], RubikSGS]

Out[169]=

False

But pairs of them are allowed, in adequate directions:

In[170]:=

PermMemberQ[Cycles[{10, 4}, {7, 13}], RubikSGS]

Out[170]=

True

In[171]:=

PermMemberQ[Cycles[{8, 15, 14}, {24, 41, 38}], RubikSGS]

Out[171]=

True

In[172]:=

PermMemberQ[Cycles[{8, 15, 14}, {24, 38, 41}], RubikSGS]

Out[172]=

False

A combination of both is impossible:

In[173]:=

PermMemberQ[Cycles[{10, 4}, {8, 15, 14}], RubikSGS]

Out[173]=

False

There is the famous question on the minimum number of moves which allows solving any configuration of the Rubik cube. Here it is very important to distinguish between face turns and quarter turns. An f-turn can be equal to one or two q-turns depending on the case. In what follows we only consider q-turns. There is a simple lower bound to the minimum number of q-turns required to solve any configuration, obtained by branching over 7 possibilities (the identity and the six rotations) that number of times: 24

24 is the first power of 7 which is larger than the order of the group:

In[174]:=

order/7^24//N

Out[174]=

0.225763

The superflip position requires 24 moves (see wikipedia):

In[175]:=

superflip = Cycles[{2, 47}, {4, 10}, {7, 13}, {5, 16}, {20, 19}, {21, 22}, {28, 34}, {18, 44}, {25, 36}, {45, 23}, {42, 39}, {31, 37}] ;

In[176]:=

PermMemberQ[superflip, RubikSGS2]

Out[176]=

True

Interestingly, this is the only nontrivial permutation which commutes with every other permutation in the Rubik group:

In[177]:=

PermEqual[Permute[superflip, rot1, superflip], rot1]

Out[177]=

True

In[178]:=

PermEqual[Permute[superflip, rot2, superflip], rot2]

Out[178]=

True

In[179]:=

PermEqual[Permute[superflip, rot3, superflip], rot3]

Out[179]=

True

In[180]:=

PermEqual[Permute[superflip, rot4, superflip], rot4]

Out[180]=

True

In[181]:=

PermEqual[Permute[superflip, rot5, superflip], rot5]

Out[181]=

True

In[182]:=

PermEqual[Permute[superflip, rot6, superflip], rot6]

Out[182]=

True

A position requiring 26 q-turns is known.

As of 2008, the best upper bounds known are 26 f-turns and 35 q-turns to solve arbitrary configurations of the cube.

Another frequent question whether a SGS can be used to actually solve an arbitrary configuration of the Rubik cube and the answer is of course positive. The algorithm PermWord can decompose any configuration in a product of 19 coset representatives, but then we need to decompose each of those 19 representatives in terms of the original 6 rotations. The final algorithm is, however, far from optimal, and actually very simple "human" algorithms perform better than this.

There are 239 possible nontrivial coset representatives:

In[183]:=

Plus @@ basicindices - 18

Out[183]=

239

Let us construct the canonical representatives:

In[184]:=

reprs = {} ;

reprs = Flatten[reprs] ;

Those moves can be expressed in terms of face turns. For simplicity, we use an external solver to do it (we use kociemba.org). This function transforms a permutation into a chain of facelets that can be fed to that solver:

In[187]:=

For example:

In[188]:=

tochain[PermuteList[RubikPoints, InversePerm @ reprs[[235]]]]

Out[188]=

uuduudurrubbdrrdrdrbbffffffllldddrflllflluflurbbubbbrd

and relate them with the collections of face-turns that we have previously stored in a file:

In[189]:=

(RubikFaceTurns = <<"data/RubikFaceTurns")//ColumnForm

Check that the relations are correct:

In[190]:=

Apply[And, RubikFaceTurns/.permute→Permute/.faceturns/.Rule→PermEqual]

Out[190]=

True


Created by Mathematica  (May 16, 2008) Valid XHTML 1.1!