One simple way to accomplish this is described in the
Wikipedia-Article.
I've written a small program in C which does exactly that.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[])
{
unsigned size = 0;
if (argc < 2 || sscanf(argv[1], "%u", &size) != 1 || size < 3 || size % 2 == 0) {
char strnum[10];
do {
printf("\nEnter an odd number (> 1): ");
fgets(strnum, 10, stdin);
}
while (sscanf(strnum, "%u", &size) != 1 || size < 3 || size % 2 == 0);
}
{
unsigned long area = (unsigned long)size * (unsigned long)size;
unsigned edge = size - 1;
unsigned x = size >> 1;
unsigned y = 0;
unsigned long i = 2;
unsigned long *c = calloc(area, sizeof (unsigned long));
if (c == NULL) {
printf("%s\n", "Failed to allocate memory!");
return -1;
}
c[x] = 1;
for (; i <= area; i++) {
unsigned long offset;
unsigned newx;
unsigned newy;
if (x != edge)
newx = x + 1;
else
newx = 0;
if (y != 0)
newy = y - 1;
else
newy = edge;
offset = newy * size;
if (c[offset + (unsigned long)newx] != 0) {
newx = x;
if (y != edge)
newy = y + 1;
else
newy = 0;
offset = newy * size;
}
c[offset + (unsigned long)newx] = i;
x = newx;
y = newy;
}
{
unsigned char padding = ceil(log10(area));
char formatstr[10];
sprintf(formatstr, "%%%dd ", padding);
for (y = 0; y < size; y++) {
unsigned offset = y * size;
for (x = 0; x < size; x++)
printf(formatstr, c[offset + x]);
printf("\n");
}
}
}
return 0;
}