/*

Spiralna kvadratna matrica reda n x n

pocevsi od  gornjeg levog (GL) elementa M[0][0]

popunjava se u pravcu kazaljke na satu

brojevima od 1 do n x n.

*/


#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 20


// Prikazuje matricu M[][] koja ima r redova i k kolona
void prikazi_matricu( char *tekst, int M[][MAX_SIZE], int r, int k )
{
    int i, j;

    printf("\n%s\n\n",tekst);

    for(i=0;i<r;i++) {    // Stampamo matricu M[][]
        for(j=0;j<k;j++)
            printf("%4d",M[i][j]);

        printf("\n\n");   // novi red matrice
    }
    printf("\n\n");
}


// Setuje sve elemente matrice M[][] koja ima r redova i k kolona na vrednost int broj
void setuj_matricu_na_broj( int M[][MAX_SIZE], int r, int k, int broj ) {
    int i, j;

    for(i=0;i<r;i++)
        for(j=0;j<k;j++)
            M[i][j] = broj;
}




// Ovaj problem se pojednostavljuje popunjavanjem matrice prsten-po-prsten.
// Krecemo od spoljnih ivica i popunjavamo zasebno sva cetiri smera
// redosledom: desno, dole, levo, gore.
// Zatim popunjavamo sledeci prsten ...
void main (void)
{
    int M[MAX_SIZE][MAX_SIZE], n;
    int broj, r, k, r_min, k_min, r_max, k_max;

    printf("\n Unesi broj (2 <= n <= 20) redova (tj. kolona) kvadratne matrice M[][], n = ");
    scanf("%d", &n);
    printf("\n\n");

    if ( n < 2 || n > 20 ) {
        printf("\n Zbog prikaza nema smisla da red matrice bude manji od 2 ili veci od 20 !!!\n");
        exit(1);
    }

    printf("\n Red matrice je n = %d \n\n",n);

    // Setujemo sve elemente matrice M na nulu da bi smo se kretali po matrici
    // proveravajuci uslov: while( M[r][k] == 0 )
    setuj_matricu_na_broj(M,n,n,0);
//    prikazi_matricu(" Matrica sa nulama je: ", M, n, n);


    // pocetne vrednosti
    broj=1;         // broj koji se upisuje u matricu M
    r=0;            // tekuci red
    k=0;            // tekuca kolona
    r_min = 0;      // minimalni red        // granice tekuceg prstena
    k_min = 0;      // minimalna kolona
    r_max = n-1;    // maksimalni red
    k_max = n-1;    // maksimalna kolona

    while ( broj < n*n ){   // broj ide od 1 do n*n

        // u desno
        while( M[r][k] == 0  &&  k <= k_max )
            M[r][k++] = broj++;

        // na dole
        r++;    // povecavamo tekuci red jer idemo na dole
        k--;    // smanjujemo tekucu kolonu jer smo je poslednji put nepotrebno uvecali
        while( M[r][k] == 0  &&  r <= r_max )
            M[r++][k] = broj++;

        // u levo
        r--;    // smanjujemo tekuci red jer smo ga poslednji put nepotrebno uvecali
        k--;    // smanjujemo tekucu kolonu jer idemo u levo
        while( M[r][k] == 0  &&  k >= k_min )
            M[r][k--] = broj++;

        // na gore
        r--;    // smanjujemo tekuci red jer idemo na gore
        k++;    // povecavamo tekucu kolonu jer smo je poslednji put nepotrebno smanjili
        while( M[r][k] == 0  &&  r >= r_min )
            M[r--][k] = broj++;

        r_min++;     // popunili smo spoljni okvir matrice M i sada ga suzavamo
        k_min++;
        r_max--;
        k_max--;

        r = r_min;  // nove pocetne vrednosti za sledeci unutrasnji prsten matrice M
        k = k_min;
    }

    // Ako je n neparno, gornji algoritam ostavlja nepopunjen broj
    // u centru matrice M[n/2][n/2] i zato ga sada popunimo:
    if ( n % 2 )   // ako je n neparno
        M[n/2][n/2] = n*n;

    prikazi_matricu(" Spiralna matrica je: ", M, n, n);
}