(ou plus proprement)
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define USING "a.out <magic square's order>\n"
#define ORDER_ERROR "Error : can't create a magic quare with an order of %d. It must not be smaller than 3.\n"
#define ORDER_MESSAGE "A magic square of order %d\n"
#define CONSTANT_MESSAGE "With a magic constant of %ld\n"
int createOddMagicSquare(long **ppOut, int order)
{
if (order < 3) return -1;
int totalSize = order * order;
long *pOut = (long*) malloc(sizeof(int) * totalSize);
if (!pOut) return -2;
int i;
for (i=0; i<totalSize; i++) pOut[i] = 0;
int p = order / 2, pn;
pOut[p] = 1;
for (i=1; i<totalSize; i++)
{
pn = p;
pn += order;
pn %= totalSize;
pn = ((pn - pn % order) + (pn + 1) % order);
if(pOut[pn])
{
p -= order;
if (p < 0) p += totalSize;
}
else p = pn;
pOut[p] = i + 1;
}
*ppOut = pOut;
return 0;
}
void getStrLng(long in, char*pOut, int size)
{
pOut[size] = '\0';
int i;
for(i=size-1; i>=0 && in>0; i--, in/=10) pOut[i] = in % 10 + '0';
for(i=i; i>=0; i--) pOut[i] = ' ';
}
void printSq(FILE * stream, long *pIn, int weight, int height, unsigned short maxSzBytes)
{
char *outStr = (char*) malloc(sizeof(char) * maxSzBytes);
int i, ii, max = height-1;
for (i=0; i<weight; i++)
{
fprintf(stream, "[");
for (ii=0; ii<max; ii++)
{
getStrLng(pIn[i*weight + ii], outStr, maxSzBytes);
fprintf(stream, "%s, ", outStr);
}
getStrLng(pIn[i*weight + ii], outStr, maxSzBytes);
fprintf(stream, "%s", outStr);
fprintf(stream, "]\n");
}
}
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("Using : %s\n", USING);
return -1;
}
long *pMagic;
int order = atoi(argv[1]);
if (order < 3)
{
printf(ORDER_ERROR, order);
return -1;
}
createOddMagicSquare(&pMagic, order);
printf(ORDER_MESSAGE, order);
printf(CONSTANT_MESSAGE, (long)(order*order*order + order) / 2);
printSq(stdout, pMagic, order, order, log10(order*order) + 1);
return 0;
}