# Problem

Description: I really like Rubik’s Cubes, so I created a challenge for you. I put the flag on the white tiles and scrambled the cube. Once you solved the cube, you’ll know my secret.

(rev90, solved by 232)

Attachment: rev90.zip

# Solution

In this task we were given a text-file containing the scrambling of a Rubik’s cube, as well as the different sides of the cube before it was scrambled.

``````Scrambling:
F' D' U' L' U' F2 B2 D2 F' U D2 B' U' B2 R2 D2 B' R' U B2 L U R' U' L'

White side:
-------
|{|3| |
| |D|R|
| |W| |
-------

Orange side:
-------
| | | |
| | | |
| | | |
-------

Yellow side:
-------
|}| | |
|3| | |
| | | |
-------

Red side:
-------
|I| | |
| | | |
| | |C|
-------

Green side:
-------
| | | |
| | | |
| | | |
-------

Blue side:
-------
| | | |
| | | |
| | | |
-------
``````

First observation is that the flag is five characters long, since there are nine characters spread out over the cube, and of these, four are `IW{}`. This makes it really easy to brute-force this challenge, since there are only 120 possible permutations. However, brute-forcing is no fun.

Another way would be to solve this using a physical Rubik’s cube. In the lack of one of those, we decided to go with the programmatic solution.

The implementation is pretty straight forward. First we define a representation of the cube, which naturally is a 6x3x3 array (or list). We define the six different rotations in different functions. Some valuable observations where are:

• Each rotation of a side affects the four adjacent sides
• The meaning of each rotation depends on the starting state of the cube
• The scrambling needs to be done in reverse in order to de-scramble the cube
• Counter-clockwise rotations (marked with prim-sign) are equivalent to three clockwise rotations, and double rotations are reversed with double rotations

Internetwache were kind enough to supply us with the starting state in a tweet. The starting state of the cube was:

Front: green Right: red Up: white Back: blue Left: orange Down: yellow

Having implemented all rotations, and knowing the starting state, we can solve the cube. Using the provided script, the following output was given:

``````[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']

[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']

['I', 'W', '{']
['3', 'D', 'R']
['C', '3', '}']

[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']

[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']

[' ', ' ', ' ']
[' ', ' ', ' ']
[' ', ' ', ' ']
``````

This gives us the flag, IW{3DRC3}.

Code

``````# The cube
sides = {
'W': [
['{', '3', ' '],
[' ', 'D', 'R'],
[' ', 'W', ' '],
],

'O': [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' '],
],

'Y': [
['}', ' ', ' '],
['3', ' ', ' '],
[' ', ' ', ' '],
],

'R': [
['I', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', 'C'],
],

'G': [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' '],
],

'B': [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' '],
],
}

# This rotates all squares on one side
def rot(s):
return [[s[2-i][j] for i in range(3)] for j in range(3)]

# These functions rotate adjacent sides
def F(c):
tmp = (c, c, c)

c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = tmp

c = rot(c)
return c

def R(c):
tmp = (c, c, c)

c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = tmp

c = rot(c)
return c

def U(c):
tmp = (c, c, c)

c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = tmp

c = rot(c)
return c

def B(c):
tmp = (c, c, c)

c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = tmp

c = rot(c)
return c

def L(c):
tmp = (c, c, c)

c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = tmp

c = rot(c)
return c

def D(c):
tmp = (c, c, c)

c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = c, c, c
c, c, c = tmp

c = rot(c)
return c

def print_cube(c):
for side in c:
for row in side:
print row

print ""

def solve(c):
# Original:
# F' D' U' L' U' F2 B2 D2 F' U D2 B' U' B2 R2 D2 B' R' U B2 L U R' U' L'

# Reverse:
# L U R U' L' B2 U' R B D2 R2 B2 U B D2 U' F D2 B2 F2 U L U D F

c = L(c)        # L
c = U(c)        # U
c = R(c)        # R
c = U(U(U(c)))  # U'
c = L(L(L(c)))  # L'
c = B(B(c))     # B2
c = U(U(U(c)))  # U'
c = R(c)        # R
c = B(c)        # B
c = D(D(c))     # D2
c = R(R(c))     # R2
c = B(B(c))     # B2
c = U(c)        # U
c = B(c)        # B
c = D(D(c))     # D2
c = U(U(U(c)))  # U'
c = F(c)        # F
c = D(D(c))     # D2
c = B(B(c))     # B2
c = F(F(c))     # F2
c = U(c)        # U
c = L(c)        # L
c = U(c)        # U
c = D(c)        # D
c = F(c)        # F

if __name__ == '__main__':
# Color of sides in format:
# Front, right, up, back, left, down
starting_pos = "GRWBOY"
c = []
for ch in starting_pos:
c.append(sides[ch])
solve(c)
print_cube(c)
``````