I64 Answer ― Random Quilt


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

int main(int argc, char *argv[])
{
  const int numBlocksCol=8, numBlocksRow=8;
  int r,row,  nrows, c, col, ncols, red, grn, blu;
  FILE *image;
  
  /* colors assigned to each block */
  int   redBlock[numBlocksRow][numBlocksCol];
  int   grnBlock[numBlocksRow][numBlocksCol];
  int   bluBlock[numBlocksRow][numBlocksCol];

  /* check the command line parameters */
  if ( argc != 4 )
  {
    printf("randomColorBlocks fileName.ppm nrows ncols\n");
    return 0;
  }

  /* open the image file for writing in binary mode */
  if ( (image = fopen( argv[1], "wb") ) == NULL )
  {
    printf("file %s could not be created\n", argv[1]);
    return 0;
  }

  nrows = atoi( argv[2] );
  if ( nrows < 1 )
  {
    printf("number of rows must be positive\n");
    return 0;
  }

  ncols = atoi( argv[3] );
  if ( ncols < 1 )
  {
    printf("number of columns must be positive\n");
    return 0;
  }

  /* write out the PPM Header information */
  fprintf( image, "P6 ");
  fprintf( image, "%d %d %d ", ncols, nrows, 255 );
  srand( time(NULL) );

  /* assign colors to the blocks */
  for ( r=0; r<numBlocksRow; r++ )
    for ( c=0; c<numBlocksCol; c++ )
    {
      redBlock[r][c] = 16*(rand()%15);
      grnBlock[r][c] = 16*(rand()%15);
      bluBlock[r][c] = 16*(rand()%15);
    }

  /* write out the pixel data */
  for ( row=0; row<nrows; row++ )
    for ( col=0; col<ncols; col++ )
    {
      /* translate pixel coordinates into block coordinates */
      r   = row/(nrows/numBlocksRow);
      c   = col/(ncols/numBlocksCol);
      
      /* look up the color for this block */
      red = redBlock[r][c];
      grn = grnBlock[r][c];
      blu = bluBlock[r][c];

      /* write out the pixel */
      fputc( red, image );  fputc( grn, image );  fputc( blu, image );
    }

  /* close the file */
  fclose ( image );

  return 1;
}

Comments: On older C compilers you might have to put the 2D arrays in static memory and define their sizes with preprocessor constants.

There are other ways to solve this puzzle. Since the blocks are output in raster order, the colors of only 8 blocks need to be known at any one time. The 8x8 arrays could be replaced with 1D arrays that hold the color values for the current block-row.