We will be using a 3x3 cube for this challenge.

Rubik's cubers have their own notation for movements on the cube:

  • Each of the 6 faces has a clockwise turn notated with a single capital letter: UDLRFB. There are three additional letters MES denoting the three center slices.
  • Counterclockwise rotations have a prime symbol appended: U => U'. The prime symbol for this challenge will be an ASCII apostrophe.
  • A move rotated twice (either CW or CCW) has a 2 appended: U => U2.
  • A move cannot be rotated twice and prime at the same time.
  • Individual moves are separated by spaces: U F D' B2 E M' S2
  • This challenge will not be using lowercase letters, which signify moving two layers at the same time.

Commutators, coming from group theory, is an operation of two elements \$g,h\$ such that \$\left[g,h\right]=ghg^\prime h^\prime\$, where \$g^\prime\$ is the inverse of \$g\$, e.g. R U F' => F U' R'

Rubik's cubers use a similar notation to describe commutators, used for swapping two or three pieces without disturbing any others.

Some examples of commutators:

[F U R, D B] = (F U R) (D B) | (R' U' F') (B' D')
[F' U2 R, D B2] = (F' U2 R) (D B2) | (R' U2 F) (B2 D') // note how B2 and U2 aren't primed

The Challenge

Given a Rubik's cube commutator, expand the commutator to list out all the moves performed in it.


Input is a Rubik's cube commutator. Each side of the commutator are guaranteed to be at least 1 move long. Each part of the commutator can be a separate value. Each move in each commutator part can be separate values, as long as a CCW/prime or double move is within the value of the move (e.g. [[R2], ...] is valid, but [[R,2], ...] is not).


Output is a list of moves of the commutator. All moves must be capital letters in the set UDLRFBMES, with an optional prime ' or double move 2.

Test Cases

[[F U R], [D B]] = F U R D B R' U' F' B' D'
[[F' U2 R], [D B2]] = F' U2 R D B2 R' U2 F B2 D'
[[U F' R2 F' R' F R F2 U' F R2], [F U2 F' U2 F2]] = U F' R2 F' R' F R F2 U' F R2 F U2 F' U2 F2 R2 F' U F2 R' F' R F R2 F U' F2 U2 F U2 F'
[[M2 E2 S2], [B2 D2 F2]] = M2 E2 S2 B2 D2 F2 S2 E2 M2 F2 D2 B2
[[F], [B]] = F B F' B'
[[U], [U]] = U U U' U'

Additional Rules

  • \$\begingroup\$ Relevant: Reverse a Rubik's Cube Algorithm \$\endgroup\$
    – bigyihsuan
    Jan 13 at 5:37
  • 2
    \$\begingroup\$ The 3rd test-case has 's near 2s, which seem to contradict the rules. \$\endgroup\$
    – pajonk
    Jan 13 at 7:40
  • 3
    \$\begingroup\$ Did you mean 3x3x3 cube? \$\endgroup\$
    – Noodle9
    Jan 13 at 13:06
  • 2
    \$\begingroup\$ @Noodle9 To quote OP from the sandbox: The common names for Rubik's cubes are by the size of a face since they're usually cubes, so we just call them "3x3" for a 3x3x3 cube, etc. Only in cuboids like the 3x3x4 cuboid actually have the 3rd dimension. (Although I personally still usually call it 3x3x3 Cube tbh, despite having collected twisty puzzles in the past.) \$\endgroup\$ Jan 13 at 14:01
  • 1
    \$\begingroup\$ Why do you not want to eliminate cancelling moves?? \$\endgroup\$
    – user21820
    Jan 13 at 15:10

R, 85 82 bytes

Or R>=4.1, 68 bytes by replacing two function occurrences with \s.


Try it online!

Input as two vectors of strings.


05AB1E, 14 12 bytes


Try it online or verify all test cases.


í             # Reverse each inner list of the (implicit) input-pair
 ''«          # Append a "'" to each inner-most string
    «         # Merge this modified list to the (implicit) input-list
     ˜        # Flatten it to a single list of strings
      ε       # Map over each string:
       ¤      #  Push its last character (without popping the string)
        º     #  'Double' it with a horizontal mirror
         K    #  Remove all those substrings from the string
              #  (which will only remove potential "''")
          2£  #  Only leave (up to) the first two characters of the string
              # (after which the result is output implicitly)

BQN, 20 bytesSBCS


Run online!

¬∘≠↓·⍷∾⟜"'" is a function that inverts a single move:
∾⟜"'" Append a prime symbol
Deduplicate, This removes one ' if the move already contained one.
¬∘≠ Complement (1-) of the length of the move. -1 for length 2 moves, 0 for length 1. Drop this many characters (from the end because the value is negative)

(⍷∾⟜"'")¨ "U"‿"U'"‿"U2"
# → U' U' U2'
¬∘≠¨ "U"‿"U'"‿"U2"
# → 0 ¯1 ¯1
(¬∘≠↓·⍷∾⟜"'")¨ "U"‿"U'"‿"U2"
# → U' U U2

⌽¨ Reverse each list
( ... )¨∘ Invert each move inside of each list
⊢∾ Prepend the input to the result of that
Flatten by one level


Ruby, 65 bytes

->a{[a,a.map{|x|x.reverse.map{|m|(m+?').sub("''","")[0,2]}}]*" "}

Try it online!


Jelly,  15  14 bytes


A monadic Link accepting a list of lists (parts) of lists of characters (moves) which yields a list of lists of characters (moves).

Try it online!


ḟ;ċ?”'ḣ2)Ṛ)⁸;Ẏ - Link: list of lists of moves, A
          )    - for each Part of A:
        )      -   for each Move in that part:
    ”'         -     yield a quote character
   ?           -     if...
  ċ            -     ...condition: count     (X' -> 1, X -> 0, X2 -> 0)
ḟ              -     ...then: filter discard (X' -> X)
 ;             -     ...else: concatenate    (X -> X', X2 -> X2')
      ḣ2       -     head to index 2         (X -> X, X'-> X', X2' -> X2)
         Ṛ     -   reverse (this Part)
           ⁸   - A
            ;  - concatenate (the reversed, altered Part)
             Ẏ - tighten from a list of four parts to a list of all of the resulting moves

Pyth, 16 bytes


Try it online!

                  Q   parsed input (Q is implicit)
   m                  take each sublist d:
     m           d      map each move k inside the sublist d to (d is implicit)
       -k\'               the move k without the prime symbol
      +                   and append
              hIk         1 if the move k contains only one symbol, 0 otherwise
                          (k is implicit, actually checks if taking
                           the first character is still the complete move,
                           alternatively !tk also works)
           *\'            repeats of the prime symbol
    _                   reverse the sublists
 +Q                   prepend the complete input
s                     and merge everything into a single list of moves

Charcoal, 28 bytes

WS⊞υι⪫⁺υEυ⪫E⮌⪪ι ⁺⁻λ'×'№αλ ¦ 

Try it online! Link is to verbose version of code. Takes input as a list of newline-terminated string of space-separated moves. Explanation:


Input the list of moves.

⪫⁺υEυ⪫E⮌⪪ι ⁺⁻λ'×'№αλ ¦ 

Extend the list by taking the list of moves, splitting on spaces, reversing, inverting each move, and joining with spaces, then join the extended list with spaces and output the result. Moves are inverted by removing any ' but then adding a ' if the move was a single letter.


Python 3, 113 107 83 bytes

lambda g,h:g+h+[r(r(m+"'","2'","2"),"''","")for m in g[::-1]+h[::-1]]

Try it online!

Input is two lists of strings. Naive string operations.

  • -6 bytes from @pajonk: alias str.replace to r
  • -24 bytes from @Kevin Cruijssen: output a list instead of a string

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.