18 September 2011

Rubik's Snake Combinations

I've had a long standing attraction to the Rubik's Snake puzzle for many years, including being involved with glSnake. (Scroll to the red bit for final answer)

One question of interest was how many unique configurations of the Snake are possible. The Snake consists of 24 interconnecting prisms, with each interconnect able to be in one of four possible positions. This leads to a trivial upper bound of 423 = 70,368,744,177,664 distinct combinations. But many of these are not actually possible, as they may be configurations where the snake impossibly passes through itself. And most configurations will appear twice as mirror images.

A trivial lower bound can be reached by starting with a straight snake and then only permuting every other junction. Every rotation will be along a parallel axis, giving rise to pairs of interconnects that are always on discrete planes: meaning that the snake can never bend back on itself. Halving guarantees no reflections. (Symmetrical would only be counted once, but this is a lower-bound). This gives 411/2 = 2,097,152 as a trivial lower bound.

As an enhanced lower bound, we could observe that the snake prisms exits on a 3-dimensional grid of cubes. At any time the next piece could lie in the adjacent voxel in either the x, y or z direction (but can never follow the same axis twice). If we restrict ourselves to only ever advancing in the positive direction on each axis, then we always have a choice of one of (+y or +z) or (+x or +z) or (+x or +y), depending on whether our previous move was +x, +y, or +z respectively. In any case we have 2 choices. This gives us 223, which is not any better than before. However we can extend the idea: if we partition the space into planes normal to the x axis, then any time we extend in the +x direction, without loss of generality we can start moving in in any of the four +/-y or +/-z, i.e. four choices. From there we can move +x again, or either +/- along the axis we didn't previously chose. I.e. 3 choices. In this way we never fold back to previous planes. From that point on we only have 2 choices: to continue moving in a straight diagonal, or move onto the next x plane. We can represent this as the following Markovian chain:

0020Refined lower-bound:
1110(approx 418.15)

That's about as far as I could get without using numerical methods. (I also had a complicated, slightly improved, upper bound). So I wrote a program to walk every possible combination, which back tracks whenever it found a collision. Written as a single-threaded service to run in the background this took about five months to execute. This gave the following answer:

13,535,886,319,159 = approx 421.81 combinations, including possible mirror image duplicates.
Update: 5th Aug 2022: Corrected to 13,446,591,920,995 = approx 421.81. See below.

To handle mirror images, each time it encounters a complete snake it then converts it to a normalized form as follows. The snake is represented as a string of 23 numbers (from 0 to 3). The string is then reversed. The two strings are compared lexicographically and the smaller is the normal form. If the string matches the normal form, then it is counted, otherwise it is skipped. This way potential reflections that appear twice can be counted once, but symmetrical snakes also get counted once. Note that I'm interpreting mirror images here as applying the same turns from either end, not if the volume produced is a mirror image. For example, I'm counting a left-handed corkscrew snake and a right-handed corkscrew snake as discrete. But if you just twist one piece 180 degrees at the start or the end of the snake, then I count that as the same snake.

When ignoring reflections like this, the exhaustive search gives this result. Total number of possible snake configurations that don't overlap, and ignoring mirror repeats:

Final Answer = 6,770,518,220,623 = approx 421.31
Update: 5th Aug 2022: Corrected to 6,721,828,475,867 = approx 421.31. See below.

Behold. OK, it only took another two years to getting around to writing this up any telling the world. (mainly because I started writing up a detailed paper on the method, which quickly got boring). Hopefully anyone else who has tried this got the same answer.

So table of numbers: (Update: see below for correction)

MethodNumberApprox as exponent
Trivial lower bound2,097,152410.5
Refined lower bound85,149,351,936418.15
Final answer6,770,518,220,623421.31Corrected: 6,721,828,475,867
Exhaustive with duplicates13,535,886,319,159421.81Corrected: 13,446,591,920,995
Refined upper bound30,002,572,532,736422.60
Trivial upper bound70,368,744,177,664423.00

Along the way I also discovered that there are about 64,546,391 Corrected: 63,970,851 (approx 412.97 unique cyclic paths where the head and tail of the snake connect. Also, only a relatively small number of snakes are symmetrical.

I should probably go and get some sun, or social interaction, or something now.

Update: 5th Aug 2022

It turned out that my original calculation was wrong. I wrote another Snake Calculator program while playing around with another problem - and results didn't quite match. The good thing about now having two independent programs is that each could be used to find and fix bugs in the other. The original program didn't quite handle an edge-case correctly. Further inspired by hearing about "The Soul of the Snake" I've re-run the program on a full length snake.

With both programs now agreeing for various length snakes, I now feel pretty confident about the following answer being correct for length 24:

Final Corrected Answer = 6,721,828,475,867 = approx 421.31

MethodNumberApprox as exponent
Trivial lower bound2,097,152410.5
Refined lower bound85,149,351,936418.15
Final answer6,721,828,475,867421.31
Exhaustive with duplicates13,446,591,920,995421.81
Refined upper bound30,002,572,532,736422.60
Trivial upper bound70,368,744,177,664423.00

(Yes, the difference is less than 1%, so the exponents are still pretty much the same)

The Internet is now a little bit more correct and, to offset the drop in entropy, a server somewhere in an AWS data centre has been slightly warmed.


joeloninfospace said...

Did you ever write your detailed paper?

Arthur said...

Mega is a complex algorithm, just mega! By the way, yes, the same question I had, did you write a script in Java about it?
I recently tried javascript snake https://explainjava.com/javascript-snake/ honestly I just opened and run the program and saw the magic) Most of all game development tutorials wrote great. One of my friends has been looking for some professional tutorials for game development and I'm definitely suggesting reading him your post. I was surprised by this calculation of probability, I'm sure he'll be interested too.

Timy Tons said...

so… facebook recommended me the pages “food” and “eating” ,,, yeah I’m obese|HasmAttack|

joeloninfospace said...

Well, I hope you write your paper someday.

Unknown said...
This comment has been removed by the author.
Unknown said...

And I hope you've got around to a satisfying social interaction ;)

Thanks for the efforts and sharing info in this article.

Alexander from Russia, Moscow

cuc said...

Hi Peter,

Thanks for contributing to my book "Soul of the Snake" coming out soon. That means that this page is going to change sometimes, right?
For all of you out there, keep an eye on https://tinyurl.com/Soul-Of-The-Snake.