### Problem Description

This program solves the 4 cube, 4 color version of the **Instant Insanity**
puzzle. It was developed by Frank Armbruster and the commercial version is
still available from
http://www.gamepuzzles.com/prpuzzls.htm .

### Background & Techniques

Instant Insanity is a variation of an older cube arrangement puzzle and one
of a large family of similar puzzles. In this one, we have four cubes with one
of four colors on each face of each cube. The objective is to stack the
cubes so each column of faces has all four colors.

Most of the online literature describes a graph search algorithm which can be
applied to find solutions
without the aid of a computer.

I imagine that the "trial and error" approach to solving the puzzle led to its
name, although "Eventual Insanity" might be more appropriate since there are
41,472 arrangements to check! Why 41,272? There are 24 orientations of
each cube. Check this yourself with a die by placing each of the 6 faces
pointing up and for each of these rotate the 4 vertical faces (left, front,
right and back) to the front. The product 6x4 is the number of
possible orientations for that cube.

For the first placed cube, we don't need to check all 24 orientations because
any solution would appear 8 times. That is, rotating a solution stack with each
of the 4 faces pointing to the front would represent 4 solutions and inverting
the entire stack and then rotating it would produce 4 more solutions. So for the
first cube, we only need to place one face of each of the 3 axes facing up,
skipping the other 21 possible orientations. The other three cubes must be
checked in each of the 24 orientations, so the total number of configurations to
check is 3 x 24 x 24 x24 = 41,472.

Version 1 of this program takes advantage of the computer's speed to check all
41,472 arrangements looking for solutions. Four sample cube sets are
included, plus a sample text file which maybe used as a model to input
additional sets. Future program versions may add better graphics, other
cube set sizes, and a cube set generator.

Non-programmers are welcome to read on, but may want to jump to bottom of
this page to download the executable program now.

### Programmer's Notes:

This program was about the right size to provide a moderately challenging
problem that could be solved (and coded) in 3 or 4 days of spare time
programming.

When the Search button is clicked we set up cube definitions, **Cubes ** to be modified as we search
from the **OrigCubes** definition.. Each cube is defined by a 6 character string
representing the faces in a particular order. I chose the 6 characters
to represent the colors of the Top, Left, Front, Right, Back, and Bottom faces
in that order. Cube sets are defined as** TCubes** type is defined as an array
[0..3], of
string[6] types.

**SearchBtnClick** calls recursive depth-first search procedure **CheckNext** to place the
next cube in all of its orientations. **CheckNext** creates the
next orientation for cube N and calls itself to check cube N+1. When the 4th
cube has been placed, function **CheckSolved** is called to test if
this arrangement could be a solution. If each of the four visible face
directions contains all four color across the 4 cubes, this looks like a
solution. Function **IsUniqueSolution** is called just to make sure
that we have not already encountered this solution. **IsUniqueSolution**
may not be smart enough yet to catch all duplicate solutions, but it will catch
the case where the same colors appear on opposite faces for two different
adjacent faces. (For example GRGR colors on the Left, Front, Right, and
Back faces could produce two apparently duplicate solutions when the cube is
rotated 180 degrees.)

For efficiency a doubly indexed array, **Targets**, indexes
the face numbers to move to top of cube (position 1
in the cube string). **TFace** type defines a 6 integer array to specify the
target positions for each face
of the source cube. So, for example, **Targets[2]** is a **TFace** array which
specifies the target locations for each of the 6 faces when face 2 is rotated to
the top of the cube. Values are initialized by the **InitFaceTargets**
procedure which applies successive rotations to fill in the target positions for
each of the faces 2 through 6 is to be moved to position 1 (the top face).
Within **CheckNext** , calls are made to** MoveFaceToTop** for each face 2
through 6 to run through the **Targets** array and efficiently rotate the faces.
For each face on top it calls **RotateCubeRight** to rotate each of the
visible faces to each of the 4 visible positions.

### Running/Exploring the Program