Last semester we were searching for a programming exercise in functional programming (in Haskell) for first-year BSc students.

My college had the idea to let them implement the rotations of Rubik’s cube. He made also a prototype with a list-of-lists representation of the cube: the cube was a list of faces of length 6, and a face was a list of colours of length 9.

I felt that his implementation was not “functional” enough and I experimented with a more functional implementation which follows. In the meantime I have found some errors in his code and managed to put more functionality in less and more clear code at the end!

The colours are (all the colours but orange is predefined in my diagrams-environment):

```
orange :: Color
orange = rgb 1 0.5 0
```

```
colors :: [Color]
colors = [red, blue, orange, green, white, yellow]
```

Let’s see the colours:

Representation of points:

`type R3 = (Double, Double, Double) -- (x, y, z)`

The coordinate system in which the diagrams will be drawn:

We will need some rotations around the origin.

Let `left`

left be a rotation such that the points of the y axis are fixed and the z axis will be rotated into the x axis. (This seems to be a right rotation but we will use it in covariant positions which reverse orientation.)

```
left :: R3 -> R3
left (x,y,z) = (z,y,-x)
```

Let `right`

be the inverse of `left`

:

```
right :: R3 -> R3
right = left . left . left
```

Let `up`

and `down`

be similar to `left`

and `right`

:

```
up, down :: R3 -> R3
up (x,y,z) = (x,-z,y)
down = up . up . up
```

We have to give the colour of each small face of Rubik’s cube (there are 6*9 small faces).

We could give the colours with a list but than we should give an ad-hoc bijection between the list indices and the small faces of Rubik’s cube. Instead of this let’s do the following:

- Fix Rubik’s cube in space so that it’s sizes are 3 x 3 x 3, it’s edges are parallel with the axes and it’s middle is the origin.
- Represent each small face with it’s origin.
- Give a function from the origins of small faces to colours.

So Rubik’s cube is a function:

`type Cube = R3 -> Color`

Note that this function may be a partial function defined only at the origins of small faces, but if it is total (defined on all points), that’s no problem.

Let’s see on possible definition of the standard Rubik’s cube:

```
standard :: Cube
standard (x,y,z)
| abs x > abs y && abs x > abs z = if x < 0 then green else blue
| abs y > abs x && abs y > abs z = if y < 0 then yellow else white
| otherwise = if z < 0 then orange else red
```

The function has no 6*9 different cases; it divides the space into 6 solid angles. The origins of the small faces are in the solid angles.

Example:

I have made a hidden `display`

function which can be used to display a cube:

Example:

Note that this is only one cube; the back faces of the cube are pulled out to the left to make them visible.

Let `cube`

a function which rotate Rubik’s cube:

`infixl 7 `cube``

```
cube :: Cube -> (R3 -> R3) -> Cube
cube = (.)
```

It’s that simple. (Try to define this function on a list-of-lists representation!)

Examples:

Let `top`

be a function which transforms the top row:

`infixl 7 `top``

```
top :: Cube -> (R3 -> R3) -> Cube
top c f p@(x,y,z)
| y > 0.5 = c (f p)
| otherwise = c p
```

Examples:

Note that the types allow the following (wrong) usage also: `standard `top` up`

Define the function `bottom`

which transforms the top row of Rubik’s cube. Try to express `bottom`

with `cube`

and `top`

!

```
infixl 7 `bottom`
bottom :: Cube -> (R3 -> R3) -> Cube
```

Examples:

Define the function `middle`

which transforms the middle row of Rubik’s cube. Try to express `middle`

with the previous functions!

```
infixl 7 `middle`
middle :: Cube -> (R3 -> R3) -> Cube
```

Examples:

Define the following configuration of Rubik’s cube!