Newsgroup: it.comp.lang.c
Titolo: Quadrato magico perchè non funzioni?



ciao a tutti. eccomi qui con un nuovo problema :( Scusatemi ma è
più forte di me... se creo un programma che non mi da problemi sin
dall'inizio non sono soddisfatto :) cmq eccovi il mio problema.


Il mio scopo è quello di creare un programma in c che stampi
un quadrato magico di dimensioni n(dispari). Per chi non lo sappia un quadrato
magico è un quadrato che ha la "peculiarità" di avere le
somme degli elementi di ogni riga uguali alle somme degli elementi di ogni
colonna e diagonale. Bhe, ora che tutti sapete cosa è un quadrato
magico, vi dirò qual'è il metodo per collocare ogni numero
(non sapete che gioia quando il prof ci disse che esisteva un metodo sicuro
per risolvere il problema... dopo tanti tentativi a casaccio :) ). Allora,
mettiamo caso che ho un quadrato di dimensioni 3                          
_ _ _


                                                           
| | | |


                                                           
|¯|¯|¯|


                                                           
|¯|¯|¯|


                                                            
¯ ¯ ¯


ok! il primo numero ( 1 ) deve essere inserito a metà della
prima riga , il secondo numero ( 2 ) nella riga sovrastante ed una colonna
a destra. Si va avanti cosi fino al numero n*n ( 9 ). Se salendo di riga
ci troviamo al difuori del quadrato posizioniamo il numero nell'ultima
riga. Se spostandoci nella colonna a destra ci troviamo al difuori del
quadrato posizionamo il numero nella prima colonna. Tutto chiaro? ... Tenute
presenti tutte queste "opzioni" se il posto in cui dovremmo mettere il
prossimo numero (es. '4') è occupato ( da '1') :( allora posizioniamo
il numero '4' nella stessa colonna del numero che lo precede, ma nella
riga sottostante.   Alla fine viene                                                           
15


                                                             
_ _ _ /


                                                            
|8|1|6| - 15


                                                            
|¯|¯|¯|


                                                            
|3|5|7| - 15


                                                            
|¯|¯|¯|


                                                            
|4|9|2| - 15


                                                             
¯ ¯ ¯ \


                                                             
| | |  15


                                                            
15 15 15


Beh, il problema è ... PERCHè NON FUNZIONA :O ...
scusatemi.


qui sotto c'è tutto il sorgente ( attenzione!!! ogni tanto
blocca tutto il sistema :)  ) Il tutto è stato compilato con
TurboC. Ah, vi do un aiutino. Quando compilo mi da un WARNING alle linee
60 e 62 : "Non-portable pointer assignment in function main". Nel listato
qui sotto le linee 60 e 62 sono numerate ( -60- -62-). Grazie mille a tutti
( anche a chi mi sta mandando a ... :) )


 

 

#include <stdio.h>


/*fUNZIONE PER CONTROLLARE CHE IL NUMERO NON SIA INSERITO IN UNA


  RIGA AL DI FUORI DEL QUADRATO  - i E' L'INDICE DI RIGA*/


int controlloy(int i,int n)


{ int y;


  if(i-1<0)


    y=n-1;


   else


    y=i-1;


  return y;


}


/*fUNZIONE PER CONTROLLARE CHE IL NUMERO NON SIA INSERITO IN UNA
COLONNA


  AL DI FUORI DEL QUADRATO - j E' L'INDICE DI COLONNA*/


int controllox(int j,int n)


{ int x;


  if(j+1>n-1)


   x=0;


  else


   x=j+1;


  return x;


}


main()


{


 int controllox(int,int);


 int controlloy(int,int);


 int i,j,n,m;                  
/* Indice di riga, di colonna, dimensioni


                                  
matrice, dimensioni matrice - 1 */


 int x,y;                      
/* Indici di appoggio per controllare se il


                                  
posto e' gia' occupato */


 int counter;                  
/* Controllare se sostituibile da numero */


 int **a;                      
/* Matrice dinamica per l'inserimento dei


   numeri */


 int numero;                   
/* Variabile che incrementata rappresenta


                                  
il numero da inserire */


  system("cls");


  printf("\t\tQUADRATo MAGICo\n");


  printf("\t Programma per la creazione di un quadrato\n\t
");


  printf("magico. Le somme di tutti gli elementi delle\n\t
");


  printf("righe, colonne e diagonali sono uguali\n\t ");


/*  TEST DELLE FUNZIONI controlloy E controllox


 ~~~~~DA CANCELLARE~~~~~


    printf("INSERISCI I J ed N SEPARATI DA UNO SPAZIO\n");


    scanf("%d %d %d", &i, &j, &n);


      j=controllox(j,n);


      i=controlloy(i,n);


    printf("i = %d , j = %d", i, j);  
CONTROLLO DELLE FUNZIONI controlloy


                                      
E controllox */


  printf("Inserisci il lato del quadrato.\n\t ");


  printf("Ricorda... il lato deve essere per forza dispari\n\t
");


    /* INSERIRE DUE RIGHE SOPRA IL CONTROLLO DISPARI
DEL NUMERO */


  printf("Inserisci la dimensione del lato: ");


  scanf("%d", &n);


  printf("\n");


  m=n-1;


-60-  a=malloc(m * sizeof(int *));  /* Allocazione di
n-1 int per la matrice a */


      for (counter = 0; counter < n
; counter++)


-62-   *(a+counter)=malloc (sizeof (int) * m);


  /* INIZIALIZZAZIONE A 0 DELLA MATRICE */


   for (i = 0; i < n ; i++)


      { for ( j = 0 ; j < n ; j ++)


   a[i][j]=0;


      }


  /* INIZIO INSERIMENTO NUMERI */


  i=0; j=n/2;


  a[i][j]=1;


  for (numero=2 ; numero <= n*n ; numero++)


   { x=controllox(j,n);


     y=controlloy(i,n);


     if ( a[y][x] != 0 )


      { x = j;


 y = i + 1;


 j=x; i=y; }


     else {


 a[y][x]=numero;


 j=x; i=y; }


   }


  /* STAMPA DEL QUADRATO */


 for (i=0; i < n; i++)


  { for (j=0 ; j < n; j++)


     {  if (j==n-1)


  { printf("%d\n", a[i][j]); }


 else {


  printf("%d\t", a[i][j]); }


     }


  }


  /* DEALLOCAZIONE DELLA MEMORIA */


/* for (i=0 ; i < n; i++)


    free (*(a+i));


   free (a);  */


}


G r a z i i i i i i e e e e e e e e e e



 
 
Il tuo programma funziona se:
- aggiungi 
#include <stdlib.h>  /* per malloc() e system> */
- correggi l'allocazione della memoria per n invece di (n-1)
  (il quadrato č n * n con indici da 0..(n-1) )
a=malloc(n*sizeof(int*));
for (counter=0; counter < n; ++counter)
	a[counter] = calloc(n, sizeof(int))
/*
 dato che calloc() alloca la memoria e la azzera puoi eliminare il
ciclo di azzeramento 
*/
- sposti 
a[y][x]=numero;
fuori dal blocco else
(come č scritto l'inserimento avviene solo per le celle a  zero)
for(numero=2; numero <=n*n; ++numero)
{ 
x=controllox(j,n);
y=controlloy(i,n);
if ( a[y][x] != 0 )
   {
   x = j;   y = i + 1;
   j=x; i=y;
   }
   else {   j=x; i=y; }
a[y][x]=numero;
}
Visto che usi il Turbo C puoi sostituire
system("cls") con
clrscr() /* aggiungi #include <conio.h>
cosě eviti di caricare una seconda copia di 
command.com
HTH gfb

 
 
Il tuo programma funziona se:
- aggiungi 
#include <stdlib.h>  /* per malloc() e system> */
- correggi l'allocazione della memoria per n invece di (n-1)
  (il quadrato č n * n con indici da 0..(n-1) )
a=malloc(n*sizeof(int*));
for (counter=0; counter < n; ++counter)
        a[counter] = calloc(n, sizeof(int))
/*
 dato che calloc() alloca la memoria e la azzera puoi eliminare il
ciclo di azzeramento 
*/
- sposti 
a[y][x]=numero;
fuori dal blocco else
(come č scritto l'inserimento avviene solo per le celle a  zero)
for(numero=2; numero <=n*n; ++numero)
{ 
x=controllox(j,n);
y=controlloy(i,n);
if ( a[y][x] != 0 )
   {
   x = j;   y = i + 1;
   j=x; i=y;
   }
