# Rotate a 2D array (function)

23 Sep 2018### Problem statement

Write a function that takes as input an `n x n`

2-dimensional array, and return the original array rotated by 90 degrees clockwise.

```
EXAMPLE:
Input: [[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]]
Output: [[13, 9, 5, 1],
[14, 10, 6, 2],
[15, 11, 7, 3],
[16, 12, 8, 4]]
```

### Solution

Here is the actual code of the algorithm that takes a 2-dimensional array and returns the original array rotated by 90 degrees clockwise:

```
/// Rotates the given matrix by 90 degrees clockwise.
func rotate(m: Matrix) -> Matrix {
// Prepare a constant & make a copy of the original matrix
let n = m.count; var om = m
// Enumerate matrix in layers, working towards the center
for layer in 0..<(n / 2) {
// Compute layer's start and end
let start = layer, end = n - 1 - layer
// Touch and swap each item of the current layer
for head in start..<end {
// Calculate offset from the start
let offset = head - start
// Calculate Last eleMent's Column and Row
let lmc = head, lmr = start,
// Calculate First eleMent's Column and Row
fmc = lmr, fmr = end - offset,
// Calculate Second eleMent's Column and Row
smc = fmr, smr = end,
// Calculate Third eleMent's Column and Row
tmc = smr, tmr = lmc
// Make a copy of the Last eleMent
let lm = om[lmr][lmc]
// Swap elements, first takes place of the last
om[lmr][lmc] = om[fmr][fmc]
// Swap elements, second takes place of the first
om[fmr][fmc] = om[smr][smc]
// Swap elements, third takes place of the second
om[smr][smc] = om[tmr][tmc]
// Swap elements, last takes place of the third
om[tmr][tmc] = lm
}
}
// Here is our matrix rotated by 90 degrees clockwise
return om
}
```

Following is the traditional section with assertions to validate the code performs as advertised and establish a baseline for any improvement work in the future:

### Bits & pieces

This coding challenge is not very difficult to solve, still there are a few parts requiring extra effort - figure out how to enumerate matrix in layers and calculate coordinates of each element for the given iteration.

Lets get started!

First of all, we declare a constant with the number of edge’s elements for the given matrix and a local copy of the original matrix used to apply desired transformations:

```
// Prepare a constant & make a copy of the original matrix
let n = m.count; var om = m
```

Next statement is the **main loop** to iterate over all layers in the matrix where `n / 2`

yields number of layers in the original matrix:

```
// Enumerate matrix in layers, working towards the center
for layer in 0..<(n / 2) {
... inner block of code ...
}
```

Following statement, the first in the **main loop** computes `start`

and `end`

coordinates of the current layer to be processed since these values would be needed later to calculate coordinates of the elements being exchanged:

```
// Compute layer's start and end
let start = layer, end = n - 1 - layer
```

This statement is an **inner loop** used to process each and every item of the current layer defined by range between `start`

and `end`

variables:

```
// Touch and swap each item of the current layer
for head in start..<end {
... inner block of code ...
}
```

Next statement calculates an `offset`

, that is the difference between current `head`

and `start`

positions:

```
// Calculate offset from the start
let offset = head - start
```

These statements below calculate row and column coordinates of the `last`

, `first`

, `second`

and `third`

elements accordingly. Note, however, some of the coordinates actually reuse already calculated values while others are result of simple calculations:

```
// Calculate Last eleMent's Column and Row
let lmc = head, lmr = start,
// Calculate First eleMent's Column and Row
fmc = lmr, fmr = end - offset,
// Calculate Second eleMent's Column and Row
smc = fmr, smr = end,
// Calculate Third eleMent's Column and Row
tmc = smr, tmr = lmc
```

This statment makes a copy of the `last element`

’s value, so that we can safely perform transformation of the element in this position without losing the original data:

```
// Make a copy of the Last eleMent
let lm = om[lmr][lmc]
```

Next statements perform swap operation on values of the elements following the requirement, eq. rotate by 90 degrees clockwise:

```
// Swap elements, first takes place of the last
om[lmr][lmc] = om[fmr][fmc]
// Swap elements, second takes place of the first
om[fmr][fmc] = om[smr][smc]
// Swap elements, third takes place of the second
om[smr][smc] = om[tmr][tmc]
// Swap elements, last takes place of the third
om[tmr][tmc] = lm
```

Once the **main loop** is over, we are ready to return the rotated matrix to the calling code:

```
// Here is our matrix rotated by 90 degrees clockwise
return om
```

That’s all folks! 👀

Here is a Swift playground for this article at Github: Rotate a 2D array (function).