The Recursive Version of the Magic Square Function
From exercise 8 of Chapter 1.4.3 in Fundamentals of Data Structures in C.
/* Filename: exer-1.4.3-8.c
Description: A recursive version of the magic square program (Program 1.22)
Source: Exercise 8 of 1.4.3 from Fundamentals of Data Structures in C
Version: 1.0.0
Author: imacat <imacat@mail.imacat.idv.tw>
Date: 2010-02-03
Copyright: (c) 2010 imacat */
/* Headers */
#include <stdio.h>
#include <stdlib.h>
/* Configuration */
#define MAX_SIZE 15
/* Prototypes */
void *xmalloc (size_t size);
void gen_magic_square (int **square, int size, int *i, int *j, int index);
/* Main program */
int
main (int argc, char *argv[])
{
int **square;
int size, i, j;
while (1) {
printf ("Enter the size of the square: ");
scanf ("%d", &size);
if (size < 1 && size > MAX_SIZE + 1) {
fprintf (stderr, "Please input a size between 1 and %d.\n", MAX_SIZE);
} else if (size % 2 == 0) {
fprintf (stderr, "Please input an odd size.\n");
} else {
break;
}
}
/* Initialize the square */
square = (int **) xmalloc (sizeof (int *) * size);
for (i = 0; i < size; i++) {
square[i] = (int *) xmalloc (sizeof (int) * size);
for (j = 0; j < size; j++) {
square[i][j] = 0;
}
}
i = 0;
j = (size - 1) / 2;
gen_magic_square (square, size, &i, &j, size * size);
/* Output the magic square */
printf ("Magic Squre of size %d:\n\n", size);
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
printf ("%5d", square[i][j]);
}
printf ("\n");
}
printf ("\n");
return 0;
}
/* xmalloc: malloc() and handles the error.
return: the pointer. */
void *
xmalloc (size_t size)
{
void *p;
p = malloc (size);
if (p == NULL) {
fprintf (stderr, "Failed allocate %ld bytes memory.\n", size);
exit (1);
}
return p;
}
/* gen_magic_square: Generate the magic square.
return: none. */
void
gen_magic_square (int **square, int size, int *i, int *j, int count)
{
int i1, j1;
if (count == 1) {
square[*i][*j] = count;
return;
}
/* Get into the next number */
gen_magic_square (square, size, i, j, count - 1);
i1 = (*i > 0)? *i - 1: size - 1;
j1 = (*j > 0)? *j - 1: size - 1;
if (square[i1][j1] != 0) {
j1 = *j;
i1 = *i + 1;
if (i1 >= size) {
i1 = 0;
}
}
*i = i1;
*j = j1;
square[*i][*j] = count;
return;
}