Codice PHP:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 4
struct{
int numero;
int flag;
}palla;
struct{
int numero;
struct nodo* next;//dopo
struct nodo* after;//prima
}nodo;
int index(int i, int j){
return j+i*N;
}
int getC(int index){
return index%N;
}
int getR(int index){
return index/N;
}
void freeNum(int quadrato[],struct palla urna[],int i,int j){//libera il numero voluto
if(quadrato[index(i,j)]==-1)return;
urna[quadrato[index(i,j)]].flag=0;
quadrato[index(i,j)]=-1;
}
int prelevaIndice(int indice, struct palla urna[] ){//restituisce 1 se è possibile 0 se non lo è
if((urna[indice].flag)){
urna[indice].flag=1;
return 1;
}else{
return 0;
}
}
int prelevaNumero(int numero,struct palla urna[], int indiceUrna[] ){//restituisce 1 se è possibile 0 se non lo è
prelevaIndice(indiceUrna[numero],urna);
}
int nextIndice(int indice, struct palla urna[]){//restituisce il primo indice libero, oppure alcun indice se non esiste.
if (indice>N*N) return -1;
if(!prelevaIndice(indice, urna)) return nextIndice(indice+1,urna);
return indice;
}
void freeSum(int quadrato[],struct palla urna[],int i,int j){//libera le somme di colonna di riga e di diagonale quando si cambia un numero
freeNum(quadrato,urna,i,N);
freeNum(quadrato,urna,N,j);
}
int sommaRiga(int i, struct palla urna[], int indiceUrna[]){
int x;
int sum=0;
int prova;
for(x=0;x<N-1;x++){
sum+=urna[quadrato[index(i,x)]].numero;
}
prova = (N*N*N+N)/2-sum;
if( prelevaNumero(numero,urna,indiceUrna)){
quadrato[index(i,x)]=indiceUrna[prova];
return 1;
}
else
return 0;
}
int sommaColonna(int j, struct palla urna[], int indiceUrna[]){
int x;
int sum=0;
int prova;
for(x=0;x<N-1;x++){
sum+=urna[quadrato[index(x,j)]].numero;
}
prova = (N*N*N+N)/2-sum;
if( prelevaNumero(numero,urna,indiceUrna)){
quadrato[index(x,j)]=indiceUrna[prova];
return 1;
}
else
return 0;
}
int change(quadrato,urna,i,j){//cambia la cella voluta, ma se ha già provato tutte le condizioni ritorna 0
quadrato[index(i,j)]++;
int n =urna[quadrato[index(i,j)]];
if(n>N*N) return 0;
if(prelevaIndice(n,urna))
return 1;
else
change(quadrato,urna,i,j);
}
int Rchange(quadrato,urna, i,j){//prova combinazione per combinazione, ritorna 1 se quella testata era l'ultima combinazione possibile
freeSum(quadrato,urna,i,j);
if(change(quadrato,urna,i,j))
return 0;
else
freeNum(quadrato,urna,i,j);
i++;
if(i==(N-1)){
i=0;
j++;
if(j==N) return 1;//ho finito tutte le combinazioni possibili
}
return Rchange(quadrato,urna,j,j);
}
void deleteNodo(nodo* lista){
(lista->after)->next=lista->next;//nodoprima.next=nododopo;
(lista->next)->after=lista->after;//nododopo.after=nodoprima;
free(lista);
}
main(){
struct palla urna[N*N];//contiene i numeri da 1 a N^2 da prelevare
int n_urna=N*N;
int i,j;
int indiceUrna[N*N];//alla posizione i-esima troviamo dov'è il numero i nell'urna
struct quadrato[N*N];//contiene il riferimento a un numero dell'urna...
int num=0;
int somma=0;
int numero=0;
//RIEMPIRE URNA IN MODO CASUALE
for(i=0;i<N*N;i++){
urna[i].numero=i;
urna[i].flag=0;
quadrato[i]=-1;
}
//RIEMPIRE QUADRATO CON -1
for(i=0;i<N-1;i++){
for(j=0;j<N-1;j++){
//INSERIRE ANCHE IL CONTROLLO DI COLONNA
num=nextIndice(num,urna);
somma+=urna[num];
if(somma>(N*N*N+N)/N);//ESCI DAL CICLO E CAMBIA COMBINAZIONE CAZZO
if(num=-1);//DOVREBBE USCIRE DAL CICLO E CAMBIARE COMBINAZIONE
quadrato[index(i,j)]=num;
}
if(prelevaNumero((N*N*N+N)/N-somma,urna,indiceUrna));//ESCI
quadrato[i,j]=indiceUrna[(N*N*N+N)/N-somma];
}
while(!change(quadrato,i,j)){
}
//VISUALIZZARE
system("pause");
}