D11 Answer


#include <stdio.h>
#include <stdlib.h>

#define NUMCOLS 4
#define NUMROWS 8

/* Puzzle D11 -- reverse the order of the elements in a 2D array */
int reverse2D( int x[][NUMCOLS], int nrows )
{
  int r,  c;
  int temp;

  /* Swap elements in the full rows of the first half of */
  /* the array with elements in full rows of the last half */
  for ( r=0; r<nrows/2; r++ )
    for ( c=0; c<NUMCOLS; c++ )
    {
      temp = x[r][c];
      x[r][c] = x[nrows-1-r][NUMCOLS-1-c];
      x[nrows-1-r][NUMCOLS-1-c] = temp;
    }

  /* If there are an odd number of rows, deal with the middle row */
  if ( nrows%2 == 1 )
  {
    r = nrows/2;

    for ( c=0; c<NUMCOLS/2; c++ )
    {
      temp = x[r][c];
      x[r][c] = x[nrows-1-r][NUMCOLS-1-c];
      x[nrows-1-r][NUMCOLS-1-c] = temp;
    }
  }
}


Comments: Conceptually there are two "fingers" pointing to elements of the array. One finger starts on the first element (the upper left), the other finger starts on the last element (the lower right), and the two fingers move toward each other (in raster order) swapping elements as they go.

Dealing with an odd number of rows is fairly tricky. It is hard to get this correct the first time. Another way to do this is to regard the elements in memory as a 1D array, and to reverse those elements in a 1D fashion:

int reverse2Das1D( int x[][NUMCOLS], int nrows )
{
  int j, temp ;
  for ( j=0; j<(NUMCOLS*nrows)/2; j++ )
  {
     temp    = x[0][j] ;
     x[0][j] = x[0][NUMCOLS*nrows-1-j] ;
     x[0][NUMCOLS*nrows-1-j] = temp ;
  }
}