# GeeksforGeeks: Rotate matrix by 90 degrees

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ArrayQuestions
{
/// <summary>
/// https://www.geeksforgeeks.org/inplace-rotate-square-matrix-by-90-degrees/
/// </summary>
[TestClass]
public class RotateMatrix90
{
[TestMethod]
public void Rotate3x3Test()
{
int[,] mat =
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[,] expected =
{
{3, 6, 9},
{2, 5, 8},
{1, 4, 7}
};
rotateMatrix(mat);
for (int r = 0; r < mat.GetLength(0); r++)
{
for (int c = 0; c < mat.GetLength(1); c++)
{
Assert.AreEqual(expected[r, c], mat[r, c]);
}
}

}

void rotateMatrix(int[,] mat)
{
int size = mat.GetLength(0);
for (int x = 0; x < size / 2; x++)
{
for (int y = x; y < size - x - 1; y++)
{
int temp = mat[x, y];             // save 1
mat[x, y] = mat[y, size - x - 1]; // move 3 into 1
mat[y, size - x - 1] = mat[size - x - 1, size - y - 1]; // move 9 into 3
mat[size - x - 1, size - y - 1] = mat[size - y - 1, x]; // move 7 into 9
mat[size - y - 1, x] = temp;
}
}
}
}
}

• Obligatory xkcd: xkcd.com/184 – Acccumulation May 22 '19 at 22:21
• @Acccumulation omg that's the best!! funny man! – Gilad May 23 '19 at 9:41

A simple improvement for readability could be to eliminate the - 1 in the indices by replacing size with max = mat.GetLength(0) - 1;:

void rotateMatrix(int[,] mat)
{
int max = mat.GetLength(0) - 1;
for (int x = 0; x < (max + 1) / 2; x++)
{
for (int y = x; y < max - x; y++)
{
int temp = mat[x, y];             // save 1
mat[x, y] = mat[y, max - x]; // move 3 into 1
mat[y, max - x] = mat[max - x, max - y]; // move 9 into 3
mat[max - x, max - y] = mat[max - y, x]; // move 7 into 9
mat[max - y, x] = temp;
}
}
}


You could also make a pair of vars for max - x and max - y as :

void rotateMatrixReview(int[,] mat)
{
int max = mat.GetLength(0) - 1;
for (int x = 0; x < (max + 1) / 2; x++)
{
for (int y = x; y < max - x; y++)
{
int xmax = max - x;
int ymax = max - y;
int temp = mat[x, y];             // save 1
mat[x, y] = mat[y, xmax]; // move 3 into 1
mat[y, max - x] = mat[xmax, ymax]; // move 9 into 3
mat[xmax, ymax] = mat[ymax, x]; // move 7 into 9
mat[max - y, x] = temp;
}
}
}


Just for the fun: another approach could be:

void Swap(int[,] mx, int r1, int c1, int r2, int c2)
{
int tmp = mx[r1, c1];
mx[r1, c1] = mx[r2, c2];
mx[r2, c2] = tmp;
}

void rotateMatrix(int[,] mat)
{
int m = mat.GetLength(0) - 1;

// l = level in the matrix from outer = 0 to inner
for (int l = 0; l < (m + 1) / 2; l++)
{
// o = offset along rows and cols
for (int o = 0; o < m - 2 * l; o++)
{
Swap(mat, l, l + o, l + o, m - l);
Swap(mat, m - l - o, l, m - l, m - l - o);
Swap(mat, l + o, m - l, m - l - o, l);
}
}
}

• thanks as always! – Gilad May 23 '19 at 12:21