5
\$\begingroup\$

TL;DR for those not interested: Look at the test cases at the bottom. Have a program/function that outputs the 2D list displayed for the given input.

Introduction:

On November 15th, 2018 puzzle designer Raphaël Mouflin revealed his Triangularity puzzle. Here is a picture of that puzzle:
enter image description here As you can see, the shape is a 3-sided (4-faced) pyramid (a.k.a. tetrahedron), and it has six pieces per face.

So, what makes this puzzle so unique? It's the first puzzle in the shape of a regular platonic solid that is a hybrid of all three twisty puzzle rotational axis systems: face-turning, corner-turning, AND edge-turning. Most puzzles only have a single rotational axis system, like face-turning for the regular 3x3x3 Rubik's Cube; corner-turning for the Pyraminx; edge-turning for the Helicopter Cube; etc. Lately more hybrid puzzles are getting released of which most have two rotational axis systems combined in the same puzzle (usually face- and corner-turning, since that seems to be the easiest hybrid combination to accomplish).

There are some other puzzles with all three rotational axis, like the Truncated Icosidodecahedron or Superstar puzzles, but those use a pretty complex shape in order to accomplish that. Triangularity however is a simple 3-sided pyramid that still has all three rotational axis systems.

Here a video to show those moves.

Challenge:

Input:

The move we are doing, which is one of the following:

  • E# for an edge-turn, where # is a digit in the range [1,6] (or [0,5]) for the six edges, numbered here. So the blue-red edge is 1; blue-yellow is 2; yellow-red is 3; blue-green is 4; yellow-green is 5; and red-green is 6.
  • F#D for the face-turn, where # is a digit in the range [1,4] (or [0,3]) for the four faces, numbered here. So the blue face is 1; yellow face is 2; red face is 3; green face is 4. And D is the direction, either C (clockwise) or A (anti/counter clockwise).
  • C#D for the corner, where # is a digit in the range [1,4] (or [0,3]) for the four corners, numbered here. So the blue-yellow-red corner is 1; blue-green-red corner is 2; blue-yellow-red corner is 3; yellow-red-green corner is 4. And D is the direction, either C (clockwise) or A (anti/counter clockwise).

Optional second input: The initial solved state 2D-array below.

Output:

The output will be the modified 2D-array after we've executed the single given move, where the initial solved configuration pictured above would be:

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

Where these numbers indicate the pieces per face, so (using 'outer color - inner color' to indicate the pieces): 1 and 2 are the blue-red pieces; 3 and 4 the blue-yellow pieces; 5 and 6 the blue-green; 7 and 8 the yellow-blue; 9 and 10 the yellow-red; 11 and 12 the yellow-green; 13 and 14 the red-blue; 15 and 16 the red-yellow; 17 and 18 the red-green; 19 and 20 the green-blue; 21 and 22 the green-yellow; and 23 and 24 the green-red. (Looking at the faces in a clockwise direction, the first number is the first you encounter when going clockwise, and the second number the one next to it.)

Challenge rules:

  • The moves will be done in increments that doesn't change the tetrahedron shape. So even though the puzzle allows 60 degree increments for face-turns, and 90 degree increments for edge-turns, we will only do 180 degree edge turns and 120 degree face- and corner-turns so the puzzle won't shapeshift and will retain its tetrahedron shape.
  • Since the challenge is mainly about executing the move, and not about compressing the initial state, you can (optionally) take the initial state as additional input.
  • You are allowed to use either 1-indexed or 0-indexed numbers for the edges, faces, and corners. They do have to be consistent though, so you are not allowed to use [1,6] for the edges, and [0,3] for the corners. It should be either all 1-indexed or all 0-indexed. Please state what you've used in your answer.
  • I/O is flexible. Input move can be a String, character-array, etc. (You are not allowed to take the input as a list of codepoints, unless you language does this implicitly.) Output can be a 2D array/list, can modify the optional input 2D array/list, can be a string, etc.
  • You may optionally take the edge turns with a trailing C/A as well if it would save bytes, but the output would be the same in both cases, since the turns are in 180 degrees. (Please state so in your answer if you do take them with a trailing C/A which is ignored.)

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases / All possible I/O (1-indexed):

Input move    Output                                                                      (cycled pieces)

F1C           [[5,6,1,2,3,4],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]    (1→3→5→1 and 2→4→6→2 as 3-cycles)
F1A           [[3,4,5,6,1,2],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]    (1→5→3→1 and 2→6→4→2 as 3-cycles)
F2C           [[1,2,3,4,5,6],[11,12,7,8,9,10],[13,14,15,16,17,18],[19,20,21,22,23,24]]    (7→9→11→7 and 8→10→12→8 as 3-cycles)
F2A           [[1,2,3,4,5,6],[9,10,11,12,7,8],[13,14,15,16,17,18],[19,20,21,22,23,24]]    (7→11→9→7 and 8→12→10→8 as 3-cycles)
F3C           [[1,2,3,4,5,6],[7,8,9,10,11,12],[17,18,13,14,15,16],[19,20,21,22,23,24]]    (13→15→17→13 and 14→16→18→14 as 3-cycles)
F3A           [[1,2,3,4,5,6],[7,8,9,10,11,12],[15,16,17,18,13,14],[19,20,21,22,23,24]]    (13→17→15→13 and 14→18→16→14 as 3-cycles)
F4C           [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[23,24,19,20,21,22]]    (19→21→23→19 and 20→22→24→20 as 3-cycles)
F4A           [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[21,22,23,24,19,20]]    (19→23→21→19 and 20→24→22→20 as 3-cycles)
C1C           [[1,8,9,4,5,6],[7,16,13,10,11,12],[3,14,15,2,17,18],[19,20,21,22,23,24]]    (2→16→8→2 and 3→13→9→3 as 3-cycles)
C1A           [[1,16,13,4,5,6],[7,2,3,10,11,12],[9,14,15,8,17,18],[19,20,21,22,23,24]]    (2→8→16→2 and 3→9→13→3 as 3-cycles)
C2C           [[17,2,3,4,5,14],[7,8,9,10,11,12],[13,24,15,16,19,18],[1,20,21,22,23,6]]    (1→19→17→1 and 6→24→14→6 as 3-cycles)
C2A           [[19,2,3,4,5,24],[7,8,9,10,11,12],[13,6,15,16,1,18],[17,20,21,22,23,14]]    (1→17→19→1 and 6→14→24→6 as 3-cycles)
C3C           [[1,2,3,20,21,6],[5,8,9,10,11,4],[13,14,15,16,17,18],[19,12,7,22,23,24]]    (4→12→20→4 and 5→7→21→5 as 3-cycles)
C3A           [[1,2,3,12,7,6],[21,8,9,10,11,20],[13,14,15,16,17,18],[19,4,5,22,23,24]]    (4→20→12→4 and 5→21→7→5 as 3-cycles)
C4C           [[1,2,3,4,5,6],[7,8,9,22,23,12],[13,14,11,16,17,10],[19,20,21,18,15,24]]    (10→18→22→10 and 11→15→23→11 as 3-cycles)
C4A           [[1,2,3,4,5,6],[7,8,9,18,15,12],[13,14,23,16,17,22],[19,20,21,10,11,24]]    (10→22→18→10 and 11→23→15→11 as 3-cycles)
E1            [[13,14,3,4,5,6],[7,8,9,10,11,12],[1,2,15,16,17,18],[19,20,21,22,23,24]]    (1↔13 and 2↔14 as swaps)
E2            [[1,2,7,8,5,6],[3,4,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]    (3↔7 and 4↔8 as swaps)
E3            [[1,2,3,4,5,6],[7,8,15,16,11,12],[13,14,9,10,17,18],[19,20,21,22,23,24]]    (9↔15 and 10↔16 as swaps)
E4            [[1,2,3,4,19,20],[7,8,9,10,11,12],[13,14,15,16,17,18],[5,6,21,22,23,24]]    (5↔19 and 6↔20 as swaps)
E5            [[1,2,3,4,5,6],[7,8,9,10,21,22],[13,14,15,16,17,18],[19,20,11,12,23,24]]    (11↔21 and 12↔22 as swaps)
E6            [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,23,24],[19,20,21,22,17,18]]    (17↔23 and 18↔24 as swaps)
\$\endgroup\$
  • \$\begingroup\$ Can we return by modifying the input state? \$\endgroup\$ – TFeld Jan 4 at 9:46
  • \$\begingroup\$ @TFeld Yes. It's also stated in the rules (although only very briefly): "I/O is flexible. Input move can be a string, character-array, etc. (You are not allowed to take the input as a list of codepoints, unless you language does this implicitly.) Output can be a 2D array/list, can modify the optional input 2D array/list, can be a string, etc." \$\endgroup\$ – Kevin Cruijssen Jan 4 at 9:50
2
\$\begingroup\$

Python 2, 384 362 359 344 337 313 bytes

def f((a,b,c),I):
 b=int(b)-1;q=b==1;Q=b==2;j=ord(c)%63;A=b|1+4*q;C=A-5*q;F=2-Q;G=b%2*(b^2);H=C+2-q;J=b%2+G
 if'E'<a:G=F=C=b;A,B,H,J=range(4)
 if'E'==a:j=3;G=b%3-q-Q;A=b+b%2-b/5*2;C=F=(b/3)|2-q;J=G*2;H=J-4
 q,w,e=I[G],I[F],I[C];X=q[A],q[A-5],w[H],w[J],e[J-5],e[J-4];q[A],q[A-5],w[H],w[J],e[J-5],e[J-4]=X[j:]+X[:j]

Try it online!

Takes input with a trailing C/A for every move.

Modifies the input list in-place


Explanation:

First we identify which faces are moved, depending on the move (faces that don't move are blank):

F1C [[ 1, 2, 3, 4, 5, 6], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[ 5, 6, 1, 2, 3, 4], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]
F1A [[ 1, 2, 3, 4, 5, 6], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[ 3, 4, 5, 6, 1, 2], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]
F2C [[  ,  ,  ,  ,  ,  ], [ 7, 8, 9,10,11,12], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [11,12, 7, 8, 9,10], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]
F2A [[  ,  ,  ,  ,  ,  ], [ 7, 8, 9,10,11,12], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [ 9,10,11,12, 7, 8], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]
F3C [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [13,14,15,16,17,18], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [17,18,13,14,15,16], [  ,  ,  ,  ,  ,  ]]
F3A [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [13,14,15,16,17,18], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [15,16,17,18,13,14], [  ,  ,  ,  ,  ,  ]]
F4C [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [19,20,21,22,23,24]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [23,24,19,20,21,22]]
F4A [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [19,20,21,22,23,24]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [21,22,23,24,19,20]]
                                                                                           ->   
C1C [[  , 2, 3,  ,  ,  ], [  , 8, 9,  ,  ,  ], [13,  ,  ,16,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[  , 8, 9,  ,  ,  ], [  ,16,13,  ,  ,  ], [ 3,  ,  , 2,  ,  ], [  ,  ,  ,  ,  ,  ]]
C1A [[  , 2, 3,  ,  ,  ], [  , 8, 9,  ,  ,  ], [13,  ,  ,16,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,16,13,  ,  ,  ], [  , 2, 3,  ,  ,  ], [ 9,  ,  , 8,  ,  ], [  ,  ,  ,  ,  ,  ]]
C2C [[ 1,  ,  ,  ,  , 6], [  ,  ,  ,  ,  ,  ], [  ,14,  ,  ,17,  ], [19,  ,  ,  ,  ,24]]   ->   [[17,  ,  ,  ,  ,14], [  ,  ,  ,  ,  ,  ], [  ,24,  ,  ,19,  ], [ 1,  ,  ,  ,  , 6]]
C2A [[ 1,  ,  ,  ,  , 6], [  ,  ,  ,  ,  ,  ], [  ,14,  ,  ,17,  ], [19,  ,  ,  ,  ,24]]   ->   [[19,  ,  ,  ,  ,24], [  ,  ,  ,  ,  ,  ], [  , 6,  ,  , 1,  ], [17,  ,  ,  ,  ,14]]
C3C [[  ,  ,  , 4, 5,  ], [ 7,  ,  ,  ,  ,12], [  ,  ,  ,  ,  ,  ], [  ,20,21,  ,  ,  ]]   ->   [[  ,  ,  ,20,21,  ], [ 5,  ,  ,  ,  , 4], [  ,  ,  ,  ,  ,  ], [  ,12, 7,  ,  ,  ]]
C3A [[  ,  ,  , 4, 5,  ], [ 7,  ,  ,  ,  ,12], [  ,  ,  ,  ,  ,  ], [  ,20,21,  ,  ,  ]]   ->   [[  ,  ,  ,12, 7,  ], [21,  ,  ,  ,  ,20], [  ,  ,  ,  ,  ,  ], [  , 4, 5,  ,  ,  ]]
C4C [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,10,11,  ], [  ,  ,15,  ,  ,18], [  ,  ,  ,22,23,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,22,23,  ], [  ,  ,11,  ,  ,10], [  ,  ,  ,18,15,  ]]
C4A [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,10,11,  ], [  ,  ,15,  ,  ,18], [  ,  ,  ,22,23,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,18,15,  ], [  ,  ,23,  ,  ,22], [  ,  ,  ,10,11,  ]]
                                                                                           ->   
E1  [[ 1, 2,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [13,14,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[13,14,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [ 1, 2,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]
E2  [[  ,  , 3, 4,  ,  ], [ 7, 8,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,  , 7, 8,  ,  ], [ 3, 4,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ]]
E3  [[  ,  ,  ,  ,  ,  ], [  ,  , 9,10,  ,  ], [  ,  ,15,16,  ,  ], [  ,  ,  ,  ,  ,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,15,16,  ,  ], [  ,  , 9,10,  ,  ], [  ,  ,  ,  ,  ,  ]]
E4  [[  ,  ,  ,  , 5, 6], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [19,20,  ,  ,  ,  ]]   ->   [[  ,  ,  ,  ,19,20], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [ 5, 6,  ,  ,  ,  ]]
E5  [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,11,12], [  ,  ,  ,  ,  ,  ], [  ,  ,21,22,  ,  ]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,21,22], [  ,  ,  ,  ,  ,  ], [  ,  ,11,12,  ,  ]]
E6  [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,17,18], [  ,  ,  ,  ,23,24]]   ->   [[  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,  ,  ], [  ,  ,  ,  ,23,24], [  ,  ,  ,  ,17,18]]

These faces are mapped to their index:

F1C [0,0], [0,1], [0,2], [0,3], [0,4], [0,5]   ->   [0,2], [0,3], [0,4], [0,5], [0,0], [0,1]
F1A [0,0], [0,1], [0,2], [0,3], [0,4], [0,5]   ->   [0,1], [0,2], [0,3], [0,4], [0,5], [0,0]
F2C [1,0], [1,1], [1,2], [1,3], [1,4], [1,5]   ->   [1,2], [1,3], [1,4], [1,5], [1,0], [1,1]
F2A [1,0], [1,1], [1,2], [1,3], [1,4], [1,5]   ->   [1,1], [1,2], [1,3], [1,4], [1,5], [1,0]
F3C [2,0], [2,1], [2,2], [2,3], [2,4], [2,5]   ->   [2,2], [2,3], [2,4], [2,5], [2,0], [2,1]
F3A [2,0], [2,1], [2,2], [2,3], [2,4], [2,5]   ->   [2,1], [2,2], [2,3], [2,4], [2,5], [2,0]
F4C [3,0], [3,1], [3,2], [3,3], [3,4], [3,5]   ->   [3,2], [3,3], [3,4], [3,5], [3,0], [3,1]
F4A [3,0], [3,1], [3,2], [3,3], [3,4], [3,5]   ->   [3,1], [3,2], [3,3], [3,4], [3,5], [3,0]

C1C [0,1], [0,2], [2,3], [2,0], [1,1], [1,2]   ->   [2,3], [2,0], [1,1], [1,2], [0,1], [0,2]
C1A [0,1], [0,2], [2,3], [2,0], [1,1], [1,2]   ->   [0,2], [2,3], [2,0], [1,1], [1,2], [0,1]
C2C [3,5], [3,0], [2,1], [2,4], [0,5], [0,0]   ->   [2,1], [2,4], [0,5], [0,0], [3,5], [3,0]
C2A [3,5], [3,0], [2,1], [2,4], [0,5], [0,0]   ->   [3,0], [2,1], [2,4], [0,5], [0,0], [3,5]
C3C [0,3], [0,4], [1,5], [1,0], [3,1], [3,2]   ->   [1,5], [1,0], [3,1], [3,2], [0,3], [0,4]
C3A [0,3], [0,4], [1,5], [1,0], [3,1], [3,2]   ->   [0,4], [1,5], [1,0], [3,1], [3,2], [0,3]
C4C [1,3], [1,4], [2,5], [2,2], [3,3], [3,4]   ->   [2,5], [2,2], [3,3], [3,4], [1,3], [1,4]
C4A [1,3], [1,4], [2,5], [2,2], [3,3], [3,4]   ->   [1,4], [2,5], [2,2], [3,3], [3,4], [1,3]

E1  [0,0], [0,1], [2,2], [2,0]                 ->   [2,2], [2,0], [0,0], [0,1]
E2  [0,2], [0,3], [1,2], [1,0]                 ->   [1,2], [1,0], [0,2], [0,3]
E3  [1,2], [1,3], [2,4], [2,2]                 ->   [2,4], [2,2], [1,2], [1,3]
E4  [0,4], [0,5], [3,2], [3,0]                 ->   [3,2], [3,0], [0,4], [0,5]
E5  [1,4], [1,5], [3,4], [3,2]                 ->   [3,4], [3,2], [1,4], [1,5]
E6  [2,4], [2,5], [3,0], [3,4]                 ->   [3,0], [3,4], [2,4], [2,5]

All indices are swapped in pairs (eg. F1C has (0,0-1),(0,2-3),(0,4-5) swapped to (0,2-3),(0,4-5),(0,0-1)). Each pair of moves that uses A/C also has the same pairs swapped, only in opposite directions.

This means that the moves F1C and F1A move the same pairs, but in opposite directions. IE C: abcdef -> cdefab and A: abcdef -> efabcd.

This gives us the values of j, which is used to slice the list of indices being moved. abcdef -> [abcedf][:j] + [abcdef][:j].

IE: C: j=2, abcdef -> [abcdef][2:]+[abcdef][:2] = cdef+ab and A: j=4, abcdef -> [abcdef][4:]+[abcdef][:4] = ef+abcd

For moves with E, we only swap two pairs. This is done by setting j to 3: abcdef -> [abcdef][3:]+[abcdef][:3] = def+abc. By mapping the pairs that we want to swap to ab and de, and setting candf to the same, this works.

Finally we need to calculate all these indeces as shown in the second list.

By naming each value to as follow (names are a bit random, but what came from golfing):

[G,A], [G,B], [F,H], [F,J], [C,D], [C,E] -> ...

We get the following lists for each variable (also introducing b as x-1):

FxA/C:                               CxA/C:                               Ex:
x b  G  A  B  F  H  J  C  D  E       x b  G  A  B  F  H  J  C  D  E       x b  G  A  B  F  H  J  C  D  E
1 0  0, 0, 1, 0, 2, 3, 0, 4, 5       1 0  0, 1, 2, 2, 3, 0, 1, 1, 2       1 0  0, 0, 1, 2, 2, 0, 2, 1, 2
2 1  1, 0, 1, 1, 2, 3, 1, 4, 5       2 1  3, 5, 0, 2, 1, 4, 0, 5, 0       2 1  0, 2, 3, 1, 2, 0, 1, 1, 2
3 2  2, 0, 1, 2, 2, 3, 2, 4, 5       3 2  0, 3, 4, 1, 5, 0, 3, 1, 2       3 2  1, 2, 3, 2, 4, 2, 2, 3, 4
4 3  3, 0, 1, 3, 2, 3, 3, 4, 5       4 3  1, 3, 4, 2, 5, 2, 3, 3, 4       4 3  0, 4, 5, 3, 2, 0, 3, 1, 2
                                                                          5 4  1, 4, 5, 3, 4, 2, 3, 3, 4
                                                                          6 5  2, 4, 5, 3, 0, 4, 3, 5, 0

All these numbers are then calculated for the current move.

A few dependencies can be seen:

D = (J+1)%6      (equal to J-5, because negative index wraps arund)
E = (J+2)%6      (equal to J-4, .. )
B = (A+1)%6      (equal to A-5, .. )

Which means that we need to calculate the following numbers:

b   0123    0123    012345
    F       C       E
A   0000    1533    022444
C   0123    1033    212333
F   0123    2212    212333
G   0123    0301    001012
H   2222    3155    224240
J   3333    0402    002024

Now all we have to do is golf all of these sequences based on the move...

Introducing two numbers (q: b==1, Q: b==2) we then have:

    F       C           E
A   0       b|1+4*q     b+b%2-b/5*2
C   b       A-5*q       (b/3)|2-q
F   b       2-Q         C
G   b       b%2*(b^2)   b%3-q-Q
H   2       C+2-q       J-4 (also (J+2)%6)
J   3       b%2+G       G*2

j   2/4     2/4         3

All of these are then used to modify the input list, by assigning the indices to themselves, but reordered.

\$\endgroup\$
  • \$\begingroup\$ I'm not sure why it works, because I barely understand your magic number calculations (I hope you could add an explanation after you've fully golfed it), but you can save 4 bytes by changing D=A-2*Q;E=-~D%6; to E=(A-2*Q+1)%6;, remove ;D=J+1 at the end of the first if-block, and changing both e[D] to e[J+1] in the else-block. \$\endgroup\$ – Kevin Cruijssen Jan 4 at 14:22
  • 1
    \$\begingroup\$ @KevinCruijssen Thanks :) I'll try to write up an explanation soon \$\endgroup\$ – TFeld Jan 4 at 14:37
  • 1
    \$\begingroup\$ @KevinCruijssen Phew, writeup done.. I hope it makes sense :) \$\endgroup\$ – TFeld Jan 7 at 8:26
2
\$\begingroup\$

Ruby, 332 324 bytes

->m,a{g=->x,y,z{"7KN=)&L]idSGWCaf>M!$3?<-".bytes.index x*16+y*4+z+69}
m=m.hex;q=(t=m%16<8)?m%8/4+3:m/16%26-7
(r=[*-2..2]).product(r,r).map{|i|n=g[*i]
d=0
6.times{|j|d+=(i[j%3]*=(26564818>>j%3*8+q&2)-1)**2
j==2&&(t ?i[-k=m%4]>1&&(i[1-k]*=-1;i[2-k]*=-1):i.max<1&&i.rotate!(m%8*((22>>q&2)-1)))}
h=g[*i]
d==10&&a[h/6][h%6]=n}
a}

Try it online!

Takes input as a string, which it then interprets as a hexadecimal number. If it is acceptable to take input as an integer, that would save 8 bytes.

Originally developed to output a 0 indexed 1 dimensional array. On re-reading the spec a 2D array is required, so the solved array is used as a dummy template to be filled with data (the structure is used but none of the data within it is.) Output is 0 indexed; it can be made 1 indexed by changing the second last line to d==10&&a[h/6][h%6]=n+1}

Explanation

A reshaping of the puzzle pieces yields a cubic puzzle. The faces of the tetrahedron are built up with triangular pyramids whose sides are 90 degree isosceles triangles. The edges of the original tetrahedron become diagonals on the faces of the cube. See image of partially unfolded cube, showing the numbers and the positive directions for the x,y and z axes.

A rotation of an edge of the tetrahedron corresponds with a rotation of a face of the cube. A rotation of a corner or face of the tetrahedron corresponds with a rotation of a corner of the cube. The numbers of the edges of the tetrahedron become the numbers of the faces of the cube, and the numbers of the corners and faces of the tetrahedron become those of the corners of the cube.

enter image description here

In the code, each piece has a coordinate which is a permutation of [+/-2,+/-1,0] where the coordinate of magnitude 2 corresponds to the face and the other coordinates correspond to the position on the face. The function generates all possible x,y,z coordinates in the range -2..2 and acts only on those where the square of the euclidean distance is 5. For each set of coordinates that is kept, it looks up (using helper function g) the piece number which corresponds to the coordinates and saves it to n. It then modifies the coordinates (if required) according to the move. Finally it looks up the the number which corresponds to the modified coordinates and saves the value of n to the corresponding cell of the array. Once it has processed all 24 valid sets of coordinates it returns the fully populated array.

Commented code

->m,a{                                                          #Input the moves as a string (and the array which we only use as a structure template)
g=->x,y,z{"7KN=)&L]idSGWCaf>M!$3?<-".bytes.index x*16+y*4+z+69} #Helper function to convert native coordinates to the ones required by the question
m=m.hex                                                         #Convert input to an integer. If the last digit is 0..6 (not A or C) t=true.
q=(t=m%16<8)?m%8/4+3:m/16%26-7                                  #If t false q=0..7 to flip correct axes for the particular F# or C# move. If t true q =3 or 4 (flip all or no axes for E# move.)
(r=[*-2..2]).product(r,r).map{|i|                               #Iterate i=[x,y,z] for values in range -2..2 . For each set of coordinates...
n=g[*i]                                                         #Fetch the value from the array (returns nil without errors if coordinates invalid) 
d=0                                                             #Initialize a counter to check for valid coordinates (x*x+y*y+z*z)*2=10
6.times{|j|                                                     #Iterate through all three axes (twice, so that flipped axes get unflipped again)
d+=(i[j%3]*=(26564818>>j%3*8+q&2)-1)**2                         #Flip axis j%3 according to the value of q (use magic number to lookup whether to flip or not.) Add coordinate squared to d.              
j==2&&                                                          #If this is the 3rd iteration, flips are in correct state to perform the move, so do something.
  (t ?i[-k=m%4]>1&&(i[1-k]*=-1;i[2-k]*=-1):                     #For E#, if the coordinate in axis -k=m%4 is +2 rotate 180 by flipping the other two axes. 
  i.max<1&&i.rotate!(m%8*((22>>q&2)-1)))}                       #For F# or C# if all axes 0 or less, rotate by permuting axes in direction determined by m%8 (A/C) & magic number 22
h=g[*i]                                                         #h = index to store the value in after carrying out move
d==10&&a[h/6][h%6]=n}                                           #If d=(x*x+y*y+z*z)*2=10 coordinates are valid. Store the value in the array according to index h.
a}                                                              #Return array a
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.