A Grid of Random Stars, Part II

To count all possible rectangles in a random grid requires a lot of scanning. My first thought was that the process would involve recursion. I wasn’t 100 percent certain, but I wanted to prep the code for such a possibility.

The first issue to deal with is the two-dimensional array, grid[][]. It’s difficult to pass such a beast to a function. A single-dimension array can be passed, similar to a pointer. As the overhead required to calculate row/column offsets is identical for a one-dimension array as it would be for a pointer, I converted grid[][] into *grid.

Another modification I made was to place the output statements into their own function:

2024_05_25-Lesson.c

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

#define ROWS 16
#define COLS ROWS*2
#define SIZE COLS*ROWS
#define PROB 5

void output_grid(char *g)
{
    int r,c;

    for( r=0; r<ROWS; r++ )
    {
        for( c=0; c<COLS; c++ )
        {
            putchar( *(g+r*COLS+c) );
        }
        putchar('\n');
    }

}

int main()
{
    char *grid;
    int row,col;

    /* seed the randomizer */
    srand( (unsigned)time(NULL) );

    /* allocate grid */
    grid = malloc( sizeof(char) * SIZE );
    if( grid==NULL )
    {
        fprintf(stderr,"Unable to allocate memory\n");
        exit(1);
    }

    /* fill the grid */
    for( row=0; row<ROWS; row++ )
    {
        for( col=0; col<COLS; col++ )
        {
            if( rand() % PROB )
                *(grid+row*COLS+col) = '.';
            else
                *(grid+row*COLS+col) = '*';
        }
    }

    /* output the grid */
    output_grid(grid);

    /* close it up */
    free(grid);
    return 0;
}

To allocate storage for the grid, I added defined constant SIZE. It’s set equal to the number of columns (COLS) and rows (ROWS) in the grid, also defined constants. The malloc() function allocates a character buffer for the grid:

grid = malloc( sizeof(char) * SIZE );

I don’t need to add one to the buffer size as it’s not a character array.

To reference cells in the grid requires a bit of math. Here’s the format I use in the code:

*( base + current_row * column_count + current_column )

The base is the member buffer’s address, stored in the pointer. current_row is the row to place the character. column_count is the total number of columns. current_column is the column to place the character. This expression determines the proper offset within the buffer, base. It’s used to fill the grid with asterisk or period characters. It’s also used in the output_grid() function.

This update to the code generates the same output as the original code, but now it’s prepped for me to add functions that start scanning for matching asterisks. These must be included in a second nested loop that scans the grid for asterisk characters. I present this update in next week’s Lesson.

Leave a Reply