Clockwise rotate a matrix in Scala
Functional programming

Since you've tagged this post with functional-programming I guess that the goal of this exercise may have been to practice functional programming or to present you skills in functional programming. This way or another, I'll stick to the assumption that it was supposed to be written in the functional programming paradigm.

When working with functional code, a function returning a Unit is a huge warning sign. In functional programming we compose programs of functions which are (quoting John De Goes):


  
  Total: They return an output for every input. 
  Deterministic: They return the same output for the same input. 
  Pure: Their only effect is computing the output.
  


In FP, if a function returns a Unit, it basically means that the function does nothing, as the only thing a function can do is to return a result.

rotatedMatrix

In FP preallocating the rotatedMatrix doesn't make sens, because in order to stay Pure rotateByOne is disallowed to mutate the rotatedMatrix. And the solution is simple, the rotateByOne should allocate and return a rotated matrix.

rotateByOne

While moving the allocation of rotatedMatrix into the rotateByOne would make rotateByOne a pure function, the implementation of the function would still be clattered with state mutations, and generally much more complex than it needs to be.

So let's have a look at how it can be improved. 

Edge-case/error handling aside, I would expect the problem to be solved with a def rotateByOne(in: Array[Array[Int]]): Array[Array[Int]]. That function would have to create a new matrix of the same dimensions, finding a new value of each cell in the matrix. It's implementation could look like

  def rotateByOne(in: Array[Array[Int]]): Array[Array[Int]] = {
    val size = in.length
    (0 until size).map { i =&gt;
      (0 until size).map { j =&gt;
        newValueAt(in, i, j)
      }.toArray
    }.toArray
  }


Now all that's left is to implement the def newValueAt(in: Array[Array[Int]], i: Int, j: Int): Int which is again - a pure function - doing nothing but returning an Int. There are 5 cases to be considered, in newValueAt. Using the value of the cell:
below, above, on the right, on the left, and the same cell.  

For 3 x 3 matrix it's:

b l l
b s a
r r a


For 4 x 4 matrix it's:

b l l l
b b l a
b r a a
r r r a


After a few minutes of trial and error, I've ended up with the following implementation:

  def newValueAt(in: Array[Array[Int]], i: Int, j: Int): Int = {
    val s = in.size - 1
    if      (i &gt;= j &amp;&amp; s - i &gt;  j) in(i + 1)(j) // 'b'
    else if (i &lt;  j &amp;&amp; s - i &gt;= j) in(i)(j - 1) // 'l'
    else if (i &lt;= j &amp;&amp; s - i &lt;  j) in(i - 1)(j) // 'a'
    else if (i &gt;  j &amp;&amp; s - i &lt;= j) in(i)(j + 1) // 'r'
    else                           in(i)(j)     // 's'
  }