The Square is Really Magic

Before moving off the topic of arrays and their bogus dimensions, I want to play further with a magic square. Specifically, it intrigues me that you can shift rows or columns within the square and it doesn’t affect the magical properties.

For example, if you move the first column to the fifth column’s position, illustrated in Figure 1, you still have a magic square. The same effect happens for the rows as well. It’s as if the square is a frame onto a pattern of numbers that can shift about without losing its charm.

Figure 1. Shifting column one in the magic square doesn’t remove the magic, nor does it change the totals of rows, columns, and diagonals.

Can you prove that rotating rows and columns works? Sure! Just add up the rows, columns, and diagonals in your head. Or — better — you can write code that does the work for you.

The first part of the code is shown below. The magic square is defined as a two-dimensional array. From previous Lessons (here and here), I explain that a 2D array is bogus, but the notation is useful when coding.

#include <stdio.h>

int main()
{
    int grid[5][5] = {
        { 25, 13,  1, 19,  7},
        { 16,  9, 22, 15,  3},
        { 12,  5, 18,  6, 24},
        {  8, 21, 14,  2, 20},
        {  4, 17, 10, 23, 11}
    };
    int temp[5];
    int row,col;

/* display grid */
    puts("Original Magic Square");
    for(row=0;row<5;row++)
    {
        for(col=0;col<5;col++)
            printf("  %2d",grid[row][col]);
        putchar('\n');
    }

/* move column 0 to column 4 */
    /* save column 0 */
    for(row=0;row<5;row++)
        temp[row] = grid[row][0];
    /* move columns 1 through 4 */
    for(col=0;col<4;col++)
        for(row=0;row<5;row++)
            grid[row][col] = grid[row][col+1];
    /* restore column 0 to column 4 */
    for(row=0;row<5;row++)
        grid[row][4] = temp[row];

/* display grid */
    puts("New Magic Square");
    for(row=0;row<5;row++)
    {
        for(col=0;col<5;col++)
            printf("  %2d",grid[row][col]);
        putchar('\n');
    }

    return(0);
}

Starting at Line 24, the code moves column 0 to the column 4 position. First, column zero is saved in the temp[] array. Then the remaining columns, 1 through 4, are shifted to the right. Finally, column zero, stored in the temp[] array, is placed at the column 4 position in the grid[][] array. I hope you agree that the 2D array notation helps make the code readable.

Here’s a sample run:

Original Magic Square
  25  13   1  19   7
  16   9  22  15   3
  12   5  18   6  24
   8  21  14   2  20
   4  17  10  23  11
New Magic Square
  13   1  19   7  25
   9  22  15   3  16
   5  18   6  24  12
  21  14   2  20   8
  17  10  23  11   4

Does the square still work? I added the numbers in my head, and it does, but of course that’s not programming. The preferred method, for this blog, is to run the confirm_magic() function on the array. This function was presented in last week’s Lesson, but it works only with single-dimension arrays.

This post is a Lesson, not an Exercise, yet I’m going to challenge you to modify the code presented to allow the confirm_magic() function to verify the new magic square. You can code the solution on your own, or just wait until next week’s Lesson to see what I did. And, no, I’m not using pointers, nor am I folding everything into the main() function.

Leave a Reply