title: Execute Triangularity Move

text:
# Question
Title: Execute Triangularity Move
*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:
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)

```

# Answer
# 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 `c`and`f` 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.
> 3 votes

# Answer
# 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.

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

```
> 3 votes

---
Tags: code-golf, array, rubiks-cube
---


title: Fridge magnet substitution

text:
# Question
Title: Fridge magnet substitution
When writing a message with fridge magnets, you'll often find yourself substituting a `1` for an `I`. In this challenge, your goal is to find out if a message can be written using the letters of another message. The allowed substitutions are:

```
A = 4
B = 8
C = U
E = M = W = 3
G = 6 = 9
I = 1
L = 7
N = Z
O = 0
R = 2
S = 5

```

For example, the message `CIRCA 333` can be rearranged to spell `ICE CREAM`, where the first two `3`s are rotated 180 degrees to make two `E`s, and the last `3` is rotated 90 degrees counterclockwise to make an `M`. Whitespaces can be included in the messages, but they should not be accounted for in your solution, as they're made by placing the magnets on the fridge.

## Input

Two strings (or character arrays). All messages will match `^[A-Z0-9 ]+$`

## Output

Truthy if the two input strings are valid rearrangements of each other, falsey otherwise.

## Examples

```
["CIRCA 333", "ICE CREAM"] => true
["DCLV 00133", "I LOVE CODE"] => true
["WE ARE EMISSARIES", "33   423    3315542135"] => true
["WE WANT ICE CREAM", "MET CIRCA 334 MEN"] => true
["I HAVE ICE CREAM", "HAVE 2 ICE CREAMS"] => false

```

## More thruthy examples

These are all the 15+ letter words that map to another word. Some are trivial substitutions, but I included all that I found.

```
["ANTHROPOMORPHISE","ANTHROPOMORPHISM"]
["ANTIPHILOSOPHIES","ANTIPHILOSOPHISM"]
["CIRCUMSTANTIALLY","ULTRAMASCULINITY"]
["DECENTRALIZATION","DENEUTRALIZATION"]
["DIMETHYLNITROSAMINE","THREEDIMENSIONALITY"]
["INSTITUTIONALISE","INSTITUTIONALISM"]
["INTERCRYSTALLINE","INTERCRYSTALLIZE"]
["INTERNATIONALISE","INTERNATIONALISM"]
["OVERCENTRALIZATION","OVERNEUTRALIZATION"]
["OVERCENTRALIZING","OVERNEUTRALIZING"]
["PREMILLENNIALISE","PREMILLENNIALISM"]
["TRANSCENDENTALIZE","TRANSCENDENTALIZM"]

```

As this is a code golf challenge, the shortest solution wins! I will accept the shortest solution in 7 days from posting. Happy golfing!

Sample solution, non-golfed

## Related

**EDIT**: Made an error in the substitutions, had `G = 6` and `6 = 9` as separate substitutions, merged them into one.

# Answer
# Japt, ~~38~~ ~~36~~ ~~33~~ 30 bytes

Takes input as an array of 2 strings.

```
®d`z³m`i`oiglbg`í)Ôu)ñ xÃr¶

```

Try it or run all test cases

3 bytes saved thanks to ETHProductions

```
®d`z...m`i`o...g`í)Ôu)ñ xÃr¶
                                 :Implicit input of array U
®                                :Map each Z
 d                               :  For each pair of characters in the following string,
                                 :  replace all occurrences of the 1st character in Z with the 2nd
  `z...m`                        :    The compressed string "znewem"
         i                       :    Prepend
          `o...g`                :      The compressed string "oireasglbg"
                 í               :      Interleave 0-based indices
                  )              :    End prepend
                   Ô             :    Reverse
                    u            :    Convert to uppercase
                     )           :  End replace
                      ñ          :  Sort
                        x        :  Trim
                         Ã       :End map
                          r      :Reduce
                           ¶     :  By testing equality

```
> 4 votes

# Answer
# Python 2, ~~145~~ ~~131~~ ~~130~~ ~~129~~ 125 bytes

```
lambda*a:all(len({sum(map(w.count,x))for w in a})<2for x in'A4 B8 CU EMW3 G69 I1 L7 NZ O0 R2 S5'.split()+list('DFHJKPQTVXY'))

```

Try it online!

Alt:

# Python 2, 125 bytes

```
lambda*a:len({(x,sum(map(w.count,x)))for x in'A4 B8 CU EMW3 G69 I1 L7 NZ O0 R2 S5'.split()+list('DFHJKPQTVXY')for w in a})<23

```

Try it online!
> 10 votes

# Answer
# Ruby, ~~99~~ ~~72~~ 71 bytes

```
->a{!!a.map{|x|x.tr("0-9UZMW","OIREASGLBGCNE").chars.sort-[" "]}.uniq!}

```

Try it online!

Takes an array of strings, assumes input in uppercase as in all test cases.

-1 byte golfed by benj2240.
> 10 votes

# Answer
# JavaScript (ES6), ~~102~~ 100 bytes

Takes input as two arrays of characters in currying syntax `(a)(b)`. Returns a boolean.

```
a=>b=>(g=s=>s.map(c=>'648UD3F6H1JK73Z0PQ25TUV3'[parseInt(c,36)-9]||c).sort().join``.trim())(a)==g(b)

```

Try it online!

### How?

Using the helper function **g()**, for each input **s**:

* Digits **0** to **8** and letters **X**, **Y** and **Z** are left unchanged. Everything else is explicitly translated.

```
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
         ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
.........648UD3F6H1JK73Z0PQ25TUV3...

```

Code:

```
s.map(c => '648UD3F6H1JK73Z0PQ25TUV3'[parseInt(c, 36) - 9] || c)

```
* We sort the characters (which brings all spaces at the beginning), join them and remove all leading whitespace.

Code:

```
.sort().join``.trim()

```

Finally, we compare both outputs.
> 9 votes

# Answer
# Retina 0.8.2, 42 bytes

```
T` dUZMW`_\OIR\EASG\LBGCN\E
%O`.
^(.*)¶\1$

```

Try it online! Takes input on separate lines, but Link includes test cases and header. Explanation:

```
T` dUZMW`_\OIR\EASG\LBGCN\E

```

Map all the letters to a minimal set, deleting the spaces.

```
%O`.

```

Sort each string into order.

```
^(.*)¶\1$

```

Compare the two values.
> 6 votes

# Answer
# APL (Dyalog Unicode), 49 bytesSBCS

-1 thanks to ngn.

Anonymous tacit prefix function.

```
(≡/(⍋⌷¨⊂)¨)(,¨⎕D,'UMWZ ')⎕R('OIREASGLBGCEEN',⊂⍬)

```

Try it online!

`⎕R` PCRE **R**eplace:
`'UMWZ '` these five characters
`⎕D,` preceded by the digits
separately (make each into a string rather than being a single character)
with:
`⊂⍬` nothing
`'OIREASGLBGCEEN',` preceded by these characters

`(``)` apply the following tacit function to that:

`(` apply the following tacit function to each:

enclose it (to treat it as a whole)

`⍋⌷¨` use each of the indices that would sort it to index into the whole string (sorts)

`≡/` are they identical? (lit. match reduction)
> 5 votes

# Answer
# Python 2, 108 bytes

```
lambda a,b:g(a)==g(b)
g=lambda s:sorted('85930A4614012B3C4D5EF6378GH9AI2J3KL7'[int(c,36)]for c in s if'!'<c)

```

Try it online!

There are 23 equivalence classes of characters. Using the 36-character string `'85930A4614012B3C4D5EF6378GH9AI2J3KL7'`, we map each character to its equivalence class (ignoring spaces), then sort the resulting array. Two strings are equivalent iff the resulting lists are equal.
> 5 votes

# Answer
# Java 10, ~~262~~ ~~260~~ ~~258~~ ~~216~~ ~~208~~ 174 bytes

```
a->b->n(a).equals(n(b));String n(String s){return s.chars().mapToObj(x->x<48?"":"OIREASGLBG.......ABCDEFGHIJKLENOPQRSTCVEXYN".split("")[x-48]).sorted().reduce("",(a,b)->a+b);}

```

-2 bytes thanks to *@Arnauld*.
-76 bytes thanks to *@OlivierGrégoire*.

Try it online.

**Explanation:**

```
a->b->                      // Method with two String parameters and boolean return-type
  n(a).equals(n(b))         //  Return if both Strings are equal in the end

String n(String s){         // Separated method with String as both parameter return-type
  return s.chars()          //  Loop over all characters as integers
          .mapToObj(x->x<48?//   If the current character is a space:
             ""             //    Replace it with an empty String to skip it
            :               //   Else:
             "OIREASGLBG.......ABCDEFGHIJKLENOPQRSTCVEXYN".split("")[x-48]
                            //    Convert multi-substitution characters to a single one
          .sorted()         //  Sort all of the converted characters
          .reduce("",(a,b)->a+b);}
                            //  And join all of them together as single String

```
> 4 votes

# Answer
# , 123 bytes

```
function(x,y=chartr("48UMW36917Z025","ABCEEEGGILNORS",gsub(" ","",x)))all(g(y[1])==g(y[2]))
g=function(z)sort(utf8ToInt(z))

```

Try it online!

`utf8ToInt` converts a string into a vector of Unicode code points.

~~`!sd(a-b)` is one byte shorter than `all(a==b)`~~ but that doesn't help here because I'm actually dealing with integers and not logicals.
> 3 votes

# Answer
# , 56 bytes

```
-:&(-.&' '/:~@rplc'0123456789UMWZ';"0'OIREASGLBGCEEN'"1)

```

Try it online!

## Explanation:

`&` for both left and right arguments

`-.&' '` removes spaces from the input,

`rplc` replaces

`'0123456789UMWZ';"0'OIREASGLBGCEEN'"1` the characters in the input by substitution of the chars in the left column with the ones in the right one: (here transposed for saving space)

```
      |:'0123456789UMWZ';"0'OIREASGLBGCEEN'
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│0│1│2│3│4│5│6│7│8│9│U│M│W│Z│
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│O│I│R│E│A│S│G│L│B│G│C│E│E│N│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

```

`/:~@` and sorts the resulting strings

`-:` are the sorted strings equal?

## My initial solution:

# , 77 73 bytes

```
-:&(1#.(' '-.~])e."1[:(,a.,.@-.,)'EMW3','G69',9 2$'A4B8CUI1L7NZO0R2S5'"1)

```

Try it online!

## Explanation:

`(' '-.~])` removes spaces from both arguments and

`e."1` tests each character for membership in the follwing table:

`[:(,a.,.@-.,)'EMW3','G69',9 2$'A4B8CUI1L7NZO0R2S5'"1` the reference:

```
EMW3
G69
A4
B8
CU
I1
L7
NZ
O0
R2
S5
.
.
.
All other symbols one in a row

```

`1#.` adds up the comparison tables for each argument

`-:&` do they match?
> 2 votes

# Answer
# Jelly, ~~39~~ 34 bytes

```
ØB“¡Œ5a`@ẓRɼ9ẓ“%-/İ"aU5®’ṃyḟ⁶ṢɗⱮ⁸E

```

Try it online!
> 2 votes

# Answer
# Perl 6, 55 bytes

```
{[eq] .map:{sort TR/0..9UZMW/OIREASGLBGCNEE/~~m:g/\S/}}

```

Try it online!

Works with an arbitrary number of strings.
> 2 votes

# Answer
# Python 2, 111 bytes

```
lambda*t:2>len({`sorted(s.translate(dict(map(None,map(ord,'48UMW36917Z025 '),u'ABCEEEGGILNORS'))))`for s in t})

```

Try it online!

# 116 bytes

```
lambda a,b:g(a)==g(b)
g=lambda s,y='4A8BUCMEWE3E6G9G1I7LZN0O2R5S ':y and g(s.replace(y[0],y[1:2]),y[2:])or sorted(s)

```

Try it online!
> 2 votes

# Answer
# Python 3, 105 bytes

```
lambda a,b:X(a)==X(b)
X=lambda s:sorted(("ABCEEEGGILNORS"+c)["48UMW36917Z025".find(c)]for c in s if' '<c)

```

Try it online!
> 2 votes

# Answer
# 05AB1E, ~~38~~ 33 bytes

```
εðK.•2Θ`ĆĀÑεÉ•u6«•B/óÕ¦•…CN9«‡{}Ë

```

Try it online or verify all test cases.

**Explanation:**

```
ε                   # Map each value in the (implicit) input-list by:
 ðK                 #  Remove all spaces
   .•2Θ`ĆĀÑεÉ•      #  Push compressed string "abemwgilorsuz"
              u     #  To uppercase: "ABEMWGILORSUZ"
               6«   #  Append a 6: "ABEMWGILORSUZ6"
   •B/óÕ¦•          #  Push compressed integer 48333917025
          …CN9«     #  Append "CN9": "48333917025CN9"
   ‡                #  Transliterate; map all characters in "ABEMWGILORSUZ" in the
                    #  map-string to "48333917025CN9" at the same indices
    {               #  Then sort all characters
}                   # Close the map
 Ë                  # And check if both are equal (which is output implicitly)

```

See this 05AB1E tip of mine (sections *How to compress strings not part of the dictionary?* and *How to compress large integers?*) to understand why `.•2Θ`ĆĀÑεÉ•` is `"abemwgilorsuz"` and `•B/óÕ¦•` is `48333917025`.
> 1 votes

---
Tags: code-golf, string, decision-problem, substitution
---


title: Legalize Reversed Date

text:
# Question
Title: Legalize Reversed Date
**Input:**

A Date (containing `dd`, `MM` and `yyyy`). A date-object, or three separate integers are also valid as input.

**Output:**

Each part (`dd`, `MM` and `yyyy`) individually reverted and than rounded to the nearest valid date.

For example (in the format `dd-MM-yyyy`):
`21-10-2016` becomes `12-01-6102`

**Challenge rules:**

* Only `dd`, `MM`, `yyyy` is valid, but the order and which separate-symbols you use is your own choice.
So these are some valid format examples: `dd-MM-yyyy`; `MM/dd/yyyy`; `yyyy MM dd`; `ddMMyyyy`, etc.
And these are some invalid format examples: `dd MMM yyyy`; `dd-MM-'yy`; etc.
* You can also choose to just input a Date-object if your language supports it or three separate integer parameters, instead of the string representing a date.
* **Please state which date-format you've used!** (And the input and output must be in the same format.) It is also allowed to output a Date-object, as long as it can handle all test cases and the challenge rule below.
* The Julian to Gregorian Calendar transition is ignored for this challenge. So `1582` is just a valid reversed year for `2851`.
See Challenge info / tips for all valid years, months and days.
* Since you cannot have February as reversed of any other month, you don't have to worry about leap years.

**All reversed years, months and days:**

* The year can always be reversed without a problem, reaching from **0001** (reversed of `1000`) to **9999** (remains `9999`). (So `0000` isn't a valid input, and there are also no test cases for it.)
* The only months you'll have reversed are: **January** (reversed from October / `10`); **October** (reversed from January / `01`); **November** (remains November / `11`); and **December** (reversed from every other month / `02`-`09`, `12`).
* The only days you'll have reversed are: **01** (reversed from `10`), **02** (reversed from `20`), **03** (reversed from `30`), **10** (reversed from `01`), **11** (remains `11`), **12** (reversed from `21`), **13** (reversed from `31`), **20** (reversed from `02`), **21** (reversed from `12`), **22** (remains `22`), **30** (reversed from `03` or the same as *31* for November!), **31** (reversed from `04`-`09` / `13`-`19` / `23`-`29`).

**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, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return statements/output, full programs. Your call.
* Default Loopholes are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation if necessary.

**Test cases (`dd-MM-yyyy` as format):**

```
21-07-2016   ->   12-12-6102
12-11-1991   ->   21-11-1991
01-01-2000   ->   10-10-0002
27-08-1875   ->   31-12-5781
18-12-2010   ->   31-12-0102
13-01-1981   ->   31-10-1891
04-11-1671   ->   30-11-1761  // Semi-tricky case, since November has 30 days
28-11-2036   ->   30-11-6302  // Semi-tricky case, since November has 30 days
14-06-1855   ->   31-12-5581
30-10-9999   ->   03-01-9999
01-01-2851   ->   10-10-1582

```

# Answer
## Convex, 23 bytes

Byte count assumes CP-1252 encoding.

```
qS/Wf%_1=:=31^sCs¶.e<S*

```

I/O format is `dd mm yyyy`.

Try it online!

This is a direct port of my CJam answer. Convex is heavily based on CJam, and therefore the only difference is the use of Convex's  operator which wraps the top two stack elements in a list, saving a byte over `[...]`.
> 3 votes

# Answer
## CJam, 24 bytes

```
qS/Wf%[_1=:=31^sCs].e<S*

```

I/O format is `dd mm yyyy`.

Try it online!

Same byte count, I/O format `mm dd yyyy`:

```
qS/Wf%_0=:=1231^s2/.e<S*

```

Try it online!

### Explanation

```
qS/     e# Read input, split around spaces.
Wf%     e# Reverse each component.
[       e# Set marker for new list.
  _1=   e#   Duplicate reversed strings, extract reversed month.
  :=    e#   Check for equality of the characters. This gives 1 for
        e#   November (11) and 0 for everything else.
  31^   e#   XOR the result with 31, giving 30 for November and 31
        e#   for everything else.
  s     e#   Convert the result to a string, "30"/"31".
  Cs    e#   Push 12, convert to string, "12".
]       e# Wrap "30"/"31" and "12" in a list.
.e<     e# Element-wise minimum. This clamps the day and month to their
        e# respective maxima.
S*      e# Join the result with spaces.

```

The other version works similarly, except that we start from the integer `1230` or `1231` before converting it to `["12" "30"]` or `["12" "31"]`.
> 8 votes

# Answer
# Pyth, ~~55~~ ~~53~~ ~~46~~ ~~43~~ 41 bytes

```
~~APJ_Mczd=HhS,12sH=GhS,sGC@."❤❤ó»î"H%"%02d %02d %s"[GHeJ~~
~~APJ_Mczd=hS,12sH=hS,sGC@."❤❤ó»î"H%"%02d %02d %s"[GHeJ~~
~~APJ_Mcz\-%"%02d %02d %s"[hS,sGx31q11sHhS,12sHeJ~~
~~APJ_Mczdjd[>2+\0hS,sGx31q11sH>2+\0hS,12sHeJ~~
APJ_Mczdjd.[L\02[`hS,sGx31q11sH`hS,12sHeJ

```

where `❤❤` were two unprintables, respectively U+001C and U+001F.

Test suite.
> 5 votes

# Answer
# Dyalog APL, ~~32~~ 33 bytes

```
⍕¨{⍵-3↑31 11≡2↑⍵}31 12 1E4⌊⍎∊⍕⌽¨⎕

```

I/O is list of three strings (`'dd' 'mm' 'yyyy'`).

TryAPL, but note that  (prompt for input) has been replaced with  and the entire line enclosed in `{`...`}` to enable online testing, and  (execute expression) has been replaced with `2⊃⎕VFI` (verify and fix input) because execution of arbitrary code is blocked.
> 2 votes

# Answer
# Python 3, 82 bytes

```
lambda x:[min(x[0][::-1],['31','30'][x[1]=='11']),min(x[1][::-1],'12'),x[2][::-1]]

```

An anonymous function that takes input, via argument, of the date as a list of strings of the form `['dd', 'mm', 'yyyy']` and returns the validated reversed date in the same format.

**How it works**

Python compares characters and strings by their Unicode code-points. This means that any comparison on two or more integers returns the same as that comparison on those integers as strings. Hence, calling `min` on two integers as strings returns the smallest integer as a string; by taking the reversed date-part as one argument and the maximum value as another, the day and month are clamped to the desired range. The date-parts are reversed by indexing with steps of `-1` (`[::-1]`), and the maximum value for the month is changed from `'31'` to `'30'` if the month is November by indexing into a list with the Boolean result of a conditional.

Try it on Ideone
> 2 votes

# Answer
# C# ~~314~~ ~~305~~ ~~299~~ ~~249~~ ~~232~~ 223 Bytes

```
using System.Linq;string f(int d,int m,int y){Func<int,string>r=i=>string.Concat((""+i).PadLeft(2,'0').Reverse());Func<string,int,string>x=(j,k)=>int.Parse(j)>k?""+k:j;return x(r(d),m==11?30:31)+"-"+x(r(m),12)+"-"+r(y);}

```

Thanks to @KevinCruijssen for pointing out that I could shorten my variable declaration, which also made aliasing string able to save some bytes.

Saved 50 bytes storing the reversing function for reuse and another 13 by doing the same for the rounding and removing the variable declarations.

Last update makes aliasing string no longer a byte saver.

### Ungolfed Version:

```
using System.Linq;
    string dateReverse(int day, int month, int year)
{
    //setup a resuable function to reverse
    Func<int, string> reverse = intToReverse => string.Concat((""+intToReverse).PadLeft(2, '0').Reverse());

    //another function for rounding
    Func<string, int, string> round = (strToRound, maxVal) => int.Parse(strToRound) > maxVal ? "" + maxVal : strToRound;

    //Join the strings into the "dd-mm-yyyy" date format
    return
        //Round down the day value, if november cap to 30 otherwise cap to 31
        round(reverse(day), month == 11 ? 30 : 31) + "-" +

        //Round the month down
        round(reverse(month), 12) + "-" +

        //we can use the reverse function here too and pad left just won't do anything
        reverse(year);
}

```

Test it here
> 2 votes

# Answer
# Javascript, ~~106~~ ~~105~~ 94 bytes

```
d=>d.split`,`.map((a,b,r)=>(e=[...a].reverse().join``,f=!b?r[1]==11^31:b<2&&12,f&&f<e?f:e))+''

```

Test suite (rev. 3)

**Explanation**

```
d=>d.split`,`                 // split into sections by `,`

.map((a,b,r)=>(               // map each section

e=[...a].reverse().join``,    // spread a date section into array and reverse and
                              // join with `` to get string result

f=!b?r[1]==11^31              // if section being mapped is day (section 0),
                              // then max (f) is 30 for November(month 11) or else 31

:b<2&&12,                     // if part being mapped is month (section 1), then max (f) is 12

f&&f<e?f:e))                  // if there is a max (f)
                              // and the max (f) is less than the reversed string (e),
                              // then return the max (f),
                              // else return the reversed string (e)

+''                           // join all the sections back together with `,`
                              // (concatenating [] with a string will do this)

```

Thanks @KevinCruijssen for saving 1 byte for `b==1` to `b<2`. Thanks @Neil for saving 11 bytes by suggesting ES6 template literal and `,` separator.
> 1 votes

# Answer
# Ruby, ~~92~~ 84 + 1 (`-p` flag) = ~~93~~ 85 bytes

Uses `-` as the seperator.

```
d,m,y=chomp.split(?-).map &:reverse
$_=[[d,m=="11"?"30":"31"].min,[m,"12"].min,y]*?-

```
> 1 votes

# Answer
## Pyke, 29 bytes

```
F_bw-o^tDI]SX(mhj_Xjth~%R@]Sh

```

Try it here!

I can definitely see this being golfable
> 1 votes

# Answer
## Python 2, 154 bytes

```
z=input().split("-");r=[x[::-1]for x in z];z[1]=r[1]if r[1]<'12'else '12';z[0]=r[0]if r[0]<'31'else '30'if z[1]=='11'else '31';z[2]=r[2];print "-".join(z)

```

Takes the input as a string, so quotes need to be specified in the input, e.g. "11-04-2016".
> 0 votes

# Answer
# 05AB1E, 24 bytes

```
#íÐÅsË31^12‚øεßт+¦}sθªðý

```

Port of *@MartinEnder*'s CJam answer, so also inputs and outputs as a string in the format `dd MM yyyy`.

Try it online or verify all test cases.

**Explanation:**

```
#                         # Split the (implicit) input by spaces
                          #  i.e. "04 11 1671" → ["04","11","1671"]
                          #  i.e. "20 01 2000" → ["20","01","2000"]
 í                        # Reverse each string
                          #  i.e. ["04","11","1671"] → ["40","11","1761"]
                          #  i.e. ["20","01","2000"] → ["02","10","0002"]
  Ð                       # Triplicate this list
   Ås                     # Pop one of them, and push it's middle element (the months)
                          #  i.e. ["40","11","1761"] → "11"
                          #  i.e. ["02","10","0002"] → "10"
     Ë                    # Check if the digits are the same (1 for 11; 0 otherwise)
                          #  i.e. "11" → 1 (truthy)
                          #  i.e. "10" → 0 (falsey)
      31^                 # Bitwise-XOR with 31 (30 for November, 31 for other months)
                          #  i.e. 1 → 30
                          #  i.e. 0 → 31
         12‚              # Pair it with 12
                          #  i.e. 30 → [30,12]
                          #  i.e. 31 → [31,12]
            ø             # Zip/transpose; swapping rows and columns
                          # (implicitly removes year)
                          #  i.e. ["40","11","1761"] and [30,12] → [["40",30],["11",12]]
                          #  i.e. ["02","10","0002"] and [31,12] → [["02",31],["10",12]]
             ε    }       # Map each pair to:
              ß           # Get the minimum (implicitly converts to integer unfortunately)
                          #  i.e. [["40",30],["11",12]] → [30,11]
                          #  i.e. [["02",31],["10",12]] → [2,10]
               т+         # Add 100
                          #  i.e. [30,11] → [130,111]
                          #  i.e. [2,10] → [102,110]
                 ¦        # Remove the first character
                          #  i.e. [130,111] → ["30","11"]
                          #  i.e. [102,110] → ["02","10"]
                   s      # Swap so the triplicated list is at the top of the stack again
                    θ     # Pop and only leave it's last element (the year)
                          #  i.e. ["40","11","1761"] → "1761"
                          #  i.e. ["02","10","0002"] → "0002"
                     ª    # Append it to the list
                          #  i.e. ["30","11"] and "1761" → ["30","11","1761"]
                          #  i.e. ["02","10"] and "0002" → ["02","10","0002"]
                      ðý  # Join the list by spaces (and output implicitly)
                          #  i.e. ["30","11","1761"] → "30 11 1761"
                          #  i.e. ["02","10","0002"] → "02 10 0002"

```
> 0 votes

---
Tags: code-golf, date
---


title: Decode a Rövarspråket string

text:
# Question
Title: Decode a Rövarspråket string
This question is the inverse of this one by James Williams.

---

## Rövarspråket

Rövarspråket is a word game played by Swedish children, from the books about Kalle Blomkvist by Astrid Lindgren.

The basic rules used during encoding are as follows (from Wikipedia):

* Every consonant (spelling matters, not pronunciation) was doubled, and an o was inserted in-between.
* Vowels were left intact.

A few examples of decoding:

* "hohelollolo" -\> "hello"
* "MoMinon sosvovävovarore äror fofulollol momedod ålol" -\> "Min svävare är full med ål"

Swedish consonants are the same as the English ones, so the program should work with both Swedish and English entries.

The letter "y" is taken as a consonant in this case - as most of the time it is.

---

## Your Task:

Write a program to convert a Rövarspråket string of Swedish letters, inputted through a function or through stdin, into its decoded equivalent. Shortest answer in bytes wins!

# Answer
# Retina, 19 + 2 = 21 bytes

Retina strikes again! The code for this program consists of two files:

```
i`([b-z-[eiou]])o.

```

```
$1

```

This reads the input on STDIN and prints the output to STDOUT.

If you call the files `pattern.rgx` and `replacement.rpl`, you can run the program simply like

```
echo "hohelollolo" | ./Retina pattern.rgx replacement.rpl

```

## Explanation

As for the previous answer, if Retina is invoked with 2 files it is automatically assumed to operate in "Replace mode", where the first file is the regex and the second file is the pattern.

Retina can be configured (which includes `RegexOptions` and other options) by prepending the regex with ``` and a configuration string. In this case I'm only giving it `i` which is the normal regex modifier for case insensitivity.

The pattern itself is a bit more interesting this time. It still uses .NET's character class subtraction to match any consonant in the ASCII range, but then it also matches the following `o` as well as the character after it (i.e. the copy of the consonant). The replacement then just writes the captured consonant back.

You might be wondering why this is not ambiguous in a case like `lololol -> lol`. The trick is that matches cannot overlap and are always found from left-to-right. So whenever I encounter a consonant, I include the next two character in the match and replace all of them - the search continues after this. It's quite easy to convince yourself that this kind of greedy algorithm will always decode the input correctly. In fact the pattern could even have been

```
i`([b-z-[eiou]])..

```
> 10 votes

# Answer
# Julia, ~~61~~ 43 bytes

```
t->replace(t,r"(?![eiou])[b-z]o."i,s->s[1])

```

This creates an anonymous function which accepts a string as input and returns the inverse Rövarspråket transformation of the string. It's the exact inverse of my Julia answer to the Rövarspråket challenge. To call it, give it a name, e.g. `f=t->...`.

The `replace()` function is doing all of the work here. The first argument is the input string, the second is a regular expression pattern (which in Julia is given as a string preceded by `r`), and the third is the replacement.

For the regex, we're matching all pairs of consonants separated by an "o". For the replacement, we're taking the match and extracting only the first character, which is the consonant.

Examples:

```
julia> f("hohelollolo")
"hello"

julia> f("MoMinon sosvovävovarore äror fofulollol momedod ålol")
"Min svävare är full med ål"

```

Questions? Just let me know. Suggestions? Very welcome as always!

---

**Edit:** Saved 18 bytes thanks to Martin Büttner!
> 4 votes

# Answer
## Sed, 13, 15, 16, 28

```
s/\([^äöåaeiou]\)o\1/\1/g

```

Run it like this:

```
echo MoMinon sosvovävovarore äror fofulollol momedod ålol | sed 's/\([^äöåaeiou]\)o\1/\1/g'

```

Output:

```
Min svävare är full med ål

```
> 1 votes

# Answer
# Java, 47

Use as a lambda function. Works the exact same way as Martin's answer.

```
a->a.replaceAll("(?i)([b-z&&[^eiou]])o.","$1");

```

Try here
> 0 votes

# Answer
# Pyth, 27

```
VzJ:zZhZpkJ~Zhy}rJ0-G"aeoui

```
> 0 votes

# Answer
# JavaScript (ES6), 46

This turns out to be some language-specific sintax around a regexp. ES6 is quite short. Too bad we miss subtraction

```
F=s=>s.replace(/([b-df-hj-np-tv-z])../gi,'$1')

```
> 0 votes

# Answer
# Mathematica, 36 bytes

Roughly uses the strategy in my previous answer.

```
StringReplace[#,a_~~"o"|"O"~~a_:>a]&

```

Explanation:

* `"o"|"O"` matches the lettter O insensitively.
* `a_~~*..*~~a_:>a` matches any character `a` followed by an O followed by `a` again, and replaces it with `a`.
* Finally, `StringReplace[#,*..*]&` creates a pure function applying that rule to every matching sequence in its argument.
> 0 votes

# Answer
# PHP - 65 66

```
$s=$argv[1];echo preg_replace("/([^aeiou])o([^aeiou])/i","$1",$s);

```
> 0 votes

# Answer
# Python, 61

The inverse is conveniently is the same length as the original.

```
import re;g=lambda s:re.sub('(?i)(?![eiou])([b-z])o.',r'\1',s)

```

Or alternatively:

```
import re;g=lambda s:re.sub('(?i)(?![eiou])([b-z])o.','\\1',s)

```

Run it here: http://repl.it/f3N
> 0 votes

# Answer
# JavaScript 65

```
function R(x){return x.replace(/([bcdfghj-np-tv-z])o\1/gi, "$1")}

```
> 0 votes

# Answer
# JavaScript ES6, 108 bytes

```
F=s=>{
  for(n='',i=0;i<s.length;n+=c)c=s[i],i+=~'bcdfghjklmnpqrstvwxyz'.indexOf(c.toLowerCase())?3:1
  return n
}

```

To make this interesting, I tried to do this entirely without regular expressions, which is why it is so long. It works by iterating over the string, copying each letter over to a new string. If it encounters a consonant, it skips the next two letters, which would be o + that letter. Use the snippet for a GUI alert and ES5.

```
F=function(s){for(n='',i=0;i<s.length;n+=c)c=s[i],i+=~'bcdfghjklmnpqrstvwxyz'.indexOf(c.toLowerCase())?3:1
return n}

alert(F('hohelollolo')+'\n'+F('MoMinon sosvovävovarore äror fofulollol momedod ålol'))
```
> 0 votes

# Answer
# QuadR, 15 bytes

```
([^aeiou])o.
\1

```

Try it online!

PCRE Replace…

`([^aeiou])o.` non-vowel (and call this the first capturing group), "o", any character

with…

`\1` the first capturing group
> 0 votes

---
Tags: code-golf, string
---


title: What does this button do?

text:
# Question
Title: What does this button do?
Currently at my work we moved to a new building. It's supposed to be state of the art and has automatic lights, automatic roll-down shutters, and is now known as the most eco-friendly building in this town.
However, it doesn't really work all that well.. The roll-down shutters sometimes go down on cloudy days and up when the sun starts to shine, and the lights sometimes cause disco effects by alternating turning on and off every 5-10 minutes. Also, we don't have any manual way of controlling these roll-down shutters, nor the temperature, BUT we do have a remote for the lights.
These remotes however came without instruction manual and contain little over 20 buttons doing all kind of stuff except for what you seem to want..

PS: I wrote this challenge 1.5 months ago in the Sandbox. Currently we, kinda, know how the remotes work..
One big advantage about this building, it's 30+ degrees Celcius outside, but inside it stays the same 21 room temperature at all time.

So, that was the intro, and the remote control for the lights inspired this challenge.

# Challenge:

Let's say we initially have a lamp turned off:

```
L

```

Then we push all kind of buttons and output the state of the lamp afterwards.

We use the following numbers for the different functions of the remote control for the lamp. When a minus symbol is in front of that number, we do the opposite.

* `1` = ON; `-1` = OFF.
* `2` = Increase strength by 25%; `-2` = Decrease (dim) strength by 25%.
* `3` = Increase spread by 50%; `-3` = Decrease spread by 50%.
* `4` = Toggling the type of light.

So, this is all pretty vague, so let's go a little more in depth what each thing means:

So, `-1` (OFF) is pretty obvious, and `1` will go to the initial ON-state (50% for `2` and 50% for `3`):

```
   //
  //
L ====
  \\
   \\

```

`2` and `-2` is how far the light travels (`==` is appended for every 25%):

```
0% (equal to a light bulb that is OFF)
L

25%
L ==

50%
L ====

75%
L ======

100%
L ========

```

`3` and `-3` is how far the light spreads:

```
0%:
L ====

50%:
   //
  //
L ====
  \\
   \\

100%:
|| //
||//
L ====
||\\
|| \\

```

(NOTE: When `2` and `3` are both at 100%, you'll have this state:

```
||   //
||  //
|| //
||//
L ========
||\\
|| \\
||  \\
||   \\

```

`4` is to toggle the type of light.

```
Default:
  //
L ==
  \\

After toggling (note the single space before '/' instead of two):
 /
L --
 \

```

**Input:**

You will receive an input containing the possible button-presses. For example:

```
12-34

```

**Output:**

The state of the light lamp after all the buttons of the input are sub-sequential pressed. So with the example input above, we have the following output:

```
L ------

```

**Challenge rules:**

* The input only contains `1234-` (and never a `-` before the `4`).
* You can never go below 0% or above 100%. If a number would increase/decrease beyond these boundaries you can ignore it.
* When the lamp is turned off, you can ignore any actions and when turned back on again it resets back to the initial ON-state (50% for both `2` and `3`, and default `4`). For example: `12-1-341` will just print the initial ON-state mentioned above. (TIP: You can ignore everything before the final `1` of the input - excluding `-1`.)
* Trailing spaces equal to the length of the light or a single trailing new line is uninhibited. Adding extra unnecessary new lines isn't however.
* You are allowed to take the input as a list of integers instead of a single string. So instead of `12-34`, you can have `[1,2,-3,4]` as input.

**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, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
* Default Loopholes are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation if necessary.

**Test cases:**

```
12-34
L ------

12-1-341
   //
  //
L ====
  \\
   \\

14-3224333-2
||  //
|| //
||//
L ======
||\\
|| \\
||  \\

142-1-314-3-322
L --------

1324-2-3
  /
 /
L ----
 \
  \

134
| /
|/
L ----
|\
| \

1-2-2-214-3-3-3
L ----

```

# Answer
# Python 2, 221 bytes

```
for b in[-1]+input():exec["p=b>0;d=2;s=1;t=2","d+=b/2*(-2<d+b<6)","s+=b/3*(-3<s+b<5)","t=3-t"][abs(b)-1]
i=c=(s>0)*d*p
q='print" |"[s/2]*t+" "*i+t*%r;'
exec('i-=1;'+q%'/')*c
print"L "+" -="[t]*2*d*p
exec(q%'\\'+'i+=1;')*c

```

This wound up being longer than I expected. The first line calculates the state of the lamp, the rest implement the printing.

Input is given via STDIN in the array form.

See the test cases on **ideone**
> 6 votes

# Answer
# R, ~~323~~ 320 bytes

```
    z=scan();a=c=1;b=d=2;for(i in 1:sum(1|z)){s=sign(y<-z[i]);switch(y/s,b<-d<-2*(c<-a<-y),b<-b+s,c<-c+s,d<-2-d);b=min(b,4);c=min(c,2);b=b*(b>0);c=c*(c>0)}
    s="/";v=if(c>1)"|"else" ";for(i in a*b:-b){if(i)cat(v,if(d)v,rep(" ",abs(i)-1),s,if(d)s,"\n",sep="")else{cat("L ",if(d)rep("==",b)else rep("--",b),"\n",sep="");s="\\"}}

```

Ungolfed:

```
z=scan()

```

reads a line of input (integers separated with spaces)

```
a=c=1;b=d=2

```

initialises variables a (on-ness), b (brightness), c (width), d (beam type). `d` is either zero or two, which means we can call if(d) later rather than a longer if(d\>1) or similar and save a couple of bytes.

```
while(any(z|1))

```

A golf-y way of writing `while(length(z))` where z is an integer vector.

The rest of the first line handles the input via a `switch` statement. The second line prints out.

It is possible that some of the `<-` can be replaced with `=`, but I think you get eaten alive by lexical scoping...

Also note that in R, backslashes need to be escaped.

`c*(c>0)` is a golf-y way of writing `max(c,0)` that saves a character.

If the light isn't on, then since `*` has lower precedence than `:`, the `for(i in a*b:-b)` loop only iterates over `0:0` .

Update; saved 3 bytes by replacing the loop in the first line with a for (rather than while). Note that `1:sum(1|z)` is fewer characters than `1:length(z)` or `seq_along(z)`. `seq(z)` would work in most cases, but not when `z` is of length one. The solution given will not work for input of length zero but I hope that is outside the scope of the competition.
> 3 votes

# Answer
# Java 8, ~~484~~ ~~483~~ ~~452~~ ~~446~~ 440 bytes

```
z->{int a=1,b=2,c=1,d=0,j,k;for(int i:z){d=i==1?0:i>3?1-d:d;a=i*i==1?i:a;b+=i==1?2-b:i==2&b<4?1:i==-2&b>0?-1:0;c+=i==1?1-c:i==3&c<2?1:i==-3&c>0?-1:0;}String t=d<1?"=":"-",q=d<1?"//":"/",x=d<1?"\\\\":"\\",n="\n",y=" ",w=d<1?y+y:y,g=c>1?d<1?"||":"|":w,r="";if(c>0)for(r+=g,j=b;j-->0;r+=q+n+(j>0?c>1?g:w:""))for(k=j;k-->0;r+=y);for(r+="L ",j=b;j-->0;r+=t+t);r+=n;if(c>0)for(r+=g;++j<b;r+=x+n+(j<b-1?g:""))for(k=j;k-->0;r+=y);return a>0?r:"L";}

```

Finally.. Ok, my own challenge is a bit harder than I expected.. ;P

This can without a doubt be golfed by using a completely different approach.. I now first determine what to do, and then print it. The printing is actually the hardest of this challenge, imho.

-6 bytes thanks to *@ceilingcat*.

**Explanation:**

Try it here.

```
z->{                          // Method with integer-array parameter and String return-type
  int a=1,                    //  ON/OFF flag, initially ON
      b=2,                    //  Strength, initially 50%
      c=1,                    //  Spread, initially 50%
      d=0,                    //  Type of light, initially two lines
      j,k;                    //  Index-integers
  for(int i:z){               //  Loop over the input-array
    d=i==1?0:i>3?1-d:d;       //   Determine the new type of light
    a=i*i==1?i:a;             //   Determine if the light is ON/OFF
    b+=i==1?2-b:i==2&b<4?1:i==-2&b>0?-1:0;
                              //   Determine the new strength
    c+=i==1?1-c:i==3&c<2?1:i==-3&c>0?-1:0;}
                              //   Determine the new spread
  String t=d<1?"=":"-",       //  Horizontal light symbol
         q=d<1?"//":"/",      //  Upper diagonal light symbol
         x=d<1?"\\\\":"\\",   //  Bottom diagonal light symbol
         n="\n",              //  New-line
         y=" ",               //  Space
         w=d<1?y+y:y,         //  One or two spaces?
         g=c>1?d<1?"||":"|":w,//  Space(s) or vertical light symbol(s)?
         r="";                //  Result String, starting empty
  if(c>0)                     //  Do we have spread >0%?
    for(r+=g,j=b;j-->0;r+=q+n+(j>0?c>1?g:w:""))for(k=j;k-->0;r+=y);
                              //   Create upper light part
  r+="L ";                    //  Light-bulb
  for(j=b;j-->0;r+=t+t);      //  Horizontal light next to the light-bulb
  r+=n;
  if(c>0)                     //  Do we have spread >0%?
    for(r+=g;++j<b;r+=x+n+(j<b-1?g:""))for(k=j;k-->0;r+=y);
                              //   Create bottom light part
  return a>0?                 //  Is the light turned ON?
             r                //   Return the created result-String
            :                 //  Else:
             "L";}            //   Return just "L"

```
> 2 votes

# Answer
# Kotlin, 445 bytes

My first Kotlin golf, 38 bytes less than Java :)

```
fun f(z:IntArray)={var a=1<0;var b=2;var c=1;var d=a
z.map{when(it){1->{a=1>0;b=2;c=1;d=!a}-1->a=1<0;2->if(b<4)b+=1;-2->if(b>0)b-=1;3->if(c<2)c+=1;-3->if(c>0)c-=1;4->d=!d}}
var r="";val l=if(c>1)if(d)"|" else "||" else if(d)" " else "  "
if(c>0)for(i in b downTo 1)r+="${l+" ".repeat(i-1)+if(d)"/" else "//"}\n"
r+="L ${(if(d)"--" else "==").repeat(b)}\n"
if(c>0)for(i in 1..b)r+=l+" ".repeat(i-1)+"${if(d)"\\" else "\\\\"}\n"
if(a)r else "L"}()

```

With white-space and tests:

```
fun f(z: IntArray) = {
    var a = false // ON / OFF
    var b = 2 // Strength [0,4]
    var c = 1 // Spread [0,2]
    var d = a // Type

    // Find state to print
    z.map {
        when (it) {
            1 -> {
                a = true
                b = 2
                c = 1
                d = !a
            }
            -1 -> a = false
            2 -> if (b < 4) b += 1
            -2 -> if (b > 0) b -= 1
            3 -> if (c < 2) c += 1
            -3 -> if (c > 0) c -= 1
            4 -> d = !d
        }
    }

    var r = ""
    val l = if (c > 1) if (d) "|" else "||"
    else if (d) " " else "  "

    // Print state
    if (c > 0) for (i in b downTo 1) {
        r += "${l + " ".repeat(i - 1) + if (d) "/" else "//"}\n"
    }
    r += "L ${(if (d) "--" else "==").repeat(b)}\n"
    if (c > 0) for (i in 1..b) {
        r += "${l + " ".repeat(i - 1) + if (d) "\\" else "\\\\"}\n"
    }

    /* return */ if (a) r else "L"
}()

fun main(args: Array<String>) {
    println(f(intArrayOf(1, 2, -3, 4)))
    println(f(intArrayOf(1, 2, -1, -3, 4, 1)))
    println(f(intArrayOf(1, 4, -3, 2, 2, 4, 3, 3, 3, -2)))
    println(f(intArrayOf(1, 4, 2, -1, -3, 1, 4, -3, -3, 2, 2)))
    println(f(intArrayOf(1, 3, 2, 4, -2, -3)))
    println(f(intArrayOf(1, 3, 4)))
    println(f(intArrayOf(1, -2, -2, -2, 1, 4, -3, -3, -3)))
}

```

Interestingly, rather than define the function normally and `print` or `return` the created string, it was shorter to use function assignment (the `fun f() =` of an evaluated lambda. (Does that description make sense?)

I just wish SE had proper Kotlin syntax highlighting
> 2 votes

# Answer
## Batch, 552 bytes

```
@echo off
for %%a in (1 %*) do call:l %%a
set/aw*=o,l*=o
if %w% gtr 0 for /l %%a in (%l%,-1,1)do call:w %%a /
set s=----
if %t%==1 set s=====
call echo L %%s:~-%l%%%%%s:~-%l%%%
if %w% gtr 0 for /l %%a in (1,1,%l%)do call:w %%a \
exit/b
:w
set v=
set u=%2
if %w%==2 set v=l
if %t%==1 set u=%2%2&set v=%v%%v%
set s=
call set s=%%s:~-%1%%
echo %v:l=^|%%s:~1%%u%
exit/b
:l
if %1==1 set/ao=w=t=1,l=2
if %1==-1 set/ao=0
if %1==2 set/al+=1-l/4
if %1==-2 set/al-=!!l
if %1==3 set/aw+=1-w/2
if %1==-3 set/aw-=!!w
if %1==4 set/at^=1

```

Note: `set v=` contains one trailing space and `set s=` contains three. This was really awkward, as you can't easily print a variable number of `|`s in Batch, so you have to use a placeholder and replace it in the echo statement.
> 1 votes

# Answer
# 05AB1E, 106 bytes

```
“/|=
L“•Wθ¨S9ƒTª»þúÙ•6вèJ¶¡sŽ8ÃS«1¡θΣÄ}.γÄ}ODd*©н8‚ß8αFć¨šNÈi¨]R®θ8Öi"||//="2ô…|/-S:}®Ås3/©_iθ}®i'|ð:}».∊

```

Input as a list of integers.

Try it online or verify all test cases.

**Explanation:**

```
“/|=
L“               # Push string "/|=\nL"
  •Wθ¨S9ƒTª»þúÙ• # Push compressed integer 9569494169631511496055972036
   6в            # Converted to Base-6 as list: [5,3,2,2,2,2,2,2,2,2,4,1,1,0,0,4,1,1,3,0,0,4,1,1,3,3,0,0,4,1,1,3,3,3,0,0]
     è           # Index each into the string
      J          # Join everything together

```

We now have the string:

```
L ========
||//
|| //
||  //
||   //

```

Then we'll:

```
¶¡               # Split it by newlines: ["L ========","||//","|| //","||  //","||   //"]
s                # Swap to take the (implicit) input-list
 Ž8Ã             # Push compressed integer 2234
    S            # Converted to a list of digits: [2,2,3,4]
     «           # Append it at the end of the input-list
                 #  i.e. [4,3,3,2,1,3,2,4,-2,-3] → [4,3,3,2,1,3,2,4,-2,-3,2,2,3,4]
 1¡              # Then split on 1
                 #  i.e. [4,3,3,2,1,3,2,4,-2,-3,2,2,3,4]
                 #   → [[4,3,3,2],[3,2,4,-2,-3,2,2,3,4]]
   θ             # Only leave the last inner list
                 #  i.e. [[4,3,3,2],[3,2,4,-2,-3,2,2,3,4]] → [3,2,4,-2,-3,2,2,3,4]
    ΣÄ}          # Sort on the absolute value
                 #  i.e. [3,2,4,-2,-3,2,2,3,4] → [2,-2,2,2,3,-3,3,4,4]
       .γÄ}      # Then group by absolute value
                 #  i.e. [2,-2,2,2,3,-3,3,4,4] → [[2,-2,2,2],[3,-3,3],[4,4]]
           O     # Then take the sum of each group
                 #  i.e. [[2,-2,2,2],[3,-3,3],[4,4]] → [4,3,8]
            Dd   # Duplicate it, and check for each if it's non-negative (>= 0)
                 #  i.e. [4,3,8] → [1,1,1]
              *  # Multiply the two lists
                 #  i.e. [4,3,8] and [1,1,1] → [4,3,8]
               © # And store the result in the register (without popping)
н                # Now take the first value (the strength)
                 #  i.e. [4,3,8] → 4
 8‚              # Pair it with 8
                 #  i.e. 4 → [4,8]
   ß             # Pop and push the minimum of the two
                 #  i.e. [4,8] → 4
    8α           # And then calculate the absolute difference with 8
                 #  i.e. 4 → 4
      F          # Loop that many times:
       ć         #  Extract the head of the string-list
                 #   i.e. ["L ========","||//","|| //","||  //","||   //"] → "L ========"
        ¨        #  Remove the last character
                 #   i.e. "L ========" → "L ======="
         š       #  And prepend it back to the list again
                 #   i.e. ["||//","|| //","||  //","||   //"] and "L ======="
                 #    → ["L =======","||//","|| //","||  //","||   //"]
       NÈi       #  And if the loop-index is even:
          ¨      #   Also remove the last item of the string-list
                 #    i.e. ["L =======","||//","|| //","||  //","||   //"]
                 #     → ["L =======","||//","|| //","||  //"]
      ]          # Close both the if and loop
                 #  i.e. ["L ========","||//","|| //","||  //","||   //"] and 4
                 #   → ["L ====","||//","|| //"]
       R         # Then reverse the list
                 #  i.e. ["L ====","||//","|| //"] → ["|| //","||//","L ===="]
®                # Push the list from the register again
 θ               # Now take the last value (the toggle)
                 #  i.e. [4,3,8] → 8
  8Öi         }  # If it's divisible by 8:
                 #  i.e. 8 → 1 (truthy)
     "||//="     # Push string "||//="
            2ô   # Split into parts of size 2: ["||","//","="]
     …|/-        # Push string "|/-"
         S       # Split into characters: ["|","/","-"]
     :           # And replace all of them in the string-list
                 #  i.e. ["|| //","||//","L ===="] → ["| /","|/","L ----"]
®                # Push the list from the register again
 Ås              # Now take the middle value (the spread)
                 #  i.e. [4,3,8] → 3
   3/            # Divide it by 3
                 #  i.e. 3 → 1
     ©           # Store it in the register (without popping)
      _i }       # If it's exactly 0:
                 #   i.e. 1 → 0 (falsey)
        θ        #  Only leave the last value of the string-list
     ®i    }     # If it's exactly 1 instead:
                 #   i.e. 1 → 1 (truthy)
       '|ð:     '#  Replace all "|" with spaces " "
                 #   i.e. ["| /","|/","L ----"] → ["  /"," /","L ----"]
»                # Then join the string-list by newlines
                 #  i.e. ["  /"," /","L ----"] → "  /\n /\nL ----"
 .∊              # And finally intersect mirror everything vertically
                 # (which automatically converts the slashes)
                 #  i.e. "  /\n /\nL ----" → "  /\n /\nL ----\n \\n  \"
                 # (And output the result implicitly)

```

See this 05AB1E tip of mine (sections *How to compress large integers?* and *How to compress integer lists?*) to understand why `•Wθ¨S9ƒTª»þúÙ•6в` is `[5,3,2,2,2,2,2,2,2,2,4,1,1,0,0,4,1,1,3,0,0,4,1,1,3,3,0,0,4,1,1,3,3,3,0,0]`; and `Ž8Ã` is `2234`.
> 0 votes

---
Tags: code-golf, ascii-art
---


title: Words crossing over

text:
# Question
Title: Words crossing over
## Input:

Two strings (NOTE: the order of input is important).

## Output:

Both words/sentences start on lines with one empty line in between them. They 'walk' horizontally 'next to each other'. But when they have the same character at the same position, they cross each other, and then continue walking 'next to each other'.

Confusing you say? Let's give an example:

Input: `Words crossing over` & `Ducks quacking`:

```
Word  quack n
    s      i g
Duck  cross n  over

```

*Excuse the bad MS paint..*

## Challenge rules:

* We always first go back walking a straight line after we've 'crossed over' before we can cross over again (see test case above {1} - where `ing` is equal, but after we've crossed on `i`, we first have to go back walking straight (thus ignoring `n`), before we can cross again on `g`).
* The inputs can be of different length, in which case the longer one continues walking in a straight line (see test cases 1, 2, 4 & 6).
* Both inputs can be the same (see test case 3).
* The inputs won't contain any tabs nor new-lines.
* **Spaces are ignored as characters that are the same (as an edge case)**, in which case the next (non-space) character after that - if any - is crossing over instead (see test cases 3, 5 & 6).
* The inputs can have no adjacent (non-space) characters on the same position at all, in which case both just walk in a straight line horizontally (see test cases 2).
* Even if the first character is equal, we always start two lines apart (see test cases 3 & 6).
* Trailing spaces and a single trailing new-line are optional.
* You can assume the inputs will only contain printable ASCII characters (new-lines and tabs excluded).
* The inputs are case-sensitive, so `A` and `a` aren't equal, and won't cross over (see test case 7).
* Both the inputs lengths will always be at least 2.
* Input & output can be in any reasonable format. Can be a single String with new-lines; a String-array/list; printed to STDOUT; 2D array of characters; etc.

## 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, 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.
* Also, please add an explanation if necessary.

## Test cases:

```
1. Input: "Words crossing over" & "Ducks quacking"

1. Output:
Word  quack n
    s      i g
Duck  cross n  over

2. Input: "bananas" & "ananas"

2. Output:
bananas

ananas

3. Input: "I see my twin!" & "I see my twin!"

3. Output:
I  e   y  w n
  s e m  t i !
I  e   y  w n

4. Input: "Is the weather nice?" & "Not really, no.."

4. Output:
Is th ally, no..
     e
Not r  weather nice?

5. Input: "Codegolf & Programming Puzzles" & "The golfer might solve puzzles"

5. Output:
Code o f & Programming P z l s
    g l                 u z e
The  o fer might solve p z l s

6. Input: "Can you turn the lights off?" & "Can you try to solve this?"

6. Output:
C n  o   urn the  ve  s off?
 a  y u t        l   t
C n  o   ry to so igh his?

7. Input: "one Ampere" & "two apples"

7. Output:
one Am les
      p
two ap ere

8. Input: "Words crossing" & "Words Quacking"

8. Output:
W r s cross n
 o d       i g
W r s Quack n

```

# Answer
> 4 votes
# Japt, ~~56~~ ~~47~~ 33 bytes

```
y ®m+S éBv ©Zê¬©Zx ?°B:B=c2)¯3Ã·y

```

Test it online! Takes input as an array of two strings.

I am a total moron... `y ®` is a million times easier to use on two different-length strings than `U¬íV¬@`...

### Explanation

```
y ®   m+S éBv © Zê¬ © Zx ?° B:B= c2)¯  3Ã ·  y
y mZ{Zm+S éBv &&Zêq &&Zx ?++B:B=Bc2)s0,3} qR y

              Implicit: U = array of two strings
y             Transpose U, padding the shorter string with spaces in the process.
mZ{        }  Map each pair of chars Z by this function: (we'll call the chars X and Y)
  Zm+S          Append a space to each char, giving X + " " + Y + " ".
  Bv            If B is divisible by 2
  &&Zêq           and Z is a palindrome (X and Y are the same)
  &&Zx ?          and Z.trim() is not empty (X and Y are not spaces):
    ++B           Increment B. B is now odd; the top and bottom strings are swapping.
  :             Otherwise:
    B=Bc2         Ceiling B to a multiple of 2. (0 -> 0, 1 -> 2, 2 -> 2, etc.)
  é       )     Rotate the string generated earlier this many chars to the right.
  s0,3          Take only the first 3 chars of the result.
qR            Join the resulting array of strings with newlines.
y             Transpose rows with columns.
              Implicit: output result of last expression

```

`B` is a variable that keeps track of which state we're in:

* `B % 4 == 0` means first word on top, but ready to switch;
* `B % 4 == 1` means we've just switched;
* `B % 4 == 2` means second word on top, but ready to switch;
* `B % 4 == 3` means we've just switched back.

`B` happens to be preset to `11`; since `11 % 4 == 3`, the first column always has the first word on top. We increment `B` any time the words swap positions, or any time it's odd (with `B=c2`).

# Answer
> 6 votes
# APL (Dyalog), 64 bytes

```
{C←⎕UCS⋄1↓e⊖' '⍪1 0 1⍀⍵⊖⍨≠\e←C(2/⊃l)⎕R(l←C⌽⍳2)C(0@0=⌿⍵)∧' '≠1⌷⍵}

```

Try it online!

# Answer
> 4 votes
# Charcoal, 69 bytes

```
ＡＥ⮌θιθＡＥ⮌ηιηＷ∧θη«Ａ⊟θεＡ⊟ηδＡ∧¬∨φ⁼ε ⁼εδφ¿φ«εＡθδＡηθＡδη»«↑↓ε↓↗δ»»¿θ↑↓↑⮌⁺θη

```

Try it online! Link is to verbose version of code. Explanation:

```
ＡＥ⮌θιθＡＥ⮌ηιη        Turn the input strings into arrays and reverse them
Ｗ∧θη«               While both valus still have characters left
     Ａ⊟θεＡ⊟ηδ       Extract the next pair of characters
     Ａ∧¬∨φ⁼ε ⁼εδφ   Determine whether this is a crossing point
     ¿φ«εＡθδＡηθＡδη  If so then print the character and switch the value
      »«↑↓ε↓↗δ»»     Otherwise print the two characters apart
¿θ↑↓                Move to print any remaining characters accordingly
↑⮌⁺θη               Print any remaining characters

```

# Answer
> 3 votes
# Python 2, ~~217~~ 210 bytes

-1 byte thanks to officialaimm

```
a,b=map(list,input())
n=max(len(a),len(b))
c=[' ']*n
a=(a+c)[:n]
b=(b+c)[:n]
for i in range(1,n):
 if a[i]==b[i]!=' '==c[i-1]:c[i]=a[i];a[i]=b[i]=' ';a[i:],b[i:]=b[i:],a[i:]
print'\n'.join(map(''.join,[a,c,b]))

```

Try it online!

# Answer
> 2 votes
## Haskell, ~~142~~ 138 bytes

```
g(a:b)f(c:d)|f>0,a==c,a>' '=[' ',a,' ']:g d 0b|1<2=[a,' ',c]:g b 1d
g[]_[]=[]
g b f d=g(max" "b)f$max" "d
a&b=[[j!!i|j<-g a 0b]|i<-[0..2]]

```

Try it online!

How it works:

```
g                    -- function g constructs a list of lists of three characters
                     --   the 1st char belongs to the upper line,
                     --   the 2nd char to the middle line and
                     --   the 3rd char to the lower line
      f              -- flag f indicates if crossing is allowed or not
 (a:b) (c:d)         -- strings to cross
  |f>0               -- if crossing is allowed
      ,a==c          -- and both strings start with the same char
           ,a>' '    --   that is not a space
   =[' ',a,' ']      -- return space for upper/lower line and char a for the middle line
      :g d 0b        -- and go on with crossing disabled and strings swapped
 |1<2=               -- else
   [a,' ',c]         -- keep chars in their lines and
      :g b 1d        --  go on with crossing enabled

g[]_[]=[]            -- base case: stop when both strings are empty

g b f d=             -- if exactly one string runs out of characters
 g(max" "b)f$max" "d --   replace it with a single space and retry

a&b=                 -- main function
          i<-[0..2]  -- for each line i from [0,1,2]
       j<-g a 0b     -- walk through the result of a call to g with crossing disabled
    j!!i             -- and pick the char for the current line

```

# Answer
> 2 votes
# JavaScript (ES6), 112 bytes

```
(a,b,c='',g=([a,...A],[b,...B],w)=>a?w&a==b&a>' '?' '+g(B,A,c+=a):a+g(A,B,1,c+=' '):'')=>g(a,b)+`
`+c+`
`+g(b,a)

```

**Ungolfed:**

```
f=
(a,b,                                    //the inputs
 c='',                                   //c will hold the middle sentence
 g=([a,...A],[b,...B],w)=>               //define a function to walk through the strings
                                         //w will be false if we're at the beginning,
                                         //... or if we've just done a swap
     a?                                  //are there any letters left?
       w&a==b&a>' '?' '+g(B,A,c+=a):     //if we haven't just swapped and the letters match,
                                         //... add the current letter to c
                                         //... and recurse swapping the strings
                    a+g(A,B,1,c+=' '):   //else add a space to c and continue processing
                    ''
)=>
g(a,b)+'\n'+                             //call g with a, b
c+'\n'+                                  //output c
g(b,a)                                   //call g with b, a

```

**Test cases:**

```
f=
(a,b,c='',g=([a,...A],[b,...B],w)=>a?w&a==b&a>' '?' '+g(B,A,c+=a):a+g(A,B,1,c+=' '):'')=>g(a,b)+`
`+c+`
`+g(b,a)

console.log(f('Words crossing over','Ducks quacking'));
console.log('____________');
console.log(f('bananas','ananas'));
console.log('____________');
console.log(f('I see my twin!', 'I see my twin!'));
console.log('____________');
console.log(f('Is the weather nice?', 'Not really, no..'));
console.log('____________');
console.log(f('Codegolf & Programming Puzzles', 'The golfer might solve puzzles'));
console.log('____________');
console.log(f('Can you turn the lights off?', 'Can you try to solve this?'));
console.log('____________');
console.log(f('one Ampere', 'two apples'))
console.log('____________');
console.log(f('Words crossing','Words Quacking'));
console.log('____________');
```

# Answer
> 1 votes
# Perl 5, 211 bytes

```
@a=map[/./g],<>;$b=1;($f,@{$r[$i]})=$a[0][$i]eq$a[1][$i]&&$f&&$a[0][$i]ne$"?(0,$",$a[0][$i],$",$t=$b++):(1,$a[$t%2][$i],$",$a[$b%2][$i]),$i++while$a[0][$i]||$a[1][$i];for$i(0..2){print$r[$_][$i]for 0..$#r;say''}

```

Try it online!

~~\# Perl 5, 234 bytes~~

*fixed the bug Kevin pointed out*

```
@a=map[/./g],<>;$l=@{$a[0]}>@{$a[1]}?@{$a[0]}:@{$a[1]};$b=1;@{$r[$_]}=$a[0][$_]eq$a[1][$_]&&$_&&$r[$_-1][1]eq$"&&$a[0][$_]ne$"?($",$a[0][$_],$",$t=$b++):($a[$t%2][$_],$",$a[$b%2][$_])for 0..$l;for$i(0..2){print$r[$_][$i]for 0..$l;say}

```

Try it online!

# Answer
> 1 votes
# APL (Dyalog), 50 bytes

```
{3↑(0,+\2∨/2|{⍵⌈a×1+1,¯1↓⍵}⍣≡a←>⌿2=⌿3↑⍵)⊖⍵⍀⍨¯1*⍳4}

```

Try it online!

`⍵⍀⍨¯1*⍳4` gives the matrix:

```
Words.crossing.over
...................
Ducks.quacking.....
...................

```

(the dots represent spaces). Its columns will be rotated by different amounts so the first three rows end up looking like the desired result - hence the `3↑` near the beginning. The rest of the algorithm computes the rotation amounts.

Within the parens: `3↑⍵` creates a matrix like

```
Words.crossing.over
Ducks.quacking.....
...................

```

and `2=⌿` compares its rows pairwise, i.e. first string vs second string and second string vs the all-spaces row.

```
0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1

```

We are interested in where the former is true (1) and the latter false (0), so we reduce with `>⌿` to get a boolean vector named `a`.

```
0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0

```

Now, in every stretch of 1-s we need to zero out the even occurrences because no two twists can occur next to each other. First we obtain a numbering like:

```
0 0 0 0 1 0 0 0 0 0 0 1 2 3 0 0 0 0 0

```

by, loosely speaking, replacing `a[i]` with `a[i]*max(a[i-1]+1, a[i])` until the result stabilises: `{⍵⌈a×1+1,¯1↓⍵}⍣≡`, and we take that mod 2: `2|`

```
0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0

```

Now we know where the twists will occur. We copy each `1` to the left - `2∨/` (pairwise "or"):

```
0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 0

```

and compute the partial sums - `+\`

```
0 0 0 0 1 2 2 2 2 2 2 3 4 5 6 6 6 6 6

```

That gives us the column rotation amounts we needed in the beginning. Modulo 4 is implied.

# Answer
> 0 votes
# 05AB1E, 31 bytes

```
ζεËNĀ¾Èyðå_Pi¼ë¾É½}yð«S¾._¨}øJ»

```

Port of *@ETHproductions*'s Japt answer, but with two minor differences:
1) I take the input as a 2D list of characters instead of list of strings.
2) The `counter_variable` in 05AB1E is 0 by default, instead of 11 (or 3) like the `B` in Japt, so the  is added as additional check inside the map (and I rotate towards the right instead of left).

Try it online or verify all test cases.

**Explanation:**

```
ζ                  # Zip/transpose (swapping rows/columns) the (implicit) input-list
                   # with space filler by default to create pairs
 ε          }      # Map each pair `y` to:
  Ë                #  Check if both values in the pair are equal
  NĀ               #  Check if the map-index is not 0
  ¾È               #  Check if the counter_variable is even
  yðå_             #  Check if the pair contains no spaces " "
  Pi               #  If all checks are truthy:
    ¼              #   Increase the counter_variable by 1:
   ë               #  Else:
    ¾É             #   Check if the counter_variable is odd
      ½            #   And if it is: increase the counter_variable by 1
   }               #  Close the if-else
    yð«            #  Add a space after both characters in the pair
       S           #  Convert it to a list of characters (implicitly flattens)
        ¾._        #  Rotate this list the counter_variable amount of times towards the right
           ¨       #  And then remove the last character
             ø     # Zip/transpose; swapping rows/columns
              J    # Join each inner character-list to a single string
               »   # Join everything by newlines (and output implicitly)

```

---
Tags: code-golf, string, ascii-art
---