#include <cmath>
#include <cstdio>
#include <cstring>
int** generateSpiral(int);
void printMatrix(int**, int, char*);
void generateAndPrintSpiral(int);
int main() {
generateAndPrintSpiral(5);
generateAndPrintSpiral(6);
generateAndPrintSpiral(12);
return 0;
}
int** generateSpiral(int n) {
int** spiral = new int*[n];
for (int i = 0; i < n; i++){
spiral[i] = new int[n];
}
// Defining the directions order and offsets: Right, Down, Left, Up
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
//Adjusting the center for even inputs
int center = n % 2 == 0 ? n / 2 - 1 : n / 2;
int row, col, num = 1;
row = col = center;
//In an expanding spiral pattern, the length of a segment is increased after drawing two segments
int segmentsAfterToIncrease = 2;
int segmentCounter = 0;
int segmentLength = 1;
int dir = 0;
//As soon as we're exceeding a boundary the spiral ends
while (!(row >= n || row < 0 || col >= n || col < 0)) {
//Printing the numbers of the current segment
for (int i = 0; i < segmentLength; i++) {
spiral[row][col] = num++;
row += directions[dir][0];
col += directions[dir][1];
}
//Rotating to the next direction
dir = (dir + 1) % 4;
//Checking if we've printed the number of segments necessary to increase the length of the next segment
segmentCounter = (segmentCounter + 1) % segmentsAfterToIncrease;
if (segmentCounter == 0) {
segmentLength++;
}
}
return spiral;
}
void printMatrix(int** matrix, int n, char* format) {
printf("\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf(format , matrix[i][j]);
}
printf("\n");
}
}
void generateAndPrintSpiral(int n){
int** spiral = generateSpiral(n);
//Computing the number of digits of the highest number displayed in the spiral (the plus one is for an extra space)
int numDigitsPlusSpace = ((int)ceil(log10(pow(n, 2))) + 1);
//Converting the previous integer to a string (this is necessary only to create a dynamic format string)
// - Defining the number's length as a string
// - Creating an array to contain the string
// - Converting the number into a string
int numDigitsTemp = (int)ceil(log10(numDigitsPlusSpace));
char* numDigitsTempStr = new char[numDigitsTemp];
sprintf(numDigitsTempStr, "%d", numDigitsPlusSpace);
//Creating the format for each number (for example: "%2d ", "%5d ", etc.)
char* format = new char[numDigitsTemp + 3];
strcpy(format, "%");
strcat(format, numDigitsTempStr);
strcat(format, "d ");
printMatrix(spiral, n, format);
delete[] spiral;
}