Fill My Grid – Solution

The puzzle for this month’s Exercise was to create and fill a 20-by-20 character grid with 20 asterisks placed at random positions, no two asterisks in the same spot. I hope you found this Exercise interesting, but not too easy.

Here is my solution for Part A:

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

#define SIZE 20

int main()
{
    char grid[SIZE][SIZE];
    int column,row,count;

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

    /* initialize the grid */
    for(column=0;column<SIZE;column++)
        for(row=0;row<SIZE;row++)
            grid[column][row] = '.';

    /* place the random asterisks */
    count = 0;
    while(count < SIZE)
    {
        column = rand() % SIZE;
        row = rand() % SIZE;
        if( grid[column][row] != '*' )
        {
            grid[column][row] = '*';
            count++;
        }
    }

    /* display the grid */
    for(column=0;column<SIZE;column++)
    {
        for(row=0;row<SIZE;row++)
            printf(" %c ",grid[column][row]);
        putchar('\n');
    }

    return(0);
}

The randomizer is initialized at Line 13. The 20-by-20 grid, with the value 20 set as the SIZE constant, is initialized in Lines 16 through 18.

Variable count tracks the number of asterisks placed, initialized at Line 21. Then a while loop spins as random locations are obtained in Lines 24 and 25. The grid location is tested at Line 26 to see whether an asterisk is already set at that location. If not, it’s set at Line 28 and variable count is increased at Line 29.

Lines 34 through 39 display the results.

I trust you coded a similar solution. The asterisk itself acts as a flag to determine whether a specific grid location is set. And the while loop keeps spinning as random locations are fetched until that last spot is found.

To complicate matters, the Part B challenge to this Exercise required that the random location’s row and column be free of asterisks as well. You can use the code from the Part A solution to start your Part B solution, which is what I did. Extra overhead is required to scan not only the current row/column position but all the same row and column positions for any asterisks.

To perform the extra tests, I modified the while loop by adding two for loops. One scans the current row and the other scans the current column. If an asterisk is found in either row or column, a found flag is set. If the found flag remains zero, meaning both the row and column are devoid of asterisks, the asterisk is set at the random row/column intersection. Here’s the modified while loop:

    while(count < SIZE)
    {
        column = rand() % SIZE;
        row = rand() % SIZE;
        found = 0;
        if( grid[column][row] != '*' )
        {
            for(c=0;c<SIZE;c++)
                if( grid[row] == '*' )
                    found++;
            for(r=0;r<SIZE;r++)
                if( grid[column][r] == '*' )
                    found++;
            if( !found )
            {
                grid[column][row] = '*';
                count++;
            }
        }
    }

Variable found is initialized to zero just after the random row and column variables are set.

The first if test checks the specific row and column position for an asterisk. After all, if it’s already set, why scan the rows and columns?

Next, the row is scanned for asterisks. If one is present, the found variable is incremented. I could have stopped the loop once an asterisk is found. That’s because the code’s logic insists that no two asterisks will ever dwell in a single row or column. Still, time isn’t an issue in this code, so the loop keeps spinning.

The column is scanned in the same manner as the row. This for loop could be avoided when an asterisk was found in the current row. Again, time isn’t an issue in the code so I didn’t add the necessary statements to skip this loop.

Finally, the found variable is tested with “if not found.” When true, the rows and columns are clear, meaning the asterisk can be set.

Click here to view my entire solution for Part B.

I hope that you enjoyed this Exercise and devised a solution that not only worked, but offered a clever way to solve the challenge.

2 thoughts on “Fill My Grid – Solution

  1. Another possible solution which occurred to me is to maintain two additional 1D arrays of bools to flag which rows and columns have been used. This would avoid having to scan an entire row or column but is probably only worthwhile for much larger grids than 20×20.

  2. That approach is excellent, Chris, and would be far more efficient especially when the grid size increases. In fact, that would almost inspire me to concoct a new 8 Queens solution! Thanks.

Leave a Reply