HDTV

(ACS 1995 Solution B)

/**************************************************/
/*  1995 ACS Australian Programming Competition   */
/*   Problem B - HDTV                             */
/*   Solution by Mark Dixon, mark@cssa.anu.edu.au */
/**************************************************/

#include <stdio.h>


#define MAX 100

int array[MAX][MAX];

int xsize, ysize;

int done;
int first;

int checksum()
/* Generates a checksum of the array; a simple sum modulo 256 */ 
{
    int i, j, k;

    if ((xsize==0) || (ysize==0))
        return 0;
    /* Basis case :) */


    k = 0;
    /* Sum each element in the array */
    for(i=0;i<xsize;i++)
        for(j=0;j<ysize;j++)
            k = k + array[i][j];

    return (k%256);
}


void print()
/* Not needed for the output, but helped with debugging, and could be
   useful for expanding this program. */
{
    int i, j;

    for(j=ysize;j>=0;j--)    /* Co-ordinates are bottom-left is 0,0 */
                             /* So need to work backwards for output... */
        {
            for(i=0;i<xsize;i++)
                printf("%c", array[i][j]);
            printf("\n");
        }

    printf("\n\n");
}


char getch()
/* Get an alphabetic character from standard input */

{
    char c;

    c = getchar();
    /* Keep eating up characters until we find an alphabetic character */
    while (!isalpha(c))
        c = getchar();

    return c;
}


int getnum()
/* Get a number from standard input */
{
    int i = 0;
    char c;
    
    c = getchar();
    /* Eat up leading "garbage" ie; anything that isn't a digit */
    while(!isdigit(c))
        c = getchar();

    /* While we are still reading in digits... */
    while (isdigit(c))
        {
            /* Add this character to the number */
            i = i*10 - '0'+c;
            /* Get the next character */
            c = getchar();
        }

    /* This character is NOT a digit, and could be the next instruction */
    /* So we had better return it to the buffer */
    ungetc(c, stdin);

    return i;
}

void init() 
/* Initialise all the globals */
{
    int i, j;

    for(i=0;i<MAX;i++)
        for(j=0;j<MAX;j++)
            array[i][j]=0;
    
    xsize = 0;
    ysize = 0;

} 

void initialise()
/* Perform "initialisation" function */
{
    int i, j;

    /* Kludge way of making sure we don't print a checksum for the */
    /* first initialisation call */
    if (first)
        first = 0;
    else
        printf("checksum = %d\n", checksum());

    xsize = getnum(); /* Get the x dimension */
    ysize = getnum(); /* Get the y dimension */

    if ((xsize==0) && (ysize==0))
        done = 1; /* Finished if the dimensions are 0x0 */
    else
        /* Initialise all the elements in the array to 'A' */
        for(i=0;i<xsize;i++)
            for(j=0;j<ysize;j++)
                array[i][j] = 'A';
    

}

void fill()
/* Fill a block with one character */
{
    int i, j, x, y, w, h;
    char l;


    x = getnum(); /* X coordinate */
    y = getnum(); /* Y coordinate */
    w = getnum(); /* Width of block */
    h = getnum(); /* Height of block */
    l = getch();  /* Character to fill */

    for(i=x; i<(x+w); i++)
        for(j=y;j<(y+h);j++)
            array[i][j] = l;


}

void copy()
/* Copy from one region to another */
{
    int i, j, x, y, w, h, a, b;


    x = getnum(); /* source X coordinate */
    y = getnum(); /* source Y coordinate */
    w = getnum(); /* Width of block */
    h = getnum(); /* Height of block */
    a = getnum(); /* destination X coordinate */
    b = getnum(); /* destination Y coordinate */

    for(i=0;i<w; i++)
        for(j=0;j<h; j++)
            array[a+i][b+j] = array[x+i][ y+j];

}


void read()
/* Read a data sequence to store in the array */
{
    int i, j, x, y, w, h, c;


    x = getnum(); /* Get the X coordinate */
    y = getnum(); /* Get the Y coordinate */
    w = getnum(); /* Get the width of the block */
    h = getnum(); /* Get the height of the block */

    for(j=0;j<h;j++)
        for(i=0;i<w;i++)
            /* Read in a char from stdin and store it in the array */
            array[x+i][y+j] = getch();

}


void decompress()
/* Perform run-length decoding of a data stream into a block in the array */
{
    int i, j, k, x, y, w, h, z;
    char c;


    x = getnum(); /* X coordinate */
    y = getnum(); /* Y coordinate */
    w = getnum(); /* Width of block */
    h = getnum(); /* Height of block */

    z = 0;

    for(j=0;j<h;j++)
        for(i=0;i<w;i++)
            {  
                while (z==0) /* Have put all chars for this sequence, get */
                             /* the next sequence. */
                    {  
                        z = getnum();
                        c = getch();
                    }
                array[x+i][y+j] = c;
                z--;

            }

}



void main()
{
    char c;
    init();

    first = 1;
    done = 0;
    while (!done) {
        c = getch();
        switch(c) {
        case 'i' : initialise(); break;
        case 'f' : fill(); break;
        case 'c' : copy(); break;
        case 'r' : read(); break;
        case 'd' : decompress(); break;
        default : printf("******* UNKNOWN COMMAND *******\n");
        }

    }

}


1995 ACS Australian Programming Competition.