#include <iostream>
#include <cassert>
using namespace std;
template<typename T>
void printMatrix(T data, const int cols, const int rows)
{
for(int j = 0; j < rows; ++j)
{
for(int i = 0; i < cols; ++i)
{
cout << data[j * cols + i] << '\t';
}
cout << '\n';
}
}
/*
rotate src matrix 90 degrees clockwise and store in dest
Assumes dest has sufficient space.
*/
template<typename T>
void rotateMatrix(T dest, T src, int cols, int rows)
{
/*
rotate -
y' = x
x' = -y
*/
// one loop, but costs a mod and a div
for(int i = 0; i < rows * cols; ++i)
{
// source coordinates
int x = i % cols;
int y = i / cols;
// destination coordinates
int x1 = (rows - 1) - y;
int y1 = x;
dest[y1 * rows + x1] = src[y * cols + x];
}
}
// or, if you'd prefer a nested loop to division:
template<typename T>
void rotateMatrixLoop(T dest, T src, int cols, int rows)
{
for(int j=0; j < rows; ++j)
{
int dx = (rows - 1) - j;
for(int i = 0; i < cols; ++i)
{
int dy = i;
dest[dy * rows + dx] = src[j * cols + i];
// for a 2d Array, you'd just
// dest[dy][dx] = src[j][i];
}
}
}
// pointlessly optimized version
template<typename T>
void rotateMatrixSilly(T dest, T src, int cols, int rows)
{
int srcOffset = 0;
for(int j=0; j < rows; ++j)
{
int destOffset = rows - 1 - j;
for(int i = 0; i < cols; ++i)
{
dest[destOffset =+ rows] = src[srcOffset++];
}
}
}
int main()
{
int cols = 2;
int rows = 3;
char source[] {
'a', 'b',
'c', 'd',
'e', 'f',
};
char dest[sizeof(source) / sizeof(source[0])];
int destRows = cols;
int destCols = rows;
cout << "Original matrix:\n";
printMatrix(source,cols,rows);
cout << "Rotated matrix with division:\n";
rotateMatrix(dest, source, cols, rows);
printMatrix(dest, destCols, destRows);
cout << "Rotated matrix with nested loop\n";
rotateMatrixLoop(dest, source, cols, rows);
printMatrix(dest, destCols, destRows);
cout << "Slightly optimized rotation...\n";
rotateMatrixSilly(dest, source, cols, rows);
printMatrix(dest, destCols, destRows);
return 0;
}