UTNianos

Versión completa: ¿Cuánta agua puede almacenar esta pileta?
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Páginas: 1 2
Necesito ayuda en ANSI C para esto porque realmente lo intente codificar por mi cuenta y me compila pero no soy experto en ANSI C, digamos que utilize las herramientas que te brinda Sintaxis + cosas que busqué por internet y el resultado fue:
  • Compila, pero el programa se termina cerrando solo (el clásico ENVIAR - NO ENVIAR xD)

El problema es el siguiente:
Se tiene una matriz/vector de m x n de int (int pileta[m][n]). Cada celda de la matriz representa un espacio en forma cuadrada de, por ejemplo, 1 mts2 en donde se pueden apilar cubos (por ejemplo de cemento) de 1 mts3.
El int contenido en la celda, indica cuantos bloques (cubos) hay apilados uno arriba del otro (siempre contenidos en el espacio de 1mts2 de la celda).

Se desea saber cuanta agua entra en la "pileta", teniendo en cuenta que el agua fluye solo horizontalmente y verticalmente (en diagonal no), y teniendo en cuenta también que la pileta puede rebalsar de agua y en ese caso la cantidad de agua que puede almacenar la pileta seria 0.


Ejemplos:
Spoiler: Mostrar
9 9 9
9 1 9 ---Debería devolver---> 8
9 9 9

9 9 9 9
9 1 1 9 ---Debería devolver---> 16
9 9 9 9

9 1 9 9
9 1 1 9 ---Debería devolver---> 0
9 9 9 9

9 9 9 9
9 1 1 9 ---Debería devolver---> 2
9 2 8 9

9 9 9 9
9 2 1 9 ---Debería devolver---> 1
9 2 8 9

9 9 9 9
9 1 1 9 ---Debería devolver---> 14
9 8 8 9

9 9 9 9
9 3 2 9 ---Debería devolver---> 1
9 2 8 9

1 9 1 1
9 3 9 1 ---Debería devolver---> 6
1 9 1 1

Mi estrategia fallida:
Spoiler: Mostrar
1.Se recibe una matriz.
2.Se recorre la matriz por niveles (es decir, primero sumo todas las celdas en 1, despues en 2, etc etc hasta el nivel máximo)
3.Al encontrar un elemento en la matriz del nivel recorrido, se fija si desborda. Si no desborda, se suma 1 y se guarda las coordenadas de la en un vector/pila.
4.Se ejecuta recursivamente la misma acción para los 4 elementos de la matriz de los costados (los que no sean borde), creando, de esta forma, un camino.
5.Si al finalizar un camino, el flag desborda esta en TRUE getWay(que devuelve la cantidad de un camino) devuelve 0 y todos los elementos de la matriz, cuyas coordenadas estan en el vector/pila se ponen en -1.
6.getLevel devuelve la suma de todos los (caminos)getWay pertenecientes al nivel
7.getMeters devuelve la suma de todos los (niveles)getLevel.

Si alguno me puede ayudar se lo agradecería bastante... por ahi es una pelotudes pero la verdad no se que más hacer...
Mi código no lo paso por una cuestión de que no lo van a entender ni a gancho y aparte esta muy desprolijo xD.

Bueno gracias de antemano a el/la/los que me ayuden xD
Y si nadie me puede ayudar seguiré intentando arreglar mi código xDDDD[/font]
para ver donde pincha, deberias hacer una ejecucion paso a paso con algun debugger. y ver porque se esta muriendo el programa. en cuanto a la estrategia, despues en casa lo analizo con mas detenimiento, y veo si puedo ayudarte
(06-09-2011 16:17)Jarry escribió: [ -> ]para ver donde pincha, deberias hacer una ejecucion paso a paso con algun debugger. y ver porque se esta muriendo el programa. en cuanto a la estrategia, despues en casa lo analizo con mas detenimiento, y veo si puedo ayudarte

Gracias Jarry, me recomendas alguno para ANSI C? (nunca use debuggers)
fa es jodido, si lo leo a la mañana capaz lo puedo sacar =P,
a que llamas nivel?
Subi el codigo, en palabras es obvio que todo va a funcionar =P
(06-09-2011 17:21)lucho6 escribió: [ -> ]fa es jodido, si lo leo a la mañana capaz lo puedo sacar =P,
a que llamas nivel?

Cada nivel es como un piso digamos
En pseudocódigo lo queres rld?
Que subas el codigo que no te anda dice rld
Bueno, pero conste que no se entiende nada... bah yo solo me lo entiendo, no tiene comentarios en ningun lado y si se los tengo q explicar voy a estar hasta el año q viene... aunq bueno lo que les puedo decir es que como lo que vi de pilas en sintaxis no me sirvió, simule una pila en un vector o eso intente, es un vector de estructuras tal vez hay algún tema de manejo de punteros a estructuras (ya que no se pasa el vector entero, sino que se pasa el puntero a la primer estructura del vector). También en algunos lados hay cosas como &m[i][j] ... la verdad no se por qué, pero si no lo pongo así, no compila xDDD
Supongo que deberán ser más que nada errores sintácticos del lenguaje, asique bueno si alguien me puede ayudar se lo agradecería.

En fin, acá esta el código... (reservense los comentarios de que es espantoso o cosas por el estilo, no me dedico a programar asique es lo mas seguro xD)

Spoiler: Mostrar

#include <stdio.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE 1
typedef struct { int x; int y; } points;
int getMeters (int ** ,int ,int);
int getLevel (int **,int,int,int);
int getWay (int **,int,int,int,int,int,points *,int);
int noDesborda (int **,int,int,int,int,int);
int getMax (int **,int,int);
void pop ( points * , points , int );
void push (points,points *,int);

void pop ( points *pila , points point, int len ) {
puts("Ejecutando pop");
point.x=&pila[len].x;
point.y=&pila[len].y;
len--;
return;
}
void push (points point, points *p, int len) {
puts("Ejecutando push");
len++;
p[len].x=point.x;/*estas dos líneas compilan, pero cuando se ejecutan, muere el programa*/
p[len].y=point.y;
return;
}

int getMeters (int **m ,int filas ,int columnas) {
int i,max,acum=0;
puts("Ejecutando getMeters");
max = getMax(m,filas,columnas);
for ( i = 0 ; i<=max; i++ ) {
acum = acum + getLevel(m,filas,columnas,i);
}
return acum;
}

int getLevel (int **m,int filas,int columnas,int level) {
int i,j,acum=0,aux,len=0;
points point, *p;
puts("Ejecutando getLevel");
for(i=1;i<=filas-1;i++) {
for(j=1;j<=columnas-1;j++) {
aux=getWay(m,filas,columnas,i,j,level,p,len);
len=0;
if(&m[i][j]==level && aux) {
acum = acum + aux;
while (point.x != -1)
m[point.x][point.y]++;
}
else {
while (point.x != -1)
m[point.x][point.y]=0;
}
}
}
return acum;
}

int getWay (int **m,int filas,int columnas,int i,int j,int level, points *p,int len) {
int acum,desborda=FALSE;
points point;
puts("Ejecutando getWay");
if ( noDesborda(m,filas,columnas,i,j,level) )
acum++;
else
desborda = TRUE;
point.x=i;
point.y=j;
push(point,p,len);
if ( i-1>0 && &m[i-1][j]==level )
getWay (m,filas,columnas,i-1,j,level,p,len);
if ( i+1<filas && &m[i+1][j]==level )
getWay (m,filas,columnas,i+1,j,level,p,len);
if ( j+1<columnas && &m[i][j+1]==level )
getWay (m,filas,columnas,i,j+1,level,p,len);
if ( j-1>0 && &m[i][j-1]==level)
getWay (m,filas,columnas,i,j-1,level,p,len);
if ( desborda )
return 0;
else
return acum;
}

int noDesborda (int **m,int filas,int columnas,int i,int j,int level) {
puts("Ejecutando noDesborda");
if(i-1==0 && &m[i-1][j]>level)
return TRUE;
if(i+1==filas && &m[i+1][j]>level)
return TRUE;
if(j-1==0 && &m[i][j-1]>level)
return TRUE;
if(j+1==0 && &m[i-1][j]>level)
return TRUE;
else
return FALSE;
}

int getMax (int **m,int filas,int columnas) {
int i,j,max=0;
puts("Ejecutando getMax");
for(i=0;i<=filas;i++) {
for(j=0;j<=columnas;j++) {
if(&m[i][j]>max)
max=&m[i][j];
}
}
return max;
}

int main (void) {
int m[3][3] = {
{ 9 , 9 , 9 },
{ 9 , 1 , 9 },
{ 9 , 9 , 9 },
};
int acum;
puts("Iniciando prueba");
acum=getMeters(m,3,3);
printf("La cantidad de agua es: %d", acum);
return 0;
}



Esto, con el borland, debería compilar (aparte de que te tira 8mil warnings xD), pero bueno cuando lo ejecutan verán que se queda trabado cuando invoca a push y empieza a hacer el manejo de estructuras y se cierra solito =P
Se me está ocurriendo otra forma de guardar las coordenadas en vez de usar estructuras pero tiene mucha limitación, asique sería mejor si esto se puede arreglar
Una vez más, GRACIAS por la ayuda =)
Cita:

int getMeters (int ** ,int ,int);



Ni sabia que se podian declarar funciones asi...vale ponerle nombres a las variables ahi, sino es inentendible =P

Creo que el error esta en getLevel, no probé arreglarlo. Fijate que tenés:


int getLevel(...) {
...
points point, *p;
...
aux = getWay(...,p,...);
...
}




Y despues getWay llama a push que también recibe a p, y despues se desreferencia p pero nunca se inicializó (p[len] = ...). Cuando lo corro, p apunta a cualquier lado, y eso debería estar causando el segfault. No se si es el unico error, pero en algun lado se arranca =P

pileta.c: In function ‘getWay’:
pileta.c:66:13: warning: ‘acum’ may be used uninitialized in this function
pileta.c: In function ‘getLevel’:
pileta.c:45:16: warning: ‘p’ may be used uninitialized in this function




Warnings bastante importantes =P
Spoiler: Mostrar
(07-09-2011 15:05)rld escribió: [ -> ]
Cita:

int getMeters (int ** ,int ,int);



Ni sabia que se podian declarar funciones asi...vale ponerle nombres a las variables ahi, sino es inentendible =P

Creo que el error esta en getLevel, no probé arreglarlo. Fijate que tenés:


int getLevel(...) {
...
points point, *p;
...
aux = getWay(...,p,...);
...
}




Y despues getWay llama a push que también recibe a p, y despues se desreferencia p pero nunca se inicializó (p[len] = ...). Cuando lo corro, p apunta a cualquier lado, y eso debería estar causando el segfault. No se si es el unico error, pero en algun lado se arranca =P

pileta.c: In function ‘getWay’:
pileta.c:66:13: warning: ‘acum’ may be used uninitialized in this function
pileta.c: In function ‘getLevel’:
pileta.c:45:16: warning: ‘p’ may be used uninitialized in this function




Warnings bastante importantes =P

Bueno lo de las declaraciones, mientras ande es irrelevante ya que cuando escribis el código de la función ahí es obligatorio ponerle nombre a los parámetros.

Después el problema es que p[len] es un puntero a una estructura... ¿como hago para inicializarlo eso y que no apunte en cualquier lado? Intenté hacer p[len]=.... pero me tira ERROR BLABLABLA: Illegal structure operation in function BLABLABLA Confused
No entiendo porque me tira ese error si estoy asignando al puntero y no a la estructura xD

El error del acum es facil de corregir, pero el del p "unitialized" tiene que ver con lo que te plantie antes.

EDITO: eso se hace con malloc supongo no?? Si es así ni idea de cómo utilizarlo, no lo vi en la facu eso xD si me podes dar una mano joya sino veo de averiguar en internet

EDITO2: le agregue esto en la linea anterior a llamar a getway

p = malloc (sizeof(int)*(filas-1*columnas-1));


Compiló perfecto, pero sigue sin andar xD voy a arreglar lo del acum que me olvide

EDITO3: haciendo un debug manual, el push palma la aplicación en esta linea

p[len].x=point.x;


Si declaraste


int *p;



lo único que tenés es un puntero apuntando a un lugar cualquiera...para tener una zona de memoria válida para leer/escribir datos, necesitás llamar a malloc. La idea es que le pasas un numero y te reserva una zona contigua de tantos bytes que se garantiza que es válida. Si no la pudo reservar (no hay suficiente memoria, zona contigua demasiado grande, etc.) devuelve NULL. Ej:


int *p = malloc(3*sizeof(int));
p[0] = 1;
p[1] = 2;
p[2] = 3;



debería funcionar bien. Sin el malloc probablemente tire segfault en la segunda instrucción, que es lo que pasa acá.

Si quisiste hacer un vector de punteros a estructuras, deberías haber declarado points **p, que es lo mismo que points *p[]. Si no, points *p es un puntero a un arreglo de estructuras.
Lo que quise hacer es guardar la pila en un vector (p) de estructuras que contiene las coordenadas que quiero guardar de la matriz, y a la funcion push y pop no le podes pasar un vector, sino que le pasas un puntero que apuntaría al primer elemento del vector.
Pero p, en realidad para getLevel, sería un vector de points. Para getWay, p es un puntero que apunta al primer elemento del vector. ¿Me explico?
Ya lo pude hacer, al final lo hice en Visual C# con la ayuda de un amigo y quedo espectacular =P
Gracias por la ayuda!

PD: Cierren!
depende del tamaño de la pileta cuanta agua puede tener man...


Ademas con pileta te podes referir a la de la cocina, baño, la pelopincho, la de fibra de vidrio, la olimpica, etc


Aclara mejor asi te podemos ayudar thumbup3
JAJAJAJAJ Q hdp este tipo
Páginas: 1 2
URLs de referencia