1

I am writing a short program that rotates a given NxN matrix the following way:

┌     ┐    ┌     ┐ 
|1 2 3|    |4 1 2| 
|4 5 6| -> |7 5 3| 
|7 8 9|    |8 9 6|   
└     ┘    └     ┘

var a = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

for (var i = 0; i < a.length; i++) {
  for (var j = 0; j < a[i].length; j++) {
    document.write(a[i][j]);
  }
  document.write('<br>');
};

I got the loop sorted and the array but I cannot figure out how to rotate it clockwise. It is really becoming a headache.

All help is appreciated. :)

Ele
  • 31,191
  • 6
  • 31
  • 67

1 Answers1

1

You could move each side and use an offset for the rings.

This approach takes four loops, one for every side of the matrix and stores previously the value of the top left position of each ring.

Then all item are moved and the the item of all ther sides are moved as well. Finally, at the last loop, the saved item is move to a new position.

Example of the algorithm:

2D Array  1  2  3  4  5
          6  7  8  9 10
         11 12 13 14 15
         16 17 18 19 20
         21 22 23 24 25
------- ---------------- ---------------- ---------------- ---------------- ----------------
         take value for   1st loop         2nd loop         3rd loop         4th loop
         insert in 4th    left side up     bottom left      right down       top right
------- ---------------- ---------------- ---------------- ---------------- ----------------
Ring 0  [ 1] 2  3  4  5    6  .  .  .  .    .  .  .  .  .    .  .  .  .  .    .[ 1] 2  3  4
          6  .  .  . 10   11           .    .           .    .           5    .           .
         11  .  .  . 15   16           .    .           .    .          10    .           .
         16  .  .  . 20   21           .    .           .    .          15    .           .
         21 22 23 24 25    .  .  .  .  .   22 23 24 25  .    .  .  .  . 20    .  .  .  .  .

Ring 1    .  .  .  .  .                                                      
          .[ 7] 8  9  .      12  .  .          .  .  .          .  .  .          .[ 7] 8
          . 12  . 14  .      17     .          .     .          .     9          .     .
          . 17 18 19  .       .  .  .         18 19  .          .  . 14          .  .  .
          .  .  .  .  .
------- ---------------- ---------------- ---------------- ---------------- ----------------
Result    6  1  2  3  4
         11 12  7  8  5
         16 17 13  9 10
         21 18 19 14 15
         22 23 24 25 20

function rotate(array) {

    function rotateRing(offset) {
        var i = offset,
            j = offset,
            l = array.length - offset,
            last = array[i][j];

        for (; i + 1 < l; i++) array[i][j] = array[i + 1][j];
        for (; j + 1 < l; j++) array[i][j] = array[i][j + 1];
        for (; i > offset; i--) array[i][j] = array[i - 1][j];
        for (; j > offset; j--) array[i][j] = j - 1 === offset ? last : array[i][j - 1];
    }

    for (var i = 0, l = array.length >> 1; i < l; i++) rotateRing(i);
    return array;
}

function print(array) {
    array.forEach(a => console.log(...a.map(v => v.toString().padStart(2))));
    console.log('');
}

var array3 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
    array4 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]],
    array5 = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]];

print(array3);
rotate(array3);
print(array3);

print(array4);
rotate(array4);
print(array4);

print(array5);
rotate(array5);
print(array5);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324
  • this answer if fantastic, but I did not study this yet. is there possibly any way to simplify it? – Valiant Lupori Buzzactaxe Feb 27 '20 at 07:59
  • you could delete the ouput parts, but it stays as it it, because you need a loop for each side to move and the same for each ring in the matrix. but if you may have a shorter approach, i am open. – Nina Scholz Feb 27 '20 at 08:18