View Full Version : [C] Modificare valore all'interno di una matrice
Il codice che ho scritto è questo, dopo l'inserimento di una griglia di valori esempio
1 2 1 2
3 4 5 6
1 3 9 8
7 2 7 6
devo implementare delle tecniche per risolvere un gioco che si chiama Hitori
la griglia è sempre quadrata di varie dimensioni
La funzione panino imbottito implementa una tecnica che trova un valore da "non annerire" in mezzo a due numeri uguali
Per non annerire intendo marcarli in qualche modo ad esempio -2- in modo da stampare in output in questo modo
come faccio a marcarlo e tenere in memoria questo per poi stamparlo a video così:
1 -2- 1 2
-3- 4 5 6
1 3 9 8
7 -2- 7 6
Suggerimenti!!!!
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef int** TMatrice; /* tipo matrice, vettore di puntatori */
/*============================ Dichiarazione delle funzioni (prototipi) ===============================*/
TMatrice alloca_matrice(int n); /* Alloca memoria per una matrice */
void libera_matrice(TMatrice *matrice, int n); /* Libera la memoria allocata */
void inserimento(TMatrice matrice, int n);
void stampa_matrice (TMatrice matrice , int n);
void panino_imbottitorighe(TMatrice matrice, int n);
void panino_imbottitocolonne(TMatrice matrice, int n);
/*=====================================================================================================*/
/*==================== MAIN ===================== */
int main()
{
TMatrice matrice;
int n;
printf("Dimensione griglia?\n");
scanf("%d" , &n);
matrice = alloca_matrice(n);
inserimento(matrice, n);
panino_imbottitorighe(matrice,n);
panino_imbottitocolonne(matrice,n);
printf("\n");
stampa_matrice(matrice, n);
libera_matrice(&matrice, n);
return 0;
}
/*
Alloca la memoria per una matrice di dimensione n e ne restituisce
un puntatore.
*/
TMatrice alloca_matrice(int n)
{
TMatrice matrice;
int i;
/* alloco il vettore delle righe. Ogni elemento di questo vettore è un puntatore */
if(!(matrice = (TMatrice) malloc (n * sizeof(int *)))) {
fprintf(stderr,"Errore di allocazione per la matrice\n");
return 0;
}
/* per ogni riga alloco le colonne */
for (i=0; i<n; i++) {
if(!(matrice[i] = (int *) malloc (n * sizeof(int)))) {
fprintf(stderr,"Errore di allocazione per la i-esima posizione \"%d\"\n",i);
return 0;
}
}
return matrice;
}
/* Libera la memoria allocata da alloca_matrice */
void libera_matrice(TMatrice *matrice, int n)
{
int i;
for (i=0; i<n; i++)
free((*matrice)[i]);
free(*matrice);
}
/* Inserimento dei valori all'interno della matrice*/
void inserimento(TMatrice matrice, int n){
int i,j;
for(i=0 ; i<n ; i++)
for(j=0 ; j<n ; j++)
{
scanf("%d",&matrice[i][j]);
}
printf("\n");
}
/* stampa del risultato della matrice */
/* in realtà alla fine dovrà stampare la metrice con degli zero che corrispondono alle caselle annerite*/
void stampa_matrice(TMatrice matrice, int n){
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
printf("%d ", matrice[i][j]);
printf("\n");
}
}
/*===================== implementazione dell tecniche di risoluzione ================*/
/* numero non annerito = -1- */
/* numero annerito = *1* */
/* numero che non si sa ancora se annerito o no = 1 */
/* [PI] PANINO IMBOTIITO*/
void panino_imbottitorighe(TMatrice matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if(matrice[i][j] == matrice[i][j+2]) /* controlla se i valori inseriti sono uguali sulle righe*/
printf("%s%d%s%d%s", "no (" , i , ", " , j+1,") : PI\n");
}
void panino_imbottitocolonne(TMatrice matrice, int n){
int i,j;
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if(matrice[i][j] == matrice[i+2][j]) /* controlla se i valori inseriti sono uguali sulle colonne*/
printf("%s%d%s%d%s", "no (" , i+1 , ", " , j,") : PI\n");
}
Per marcare hai varie tecniche: invece di creare una matrice di interi puoi creare una matrice di struct. La struct può essere composta da due interi, uno per il valore ed uno per la marcatura (0 non marcato, 1 marcato).
In alternativa può usare due matrici distinte, una per i valori ed una per le marcature.
la funzione non annerire che mi mette matrice.marcatura a 0 come va scritta perchè assegnandoli semplicemente il valore 0 mida segmentation fault!!!:muro:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct CELLA{
int valore;
int marcatura; /* assume il valore 0=non annerito 1=annerito */
}CELLA;
/*============================ Dichiarazione delle funzioni (prototipi) ===============================*/
CELLA** alloca_matrice(int n); /* Alloca memoria per una matrice */
void libera_matrice(CELLA** matrice, int n); /* Libera la memoria allocata */
void input(CELLA** matrice, int n);
void stampa_matrice(CELLA** matrice , int n);
void panino_imbottitorighe(CELLA** matrice, int n);
void panino_imbottitocolonne(CELLA** matrice, int n);
/*=====================================================================================================*/
/*==================== MAIN ===================== */
int main()
{
CELLA** matrice;
int n;
printf("Dimensione griglia?\n");
scanf("%d" , &n);
matrice = alloca_matrice(n);
input(matrice, n);
panino_imbottitorighe(matrice,n);
panino_imbottitocolonne(matrice,n);
printf("\n");
stampa_matrice(matrice, n);
libera_matrice(matrice, n);
return 0;
}
/*
Alloca la memoria per una matrice di struct CELLA di dimensione n e ne restituisce
un puntatore.
*/
CELLA** alloca_matrice(int n)
{
CELLA **matrice;
int i;
/* alloco un array di n puntatori alla struttra CELLA e assegno il puntatore a una varibile matrice di tipo CELLA ** */
if(!(matrice = (CELLA **) malloc (n * sizeof(CELLA*)))) {
fprintf(stderr,"Errore di allocazione per la matrice\n");
return 0;
}
/* per ogni elemento matrice[i] dell'array si alloca un array di n elementi di tipo CELLA il cui indirizzo viene posto in matrice[i] */
for(i=0; i<n; i++) {
if(!(matrice[i] = (CELLA*) malloc (n * sizeof(CELLA)))) {
fprintf(stderr,"Errore di allocazione per la i-esima posizione \"%d\"\n",i);
return 0;
}
}
return matrice;
}
/* Libera la memoria allocata da alloca_matrice */
void libera_matrice(CELLA** matrice, int n)
{
int i;
for (i=0; i<n; i++)
free((matrice)[i]);
free(matrice);
}
/* Inserimento dei valori all'interno della matrice*/
void input(CELLA** matrice, int n){
int i,j;
for(i=0 ; i<n ; i++)
for(j=0 ; j<n ; j++)
{
scanf("%d",&matrice[i][j]);
}
printf("\n");
}
/* stampa del risultato della matrice */
void stampa_matrice(CELLA** matrice, int n){
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
printf("%d ", matrice[i][j]);
printf("\n");
}
}
/*===================== implementazione dell tecniche di risoluzione ================*/
/* numero non annerito = -1- */
/* numero annerito = *1* */
/* numero che non si sa ancora se annerito o no = 1 */
/* [PI] PANINO IMBOTIITO*/
void panino_imbottitorighe(CELLA** matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if(matrice[i][j].valore == matrice[i][j+2].valore) /* controlla se ci sono valori uguali a distanza 2 sulle righe*/
printf("%s%d%s%d%s", "no (" , i , ", " , j+1,") : PI\n");
/* richiamo la funzione non annerire */
/************************************************************/
non_annerire( );
}
void panino_imbottitocolonne(CELLA** matrice, int n){
int i,j;
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if(matrice[i][j].valore == matrice[i+2][j].valore) /* controlla se ci sono valori uguali a distanza 2 sulle colonne*/
printf("%s%d%s%d%s", "no (" , i+1 , ", " , j,") : PI\n");
}
int non_annerire(CELLA** matrice, int n){
}
Non avevo visto che può avere tre stati. Fai così: 0 ancora da capire se va annerito o meno, 1 non annerito, 2 annerito.
E' sbagliata la funzione di lettura:
/* Inserimento dei valori all'interno della matrice*/
void input(CELLA** matrice, int n){
int i,j;
for(i=0 ; i<n ; i++)
for(j=0 ; j<n ; j++)
{
scanf("%d",&matrice[i][j].valore);
matrice[i][j].marcatura = 0;
}
printf("\n");
}
Ho cambiato alcune funzioni in modo da far stampare i numeri di cui so quali annerire e quali no,il problema è che applica due regole diverse sullo stesso input:
esempio
input
1 2 1
4 2 4
8 9 9
output
no (0, 1) : PI
si (1, 1) : SB
no (1, 1) : PI questa
si (0, 1) : SB e questa non dovrebbe applicarle
1 *2* 1
4 -2- 4
8 9 9
output giusto dovrebbe essere:
1 -2- 1
4 *2* 4
8 9 9
/* Inserimento dei valori all'interno della matrice*/
void input(CELLA** matrice, int n){
int i,j;
for(i=0 ; i<n ; i++)
for(j=0 ; j<n ; j++)
{
scanf("%d",&matrice[i][j].valore);
matrice[i][j].marcatura = 0;
}
printf("\n");
}
/* stampa del risultato della matrice */
void stampa_matrice(CELLA** matrice, int n){
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
if (matrice[i][j].marcatura == 1)
printf("%s%d%s ","-", matrice[i][j].valore, "-");
else if(matrice[i][j].marcatura == 2)
printf("%s%d%s ","*", matrice[i][j].valore, "*");
else if(matrice[i][j].marcatura == 0)
printf("%d ", matrice[i][j].valore);
printf("\n");
}
}
/*===================== Implementazione dell tecniche di risoluzione ================*/
/* numero non annerito = -1- */
/* numero annerito = *1* */
/* numero che non si sa ancora se annerito o no = 1 */
/* FUnzione che oltre a colorare la cella(i,j) come annerita,applica poi ricorsivamente le regole NV e A. */
void annerisci(CELLA** matrice,int i , int j){
matrice[i][j].marcatura = 2;
printf("%s%d%s%d%s", "si (" , i , ", " , j,") : SB\n");
}
/* [SB] SOLO UN BIANCO */
void solo_un_bianco(CELLA** matrice, int n,int a,int b){
int i,j;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(!(i==a && j==b) && (i==a || j==b) && matrice[i][j].valore == matrice[a][b].valore)
annerisci(matrice, i ,j);
}
/* Funzione che oltre a marcare la cella(i,j) come non annerita, applica poi ricorsivamente la regola SB.*/
void non_annerire (CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 1;
printf("%s%d%s%d%s", "no (" , i , ", " , j,") : PI\n");
solo_un_bianco(matrice,n,i,j);
}
/* [PI] PANINO IMBOTIITO*/
void panino_imbottito(CELLA** matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if(matrice[i][j].valore == matrice[i][j+2].valore) /* controlla se ci sono valori uguali a distanza 2 sulle righe*/
/* richiamo la funzione non_annerire */
non_annerire(matrice,n,i,j+1);
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if(matrice[i][j].valore == matrice[i+2][j].valore) /* controlla se ci sono valori uguali a distanza 2 sulle colonne*/
/* richiamo la funzione non_annerire*/
non_annerire(matrice,n,i+1,j);
}
trovato :D dovrebbe essere così
/* [PI] PANINO IMBOTIITO*/
void panino_imbottito(CELLA** matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if((matrice[i][j].valore == matrice[i][j+2].valore) && matrice[i][j+1].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle righe*/
/* richiamo la funzione non_annerire */
non_annerire(matrice,n,i,j+1);
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if((matrice[i][j].valore == matrice[i+2][j].valore) && matrice[i+1][j].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle colonne*/
/* richiamo la funzione non_annerire*/
non_annerire(matrice,n,i+1,j);
}
Ho un altro problema ho scritto questo:
Il problema è che mi ripete tante volte ricorsivamente, perchè NV chiama non_annerire che richiama a sua volta solo_un_bianco.
FOrse devo mettere un controllo per vedere da dove arriva...ma come??????:mc:
/* Funzione che oltre a marcare la cella(i,j) come non annerita, applica poi ricorsivamente la regola SB.*/
void non_annerire(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 1;
/* caso che vine da PI*/
printf("%s%d%s%d%s", "no (" , i , ", " , j,") : PI\n");
solo_un_bianco(matrice,n,i,j);
/* caso che viene da NV*/
/*printf("%s%d%s%d%s", "no (" , i , ", " , j,") : NV\n");*/
}
/* [NV] NERO VICINO */
void nero_vicino(CELLA** matrice, int n, int a , int b){
int i,j;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(((i==a && (j==b-1 || j==b+1)) && matrice[a][b].marcatura == 2) || ((j==b && (i==a-1 || i==b+1)) && matrice[a][b].marcatura == 2))
non_annerire(matrice,n, i ,j);
}
Puoi spostare la chiamata a solo_un_bianco nel chiamante di non_annerire. Dal punto di vista del significato dei nomi delle funzioni: perché non_annerire chiama solo_un_bianco ?
non_annerire ha un solo compito, marcare la cella come non annerita
non_annerire deve marcare la cella come non annerita, ma per creare la ricorsione come suggerimento il compito dice :
oltre a colorare la cella(i,j) del colore opportuno, applica poi ricorsivamente le regole NV e A oppure SB richiamando rispettivamente le funzioni non_annerire o annerisci su altre caselle della griglia.
allora ho inserito le due funzioni non_annerire chiama SB perchè se una casella è non annerita vado a vedere se sulla stessa riga o colonna c'è un numero uguale da annerire, se ne trova uno da annerire richiama NV per non annerire le celle vicino a quella annerita....e così via...
non riesco a capire come differenziare la stampa del PI e del NV
e il fatto della ricorsione non so se funziona
questo è il codice con dei controlli sulla stampa della griglia:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct CELLA{
int valore;
int marcatura; /* assume il valore 0=non si sa ancora; 1=non annerito; 2=annerito */
}CELLA;
/*============================ Dichiarazione delle funzioni (prototipi) ===============================*/
CELLA** alloca_matrice(int n); /* Alloca memoria per una matrice */
void libera_matrice(CELLA** matrice, int n); /* Libera la memoria allocata */
void input(CELLA** matrice, int n);
void stampa_matrice(CELLA** matrice , int n);
void panino_imbottito(CELLA** matrice, int n);
void solo_un_bianco(CELLA** matrice, int n,int a,int b);
void non_annerire(CELLA** matrice, int n, int i, int j);
void annerisci(CELLA** matrice,int n, int i, int j);
void nero_vicino(CELLA** matrice,int n, int a , int b);
/*=====================================================================================================*/
/*==================== MAIN ===================== */
int main()
{
CELLA** matrice;
int n;
printf("Dimensione griglia?\n");
scanf("%d" , &n);
matrice = alloca_matrice(n);
input(matrice, n);
panino_imbottito(matrice,n);
printf("\n");
stampa_matrice(matrice, n);
libera_matrice(matrice, n);
return 0;
}
/*
Alloca la memoria per una matrice di struct CELLA di dimensione n e ne restituisce
un puntatore.
*/
CELLA** alloca_matrice(int n)
{
CELLA **matrice;
int i;
/* alloco un array di n puntatori alla struttra CELLA e assegno il puntatore a una varibile matrice di tipo CELLA ** */
if(!(matrice = (CELLA **) malloc (n * sizeof(CELLA*)))) {
fprintf(stderr,"Errore di allocazione per la matrice\n");
return 0;
}
/* per ogni elemento matrice[i] dell'array si alloca un array di n elementi di tipo CELLA il cui indirizzo viene posto in matrice[i] */
for(i=0; i<n; i++) {
if(!(matrice[i] = (CELLA*) malloc (n * sizeof(CELLA)))) {
fprintf(stderr,"Errore di allocazione per la i-esima posizione \"%d\"\n",i);
return 0;
}
}
return matrice;
}
/* Libera la memoria allocata da alloca_matrice */
void libera_matrice(CELLA** matrice, int n)
{
int i;
for (i=0; i<n; i++)
free((matrice)[i]);
free(matrice);
}
/* Inserimento dei valori all'interno della matrice*/
void input(CELLA** matrice, int n){
int i,j;
for(i=0 ; i<n ; i++)
for(j=0 ; j<n ; j++)
{
scanf("%d",&matrice[i][j].valore);
matrice[i][j].marcatura = 0;
}
printf("\n");
}
/* stampa del risultato della matrice */
void stampa_matrice(CELLA** matrice, int n){
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
if (matrice[i][j].marcatura == 1)
printf("%s%d%s ","-", matrice[i][j].valore, "-");
else if(matrice[i][j].marcatura == 2)
printf("%s%d%s ","*", matrice[i][j].valore, "*");
else if(matrice[i][j].marcatura == 0)
printf("%d ", matrice[i][j].valore);
printf("\n");
}
}
/*===================== Implementazione dell tecniche di risoluzione ================*/
/* numero non annerito = -1- */
/* numero annerito = *1* */
/* numero che non si sa ancora se annerito o no = 1 */
/* [Pi] PANINO IMBOTIITO*/
void panino_imbottito(CELLA** matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if((matrice[i][j].valore == matrice[i][j+2].valore) && matrice[i][j+1].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle righe e il valore in mezzo non è stato ancora marcato*/
/* richiamo la funzione non_annerire */
non_annerire(matrice,n,i,j+1);
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if((matrice[i][j].valore == matrice[i+2][j].valore) && matrice[i+1][j].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle colonne*/
/* richiamo la funzione non_annerire*/
non_annerire(matrice,n,i+1,j);
}
/* [SB] SOLO UN BIANCO */
void solo_un_bianco(CELLA** matrice, int n,int a,int b){
int i,j;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(matrice[i][j].marcatura == 0 && matrice[i][j].valore == matrice[a][b].valore && !(i==a && j==b) && ((i==a || j==b)))
annerisci(matrice,n, i ,j);
}
/* Funzione che oltre a colorare la cella(i,j) come annerita,applica poi ricorsivamente le regole NV e A. */
void annerisci(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 2;
printf("%s%d%s%d%s", "si (" , i , ", " , j,") : SB\n");
stampa_matrice(matrice,n);
printf("\n");
nero_vicino(matrice,n,i,j);
}
/* Funzione che oltre a marcare la cella(i,j) come non annerita, applica poi ricorsivamente la regola SB.*/
void non_annerire(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 1;
printf("%s%d%s%d%s", "no (" , i , ", " , j,") : PI\n");
stampa_matrice(matrice,n);
printf("\n");
solo_un_bianco(matrice,n,i,j);
}
/* [Nv] NERO VICINO */
void nero_vicino(CELLA** matrice, int n, int a , int b){
int i,j;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(matrice[i][j].marcatura == 0 && matrice[a][b].marcatura == 2 && (i==a && (j==b-1 || j==b+1)) || (j==b && (i==a-1 || i==b+1)))
non_annerire(matrice,n, i ,j);
printf("%s%d%s%d%s", "no (" , i , ", " , j,") : NV\n");
stampa_matrice(matrice,n);
printf("\n");
}
Non capisco perchè con questo codice:
/*===================== Implementazione dell tecniche di risoluzione ================*/
/* numero non annerito = -1- */
/* numero annerito = *1* */
/* numero che non si sa ancora se annerito o no = 1 */
/**************** [PI] PANINO IMBOTIITO *****************/
void panino_imbottito(CELLA** matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if((matrice[i][j].valore == matrice[i][j+2].valore) && matrice[i][j+1].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle righe e il valore in mezzo non è stato ancora marcato*/
/* richiamo la funzione non_annerire */
non_annerire_pi(matrice,n,i,j+1);
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if((matrice[i][j].valore == matrice[i+2][j].valore) && matrice[i+1][j].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle colonne*/
/* richiamo la funzione non_annerire*/
non_annerire_pi(matrice,n,i+1,j);
}
/**************** [SB] SOLO UN BIANCO ****************/
void solo_un_bianco(CELLA** matrice, int n,int a,int b){
int i,j;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(matrice[i][j].marcatura == 0 && matrice[i][j].valore == matrice[a][b].valore && !(i==a && j==b) && (i==a || j==b))
annerisci_sb(matrice,n, i ,j);
}
/******************** ANNERISCI******************/
/* Funzione che oltre a colorare la cella(i,j) come annerita,applica poi ricorsivamente le regole NV e A. */
void annerisci_sb(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 2;
printf("%s%d%s%d%s", "si (" , i , ", " , j,") : SB\n");
stampa_matrice(matrice,n);
printf("\n");
nero_vicino(matrice,n,i,j);
}
void annerisci_cs(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 2;
printf("%s%d%s%d%s", "si (" , i , ", " , j,") : CS\n");
stampa_matrice(matrice,n);
printf("\n");
nero_vicino(matrice,n,i,j);
}
/****************** NON_ANNERIRE********************/
/* Funzione che oltre a marcare la cella(i,j) come non annerita, applica poi ricorsivamente la regola SB.*/
void non_annerire_pi(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 1; /* imposto la marcatura come non annerito */
printf("%s%d%s%d%s", "no (" , i , ", " , j,") : PI\n");
stampa_matrice(matrice,n);
printf("\n");
solo_un_bianco(matrice,n,i,j);
}
/* Funzione che oltre a marcare la cella(i,j) come non annerita, applica poi ricorsivamente la regola SB.*/
void non_annerire_nv(CELLA** matrice,int n,int i , int j){
matrice[i][j].marcatura = 1;
printf("%s%d%s%d%s", "no (" , i , ", " , j,") : NV\n");
stampa_matrice(matrice,n);
printf("\n");
solo_un_bianco(matrice,n,i,j);
}
/***************** [NV] NERO VICINO *********************/
void nero_vicino(CELLA** matrice, int n, int a , int b){
int i,j;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(matrice[i][j].marcatura == 0 && matrice[a][b].marcatura == 2 && ((i==a && (j==b-1 || j==b+1)) || (j==b && (i==a-1 || i==b+1))))
non_annerire_nv(matrice,n, i ,j);
}
/*********************** [CS] COPPIA E SINGLE ***********************/
void coppia(CELLA** matrice, int n){
int i,j,a,b;
for(i=0; i<n;i++)
for(j=0;j+3<n;j++)
if(matrice[i][j].marcatura == 0 && (matrice[i][j].valore == matrice[i][j+1].valore))
for(a=i; a<n;a++)
for(b=j+3;b<n;b++)
if(matrice[a][b].valore == matrice[i][j].valore)
annerisci_cs(matrice,n,a,b);
}
E questo input:
Dimensione griglia?
5
1 1 1 2 3
5 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
output è:
no (0, 1) : PI giusto
1 -1- 1 2 3
5 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
si (0, 0) : SB giusto
*1* -1- 1 2 3
5 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
no (1, 0) : NV giusto
*1* -1- 1 2 3
-5- 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
si (0, 2) : SB giusto
*1* -1- *1* 2 3
-5- 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
no (0, 3) : NV giusto
*1* -1- *1* -2- 3
-5- 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
no (3, 2) : NV qui mi dovrebbe dare no (1,2) : NV..perchè :eek:
*1* -1- *1* -2- 3
-5- 4 2 3 1
1 5 3 4 3
2 4 -4- 1 4
1 2 1 5 4
Puoi spostare la chiamata a solo_un_bianco nel chiamante di non_annerire. Dal punto di vista del significato dei nomi delle funzioni: perché non_annerire chiama solo_un_bianco ?
non_annerire ha un solo compito, marcare la cella come non annerita
Ribadisco...
Ovviamente il discorso si estende anche alle altre funzioni.
Il problema è che facendo così come mi hai suggerito, l'esecuzione mi termina dopo un passo con BUS ERROR...
void panino_imbottito(CELLA** matrice, int n) {
int i,j;
for (i=0; i<n; i++)
for(j=0; (j+2)<n; j++)
if((matrice[i][j].valore == matrice[i][j+2].valore) && matrice[i][j+1].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle righe e il valore in mezzo non è stato ancora marcato*/
/* richiamo la funzione non_annerire */
non_annerire_pi(matrice,n,i,j+1);
solo_un_bianco(matrice,n,i,j);
for(j=0; j<n; j++)
for(i=0;(i+2)<n;i++)
if((matrice[i][j].valore == matrice[i+2][j].valore) && matrice[i+1][j].marcatura == 0) /* controlla se ci sono valori uguali a distanza 2 sulle colonne*/
/* richiamo la funzione non_annerire*/
non_annerire_pi(matrice,n,i+1,j);
solo_un_bianco(matrice,n,i,j);
}
Dimensione griglia?
3
1 2 1
4 5 6
6 2 8
no (0, 1) : PI
1 -2- 1
4 5 6
6 2 8
Bus error
perchè non funziona....avete suggerimenti!!!!
(cionci) così non riesco a venirne a capo...sarò io che sbaglio la logica, mi date una mano..
Ho provato a usare il debugger di emacs , uso Mac!!!
Se hai da consigliarmi un debugger per mac è ben accetto..visto che quello di emacs è un po incasinato!!! non c'è un modo per vedere per ogni passo cosa succede...?.....
Non sono un grande esperto di Mac. Prova Code::Blocks: http://wiki.codeblocks.org/index.php?title=Installing_Code::Blocks_nightly_build_on_Mac_OS_X
Ho trovato un errore qui:
void nero_vicino(CELLA** matrice, int n, int a , int b){
int i,j;
for(j=0; j<n;j++)
for(i=0;i<n;i++)
if(matrice[i][j].marcatura == 0 && (((j==b && (i==a-1 || i==a+1))) || (i==a && (j==b-1 || j==b+1))))
non_annerire_nv(matrice,n, i ,j);
}
avevo scritto b+1 invece di a+1...
questa funzione invece dovrebbe trovare che se 2 numeri adiacenti sono uguali , allora se c'è un numero uguale a quei 2 lo annerisco, sia sulla riga che sulla colonna
così mi funziona nel primo caso
no (1, 4) : PI
*1* -1- *1* -2- 3
-5- 4 -2- 3 -1-
1 -5- 3 -4- 3
-2- 4 4 -1- 4
1 -2- 1 5 4
si (3, 4) : CS
*1* -1- *1* -2- 3
-5- 4 -2- 3 -1-
1 -5- 3 -4- 3
-2- 4 4 -1- *4*
1 -2- 1 5 4
in una successiva iterazione questo non va bene
no (4, 4) : NV
*1* -1- *1* -2- *3*
-5- 4 -2- 3 -1-
1 -5- *3* -4- -3-
-2- *4* -4- -1- *4*
1 -2- 1 5 -4-
si (4, 4) : CS
*1* -1- *1* -2- *3*
-5- 4 -2- 3 -1-
1 -5- *3* -4- -3-
-2- *4* -4- -1- *4*
1 -2- 1 5 *4*
/*********************** [CS] COPPIA E SINGLE ***********************/
void coppia(CELLA** matrice, int n){
int i,j,a,b;
for(i=0; i<n; i++)
for(j=0; j<(n-3); j++)
if(matrice[i][j].marcatura == 0 && matrice[i][j+1].marcatura == 0 && (matrice[i][j].valore == matrice[i][j+1].valore)) /* verifico se ci sono due valori vicini uguali*/
for(a=i; a<n; a++) /* sulla riga */
for(b=(j+3); b<n; b++) /* se ci sono guardo se nella stessa riga (o colonna) su cui si trovano c'è un numero uguale */
if(matrice[i][j].valore == matrice[a][b].valore)
annerisci_cs(matrice,n,a,b);
}
ma tutto questo lavoro con le matrici come influisce sulla complessità dei calcoli?
grazie
non capisco dove sta l'errore in CS...perchè mi seleziona di nuovo la cella (4,4) che era già non annerita e l'annerisce?:confused:
Ho trovato l'errore nella funzione CS!!!!!!!:p
Ora mi manca da implementare 2 funzioni:
[NI] Nero impossibile: assumendo che la casella sia nera e applicando ricorsivamente le tecniche NV e SB si ottiene una configurazione che non rispetta le regole,allora la casella non può essere annerita.
[BI] uguale al contrario
come posso implementarle???????
per vedere la componente connessa della regola [A] : non ci devono essere caselle bianche isolate.
é meglio utilizzare un grafo con visita in ampiezza o qualcosa del genere?????
Ho un po di dubbi su questo!!!:wtf:
Sull'ultima...non ti basta esplorare le 8 caselle contigue a tutte le bianche ?
si avevo già trovato una soluzione del genere:
void angolo(CELLA** matrice , int n){
if(matrice[0][1].marcatura == 2) /* CASO 1 */
non_annerire_a(matrice,n,1,0);
if(matrice[1][0].marcatura == 2) /* CASO 2 */
non_annerire_a(matrice,n,0,1);
if(matrice[n-2][0].marcatura == 2) /* CASO 3 */
non_annerire_a(matrice,n,n-1,1);
if(matrice[n-1][1].marcatura == 2) /* CASO 4 */
non_annerire_a(matrice,n,n-2,0);
if(matrice[0][n-2].marcatura == 2) /* CASO 5 */
non_annerire_a(matrice,n,1,n-1);
if(matrice[1][n-1].marcatura == 2) /* CASO 6 */
non_annerire_a(matrice,n,0,n-1);
if(matrice[n-2][n-1].marcatura == 2) /* CASO 7 */
non_annerire_a(matrice,n,n-1,n-2);
if(matrice[n-1][n-2].marcatura == 2) /* CASO 8 */
non_annerire_a(matrice,n,n-2,n-1);
}
così pare funzionare!!!!
per il Nero impossibile e Bianco impossibile??? hai qualche idea
grazie per i suggerimenti!!!
Come potrei fare per implementare le 2 regole che controllano per assurdo se una casella annerita/non annerita , dopo aver applicato le altre tecniche SB e NV e aver visto che viola le proprietà del gioco in realtà non può essere annerita/non annerita ?????:confused:
Come potrei fare per implementare le 2 regole che controllano per assurdo se una casella annerita/non annerita , dopo aver applicato le altre tecniche SB e NV e aver visto che viola le proprietà del gioco in realtà non può essere annerita/non annerita ?????:confused:
Non l'ho capita :D
PercHé nel codice sopra tieni conto di matrice[0][1] e non di matrice[i][j] ?
PercHé nel codice sopra tieni conto di matrice[0][1] e non di matrice[i][j] ?
Ho fatto così per tenere conto dei soli angoli..
se guardi qui : http://www.menneske.no/hitori/methods/eng/methodcc.html
se metto matrice[i][j] dovrei farlo per tutte le celle sul lato come nel metodo close edge , mentre io volevo fare corner close.
Per il metodo [NI] è così:
Se annerendo una casella e applicando ricorsivamente le tecniche SB e NV si ottiene necessariamente una configurazione che non rispetta le 3 regole, allora al casella non può essere annerita.
Esempio
no (4, 3) : A
*1* -1- *1* -2- *3*
-5- 4 -2- 3 -1-
1 -5- *3* -4- -3-
-2- *4* -4- -1- *4*
1 -2- 1 -5- -4-
da qui il passo dopo è questo
no (4, 2) : NI
*1* -1- *1* -2- *3*
-5- 4 -2- 3 -1-
1 -5- *3* -4- -3-
-2- *4* -4- -1- *4*
1 -2- -1- -5- -4-
perchè suppone che venga annerito , però se viene annerito 1 verde è non annerito ma l'1 blu è annerito e non va bene perchè si chiudono delle celle, non rispettando la regola 3 della componente connessa, quindi non andrà annerita
Allora quello che ho pensato per la regola [NI]:
guardo se ci sono delle celle con marcatura==0
la suppongo nera e applico le regole ricorsivamente.
nell'esempio
*1* -1- *1* -2- *2*
-5- 4 -2- 3 -1-
1 -5- *3* -4- -3-
-2- *4* -4- -1- *4*
1 -2- 1 -5- -4-
l'1 rosso lo suppongo nero allora l'1 verde deve essere bianco perchè altrimenti il 2 rimane chiuso, e l'1 blu deve essere nero per SB..ma non può esserlo perchè le tre celle rimarebbero chiuse..quindi la supposizione non va bene e l'1 rosso non è nero ma non va annerito.
il problema è la verifica della componente connessa e mantenere memoria della cella di cui si è fatta la supposizione.
si potrebbe fare con una pila ,quando verifico che le supposizione non va bene tolgo gli elementi memorizzati nella pila e in fondo troverò la marcatura bianca da assegnarli...
hai dei suggerimenti!!!scusa è un po un casino da spiegare
Ho dimenticato questa tecnica
TRAPEZIO:
2 3
* *
2 a
a 3
dove asterisco vuol dire qualsiasi valore, anche nessuno e "a" vuol dire che non va annerito
cioè se trovo una configurazione così i 2 valori "a" non vanno anneriti!!!
Poi mi rimane da risolvere la questione già espost prima!!!
AIUTOOOOOO :muro:
void trapezio(CELLA** matrice, int n){
int i,j,a,b;
for(i=0;i<n-2;i++)
for(j=0;j<n-1;j++)
for(a=i+1;a<n-1;a++)
if(matrice[i][j].valore==matrice[a][j].valore && matrice[i][j+1].valore==matrice[a+1][j+1].valore)
/* richiamo non_annerire per il primo elemento */
non_annerire_tr(matrice,n,a+1,j);
/* richiamo non annerire per il secondo elemento */
non_annerire_tr(matrice,n,a,j+1); /* se inserisco questo mi dà una valore sbagliato*/
}
come faccio a richiamare non annerire per il secondo elemento sui valori giusti?
devo implementare una funzione che lavora su una matrice allocata dinamicamente per verificare che le celle della matrice siano collegate tra loro, senza che ci siano caselle isolate dalle altre.
Esempio:
soluzione sbagliata:
1 1 1 2 3
5 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
qui le celle non rosse sono divise in 2
i 3 numeri blu sono separati
soluzione corretta
1 1 1 2 3
5 4 2 3 1
1 5 3 4 3
2 4 4 1 4
1 2 1 5 4
tutte le celle con in numeri non rossi sono collegati
io pensavo a un grafo, avete suggerimenti?!!
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.