Doing Some C

Trying out some C, I did svpino’s problem from a couple weeks ago.

Write a function to rotate an NxN matrix by 90 degrees. You should rotate it in place, meaning you can’t use another matrix to perform the rotation, but instead you have to use the same given structure.


#include <stdio.h>
#include <math.h>

int
main(void) {
  
  void rotate(int *mat, int side);
  
  #define Side 4
  
  int mat[Side][Side] = {
    { 1,  2,  3,  4},
    { 5,  6,  7,  8},
    { 9, 10, 11, 12},
    {13, 14, 15, 16}
  };
  
  #define PrintMatrix                                                                   \
  for (int y = 0; y < Side; y++) {                                                      \
    for (int x = 0; x < Side; x++)                                                      \
      mat[y][x] < 10 ?                                                                  \
      printf(" %d ", mat[y][x]) :                                                       \
      printf( "%d ", mat[y][x]);                                                        \
    printf("\n");                                                                       \
  }
  
  PrintMatrix;
  
  rotate(&mat[0][0], Side);
  
  printf("\n");
  
  PrintMatrix;
  
}
void
rotate(int *mat, const int side) {
  
  const int xLim = (side - 1) / 2, yLim = (side - 2) / 2;
  
  const int rotId = side - 1;
  
  int *from, *to, y, x, lY, lX, tY;
  
  #define Swap(a, b)  (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
  
  for (x = 0; x <= xLim; ++x) for (y = 0; y <= yLim; ++y)

    for (lY  = y,   lX  = x,  tY = rotId - lX;
         tY != y || lY != x;
         lX  = lY,  lY  = tY, tY = rotId - lX) {
      
      from = mat + lX + side * lY, to = mat + lY + side * tY;
      
      Swap(*from, *to);
      
    }
  
}

I tried to keep it to as “in-place” as possible. There’s no new matrix generated – there’s not even a temp variable when swapping two variables within the matrix. (I took the swap macro from here, which also has some other great ideas) Here’s what the output looks like:

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

13  9  5  1
14 10  6  2
15 11  7  3
16 12  8  4
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s