rec.puzzles Archive

What is the solution to Rubik's Tangle?

competition/games/rubiks/rubiks.tangle Added material

Problem

What is the solution to Rubik's Tangle?

Show solution
From: Bob Smith <uunet!wci.com!bsmith>

Hi,

  Patchwork of a hack of a kludge.  Worth every penny of what
you're paying for it.



/*
 * This is a program to solve the puzzle defined below:
 *
#       Rubik's Tangle (#4)
#The puzzle consists of 25 square pieces which are to be arranged in
#a 5 by 5 grid such that each edge matches the edge of an adjoining
#piece.  Each piece has 4 sides and each side has 2 ordered colors.
#The idea is to match Red-to-Red and Blue-to-Blue, ...
#
#Since the pieces are square they may be rotated to fit as needed.
#
#The 25 pieces are listed below.  The listing shows the 'straight'
#piece vertical and the 'loop' opening to the left.  The colors are
#shown clockwise starting from the top
#
1        brgbrygy
2        bgybgryr
3        rygrybgb
4        rybrygbg
5        ybrybgrg
6        gybgyrbr
7        gbygbryr
8        rgyrgbyb
9        ybgybrgr
10        bygbyrgr
11        grygrbyb
12        rbgrbygy
13        yrbyrgbg
14        rbyrbgyg
15        gyrgybrb
16        gybgyrbr
17        brybrgyg
18        ygrygbrb
19        bgrbgyry
20        gbrgbyry
21        yrgyrbgb
22        grbgryby
23        rgbrgyby
24        byrbygrg
25        ygbygrbr
*
*
Since there are twelve possible combination of colors on each edge of each
piece, we substitue the possible color combinations with hex digits as
follows:
        "yg"("0");
        "yr"("1");
        "yb"("2");
        "gy"("3");
        "gr"("4");
        "gb"("5");
        "ry"("6");
        "rg"("7");
        "rb"("8");
        "by"("9");
        "bg"("A");
        "br"("B");

We will define pieces 1 to 25 to be the above; pieces 26 to 50 to be the
above pieces rotated clockwise one turn; pieces 51 to 75 ....

The solution matrix is as follows.
     1  2  3  4  5
     6  7  8  9 10
    11 12 13 14 15
    16 17 18 19 20
    21 22 23 24 25
*/

#include <stdio.h>
#include <signal.h>

char *pieces[26] = {
        "        ",  /* lets piece # equal array index */
        "brgbrygy",
        "bgybgryr",
        "rygrybgb",
        "rybrygbg",
        "ybrybgrg",
        "gybgyrbr",
        "gbygbryr",
        "rgyrgbyb",
        "ybgybrgr",
        "bygbyrgr",
        "grygrbyb",
        "rbgrbygy",
        "yrbyrgbg",
        "rbyrbgyg",
        "gyrgybrb",
        "gybgyrbr",
        "brybrgyg",
        "ygrygbrb",
        "bgrbgyry",
        "gbrgbyry",
        "yrgyrbgb",
        "grbgryby",
        "rgbrgyby",
        "byrbygrg",
        "ygbygrbr",
};


/* the loop variables */
int i01,i02,i03,i04,i05,i06,i07,i08,i09,i10;
int i11,i12,i13,i14,i15,i16,i17,i18,i19,i20;
int i21,i22,i23,i24,i25;

void current_state();
void wakeup();

main()
{
        int i,n;
        char edge[101][5];  /* the fifth field is a 'used' flag ('T' or 'F') */

        /* Uncomment the following to see a 'status' every minute */
        /*if (signal(SIGALRM, wakeup) != 0)
                printf("Alarm timer not set!!!  Continuing...\n");
        (void) alarm(60); */

        /* convert the original string patterns to edge patterns */
    for (i=1; i<=25; i++) {
                for (n=0; n<4; n++) {
                        if (!strncmp(pieces[i]+(n*2), "yg", 2)) edge[i][n] = '0';
                        else if (!strncmp(pieces[i]+(n*2), "yr", 2)) edge[i][n] = '1';
                        else if (!strncmp(pieces[i]+(n*2), "yb", 2)) edge[i][n] = '2';
                        else if (!strncmp(pieces[i]+(n*2), "gy", 2)) edge[i][n] = '3';
                        else if (!strncmp(pieces[i]+(n*2), "gr", 2)) edge[i][n] = '4';
                        else if (!strncmp(pieces[i]+(n*2), "gb", 2)) edge[i][n] = '5';
                        else if (!strncmp(pieces[i]+(n*2), "ry", 2)) edge[i][n] = '6';
                        else if (!strncmp(pieces[i]+(n*2), "rg", 2)) edge[i][n] = '7';
                        else if (!strncmp(pieces[i]+(n*2), "rb", 2)) edge[i][n] = '8';
                        else if (!strncmp(pieces[i]+(n*2), "by", 2)) edge[i][n] = '9';
                        else if (!strncmp(pieces[i]+(n*2), "bg", 2)) edge[i][n] = 'A';
                        else if (!strncmp(pieces[i]+(n*2), "br", 2)) edge[i][n] = 'B';
                }
                /* do the rotations */
                edge[i][4] = 'F';
                edge[i+25][0] = edge[i][1];
                edge[i+25][1] = edge[i][2];
                edge[i+25][2] = edge[i][3];
                edge[i+25][3] = edge[i][0];
                edge[i+25][4] = 'F';
                edge[i+50][0] = edge[i][2];
                edge[i+50][1] = edge[i][3];
                edge[i+50][2] = edge[i][0];
                edge[i+50][3] = edge[i][1];
                edge[i+50][4] = 'F';
                edge[i+75][0] = edge[i][3];
                edge[i+75][1] = edge[i][0];
                edge[i+75][2] = edge[i][1];
                edge[i+75][3] = edge[i][2];
                edge[i+75][4] = 'F';
        }

        /* replace the bottom and left edges with the 'matching' edge needed */
        /* on the top or right edge. Thus 'yg' on the top matches bottom 'gy'.*/
        for (i=1; i<=100; i++) {
                for (n=2; n<=3; n++) {
                        if (edge[i][n] == '0') edge[i][n] = '3';
                        else if (edge[i][n] == '1') edge[i][n] = '6';
                        else if (edge[i][n] == '2') edge[i][n] = '9';
                        else if (edge[i][n] == '3') edge[i][n] = '0';
                        else if (edge[i][n] == '4') edge[i][n] = '7';
                        else if (edge[i][n] == '5') edge[i][n] = 'A';
                        else if (edge[i][n] == '6') edge[i][n] = '1';
                        else if (edge[i][n] == '7') edge[i][n] = '4';
                        else if (edge[i][n] == '8') edge[i][n] = 'B';
                        else if (edge[i][n] == '9') edge[i][n] = '2';
                        else if (edge[i][n] == 'A') edge[i][n] = '5';
                        else if (edge[i][n] == 'B') edge[i][n] = '8';
                }
        }

        /* OK, Here we have 25 nested loops to do the search */
        for (i01=1; i01<=100; i01++) {
                edge[i01%25][4]='T';
        for (i02=1; i02<=100; i02++) {
                if (edge[i02%25][4] == 'T') continue;
                if (edge[i01][1] != edge[i02][3]) continue;
                edge[i02%25][4]='T';
        for (i03=1; i03<=100; i03++) {
                if (edge[i03%25][4] == 'T') continue;
                if (edge[i02][1] != edge[i03][3]) continue;
                edge[i03%25][4]='T';
        for (i04=1; i04<=100; i04++) {
                if (edge[i04%25][4] == 'T') continue;
                if (edge[i03][1] != edge[i04][3]) continue;
                edge[i04%25][4]='T';
        for (i05=1; i05<=100; i05++) {
                if (edge[i05%25][4] == 'T') continue;
                if (edge[i04][1] != edge[i05][3]) continue;
                edge[i05%25][4]='T';
        for (i06=1; i06<=100; i06++) {
                if (edge[i06%25][4] == 'T') continue;
                if (edge[i01][2] != edge[i06][0]) continue;
                edge[i06%25][4]='T';
        for (i07=1; i07<=100; i07++) {
                if (edge[i07%25][4] == 'T') continue;
                if (edge[i06][1] != edge[i07][3]) continue;
                if (edge[i02][2] != edge[i07][0]) continue;
                edge[i07%25][4]='T';
        for (i08=1; i08<=100; i08++) {
                if (edge[i08%25][4] == 'T') continue;
                if (edge[i07][1] != edge[i08][3]) continue;
                if (edge[i03][2] != edge[i08][0]) continue;
                edge[i08%25][4]='T';
        for (i09=1; i09<=100; i09++) {
                if (edge[i09%25][4] == 'T') continue;
                if (edge[i08][1] != edge[i09][3]) continue;
                if (edge[i04][2] != edge[i09][0]) continue;
                edge[i09%25][4]='T';
        for (i10=1; i10<=100; i10++) {
                if (edge[i10%25][4] == 'T') continue;
                if (edge[i09][1] != edge[i10][3]) continue;
                if (edge[i05][2] != edge[i10][0]) continue;
                edge[i10%25][4]='T';
        for (i11=1; i11<=100; i11++) {
                if (edge[i11%25][4] == 'T') continue;
                if (edge[i06][2] != edge[i11][0]) continue;
                edge[i11%25][4]='T';
        for (i12=1; i12<=100; i12++) {
                if (edge[i12%25][4] == 'T') continue;
                if (edge[i11][1] != edge[i12][3]) continue;
                if (edge[i07][2] != edge[i12][0]) continue;
                edge[i12%25][4]='T';
        for (i13=1; i13<=100; i13++) {
                if (edge[i13%25][4] == 'T') continue;
                if (edge[i12][1] != edge[i13][3]) continue;
                if (edge[i08][2] != edge[i13][0]) continue;
                edge[i13%25][4]='T';
        for (i14=1; i14<=100; i14++) {
                if (edge[i14%25][4] == 'T') continue;
                if (edge[i13][1] != edge[i14][3]) continue;
                if (edge[i09][2] != edge[i14][0]) continue;
                edge[i14%25][4]='T';
        for (i15=1; i15<=100; i15++) {
                if (edge[i15%25][4] == 'T') continue;
                if (edge[i14][1] != edge[i15][3]) continue;
                if (edge[i10][2] != edge[i15][0]) continue;
                edge[i15%25][4]='T';
        for (i16=1; i16<=100; i16++) {
                if (edge[i16%25][4] == 'T') continue;
                if (edge[i11][2] != edge[i16][0]) continue;
                edge[i16%25][4]='T';
        for (i17=1; i17<=100; i17++) {
                if (edge[i17%25][4] == 'T') continue;
                if (edge[i16][1] != edge[i17][3]) continue;
                if (edge[i12][2] != edge[i17][0]) continue;
                edge[i17%25][4]='T';
        for (i18=1; i18<=100; i18++) {
                if (edge[i18%25][4] == 'T') continue;
                if (edge[i17][1] != edge[i18][3]) continue;
                if (edge[i13][2] != edge[i18][0]) continue;
                edge[i18%25][4]='T';
        for (i19=1; i19<=100; i19++) {
                if (edge[i19%25][4] == 'T') continue;
                if (edge[i18][1] != edge[i19][3]) continue;
                if (edge[i14][2] != edge[i19][0]) continue;
                edge[i19%25][4]='T';
        for (i20=1; i20<=100; i20++) {
                if (edge[i20%25][4] == 'T') continue;
                if (edge[i19][1] != edge[i20][3]) continue;
                if (edge[i15][2] != edge[i20][0]) continue;
                edge[i20%25][4]='T';
        for (i21=1; i21<=100; i21++) {
                if (edge[i21%25][4] == 'T') continue;
                if (edge[i16][2] != edge[i21][0]) continue;
                edge[i21%25][4]='T';
        for (i22=1; i22<=100; i22++) {
                if (edge[i22%25][4] == 'T') continue;
                if (edge[i21][1] != edge[i22][3]) continue;
                if (edge[i17][2] != edge[i22][0]) continue;
                edge[i22%25][4]='T';
        for (i23=1; i23<=100; i23++) {
                if (edge[i23%25][4] == 'T') continue;
                if (edge[i22][1] != edge[i23][3]) continue;
                if (edge[i18][2] != edge[i23][0]) continue;
                edge[i23%25][4]='T';
        for (i24=1; i24<=100; i24++) {
                if (edge[i24%25][4] == 'T') continue;
                if (edge[i23][1] != edge[i24][3]) continue;
                if (edge[i19][2] != edge[i24][0]) continue;
                edge[i24%25][4]='T';
        for (i25=1; i25<=100; i25++) {
                if (edge[i25%25][4] == 'T') continue;
                if (edge[i24][1] != edge[i25][3]) continue;
                if (edge[i20][2] != edge[i25][0]) continue;
                edge[i25%25][4]='T';
                printf("Solution: ");
                current_state();

        edge[i25%25][4]='F';}
        edge[i24%25][4]='F';}
        edge[i23%25][4]='F';}
        edge[i22%25][4]='F';}
        edge[i21%25][4]='F';}
        edge[i20%25][4]='F';}
        edge[i19%25][4]='F';}
        edge[i18%25][4]='F';}
        edge[i17%25][4]='F';}
        edge[i16%25][4]='F';}
        edge[i15%25][4]='F';}
        edge[i14%25][4]='F';}
        edge[i13%25][4]='F';}
        edge[i12%25][4]='F';}
        edge[i11%25][4]='F';}
        edge[i10%25][4]='F';}
        edge[i09%25][4]='F';}
        edge[i08%25][4]='F';}
        edge[i07%25][4]='F';}
        edge[i06%25][4]='F';}
        edge[i05%25][4]='F';}
        edge[i04%25][4]='F';}
        edge[i03%25][4]='F';}
        edge[i02%25][4]='F';}
        edge[i01%25][4]='F';}

        exit(1);
}

void wakeup()
{
        current_state();
        if (signal(SIGALRM, wakeup) != 0)
                printf("Alarm timer not set!!!  Continuing...\n");
        (void) alarm(600); 
}

void current_state()
{
        printf("%d,%1d ", i01%25, i01/25);
        printf("%d ", i02%25);
        printf("%d ", i03%25);
        printf("%d ", i04%25);
        printf("%d ", i05%25);
        printf("%d ", i06%25);
        printf("%d ", i07%25);
        printf("%d ", i08%25);
        printf("%d ", i09%25);
        printf("%d ", i10%25);
        printf("%d ", i11%25);
        printf("%d ", i12%25);
        printf("%d ", i13%25);
        printf("%d ", i14%25);
        printf("%d ", i15%25);
        printf("%d ", i16%25);
        printf("%d ", i17%25);
        printf("%d ", i18%25);
        printf("%d ", i19%25);
        printf("%d ", i20%25);
        printf("%d ", i21%25);
        printf("%d ", i22%25);
        printf("%d ", i23%25);
        printf("%d ", i24%25);
        printf("%d\n",i25%25);
        return;
}


/*
 * Four unique solutions are shown below.  Each solution has four rotations.

Solution: 19,0 6 18 23 9 0 5 21 11 24 20 2 4 15 22 13 3 7 1 16 10 17 12 8 14
Solution: 19,0 16 18 23 9 0 5 21 11 24 20 2 4 15 22 13 3 7 1 6 10 17 12 8 14
Solution: 9,1 24 22 6 14 23 11 15 1 8 18 21 4 7 12 16 5 2 3 17 19 0 20 13 10
Solution: 9,1 24 22 16 14 23 11 15 1 8 18 21 4 7 12 6 5 2 3 17 19 0 20 13 10
Solution: 14,1 8 12 17 10 6 1 7 3 13 22 15 4 2 20 24 11 21 5 0 9 23 18 16 19
Solution: 14,1 8 12 17 10 16 1 7 3 13 22 15 4 2 20 24 11 21 5 0 9 23 18 6 19
Solution: 1,2 11 12 17 3 21 5 23 15 2 20 6 18 13 10 0 24 22 7 19 16 8 9 14 4
Solution: 1,2 11 12 17 3 21 5 23 15 2 20 16 18 13 10 0 24 22 7 19 6 8 9 14 4
Solution: 10,2 13 20 0 19 17 3 2 5 6 12 7 4 21 18 8 1 15 11 23 14 16 22 24 9
Solution: 10,2 13 20 0 19 17 3 2 5 16 12 7 4 21 18 8 1 15 11 23 14 6 22 24 9
Solution: 3,3 2 10 19 4 17 15 13 7 14 12 23 18 22 9 11 5 6 24 8 1 21 20 0 16
Solution: 3,3 2 10 19 4 17 15 13 7 14 12 23 18 22 9 11 5 16 24 8 1 21 20 0 6
Solution: 4,3 14 9 8 6 19 7 22 24 0 10 13 18 16 20 2 15 23 5 21 3 17 12 11 1
Solution: 4,3 14 9 8 16 19 7 22 24 0 10 13 18 6 20 2 15 23 5 21 3 17 12 11 1
Solution: 6,3 0 20 21 1 8 24 16 5 11 9 22 18 23 12 14 7 13 15 17 4 19 10 2 3
Solution: 16,3 0 20 21 1 8 24 6 5 11 9 22 18 23 12 14 7 13 15 17 4 19 10 2 3

 */


Additional material

Gill, you're right about the letters.  I've received a solution to
Tangle version 1 (there are 4 versions) from Andre' Wilhelmus
<hvsgg01!awilhelm@hvgtw.att.com> which is as follows:

FCGEA
SJIBH
TYLVU
KMWNO
RQXDP

Andre' wrote a C program to solve it, and obtained 2 solutions.  What is
needed to further define the solution is the orientation of each piece.
I have asked for that, and have suggested a notation which describes the
location of the straight rope section on each piece, i.e. T for Top, R
for right side, etc.

The puzzle I have is version 3, in which piece 'C' and 'T' are the same,
they both have a blue straight, red wiggle, green hook, and a yellow 1/4
circle.

What version do you have Gill?  What pieces are the same?  (I'm assuming
the only difference between versions is that of the complete set of 24
possible colour combinations a different one is duplicated in each set
to make the 25th piece.)

-- Ross Cowie <ao383@freenet.carleton.ca>, January 1994