Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[ansi c] torres de hanoi

Estas en el tema de [ansi c] torres de hanoi en el foro de C/C++ en Foros del Web. Estoy trabajando con las torres de hanoi. Quisiera que me ayudaran a descifrar por qué mi código no funciona como debería. El programa en debe ...
  #1 (permalink)  
Antiguo 26/05/2013, 11:41
 
Fecha de Ingreso: mayo-2013
Mensajes: 4
Antigüedad: 11 años, 6 meses
Puntos: 0
[ansi c] torres de hanoi

Estoy trabajando con las torres de hanoi. Quisiera que me ayudaran a descifrar
por qué mi código no funciona como debería.

El programa en debe ser gráfico y no narrativo. Algo como esto:
http://www.youtube.com/watch?v=xXTle8JYhys

Debo realizar el programa mediante funciones recursivas y no puedo utilizar métodos iterativos.

Las funciones donde probablemente esté el error son la g_MoverDiscos o g_TorreDeHanoiRecursiva.

En mi programa utilicé 3 arreglos unidimensionales para la "torres".
Uno que se llama Origen que se imprime a la izquierda, otro que se
llama intermedio que se imprime en el centro y el final se llama destino.





Mientras escribia esto note que los errores *parecen de impresión. :o. Creo que los
argumentos que se están pasando a la función imprimir se están cambiando debido a la
como tengo escrita la recursión en mi código. Alguna idea sobre como puedo solucionar
esto? (en caso de que esto sea el problema)

Cualquier ayuda es útil muchas gracias.

A continuación pondré las funciones donde creo que tengo el problema


Código C:
Ver original
  1. #define kMAX 30
  2. void g_MoverDiscos(int liFilas,int liNDiscos,
  3.  * * * * * * * * * int liTorreOrigen[kMAX],int liTorreDestino[kMAX])
  4. {
  5.  * *int liPosOrigen =0;
  6.  * *int liPosDestino=liFilas-1;
  7.  
  8.  * *//Busqueda de la posicio del menor disco en el origen
  9.  * *while(liTorreOrigen[liPosOrigen]==0 && liPosOrigen<liFilas-1)
  10.  * *{
  11.  * * * *liPosOrigen++;
  12.  * *}
  13.  
  14.  * *//Busqueda de la posicion del tope de la torre destino
  15.  * *while(liTorreDestino[liPosDestino]!=0 && liPosDestino>0)//Menor o igual
  16.  * *{
  17.  * * * *liPosDestino--;
  18.  * *}
  19.  * *liTorreDestino[liPosDestino]=liTorreOrigen[liPosOrigen];//Transferencia del disco
  20.  * *liTorreOrigen[liPosOrigen]=0;//Al moverse el disco esta posicion se hace cero.
  21. }
  22.  
  23.  
  24. void g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX],
  25.  * * * * * * * * * * * * * * int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  26. {
  27.  
  28.  * *if(liNDiscos==1)
  29.  * *{
  30.  
  31.  * * * *g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
  32.  * * * *system("cls");
  33.  * * * *g_ImprimirDiscos(liFilas, liTorreOrigen,
  34.  * * * * * * * * * * * * liTorreIntermedia, liTorreDestino);
  35.  
  36.  * *}//END if
  37.  * *else
  38.  * *{
  39.  * * * *g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreOrigen,
  40.  * * * * * * * * * * * * * * * *liTorreDestino,liTorreIntermedia);
  41.  
  42.  * * * *g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
  43.  * * * *system("cls");
  44.  * * * *g_ImprimirDiscos(liFilas, liTorreOrigen,
  45.  * * * * * * * * * * * * *liTorreDestino,liTorreIntermedia);
  46.  
  47.  
  48.  * * * *g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreIntermedia,
  49.  * * * * * * * * * * * * * * * *liTorreOrigen,liTorreDestino);
  50.  * *}//END else
  51. }//END g_TorreDeHanoiRecursivo



///
/// Estas son las demás funciones de mi programa (todas estas están bien)
///

Código C:
Ver original
  1. /// Esta es para leer los discos
  2. int giLeerDiscos(void)
  3. {
  4.  * *int liN;
  5.  * *do
  6.  * *{
  7.  * * * *printf("\nIndique la cantidad de discos: ");
  8.  * * * *scanf("%d",&liN);
  9.  * * * *if(liN<1||liN>kMAX_DISCOS)
  10.  * * * *{
  11.  * * * * * *system("cls");
  12.  * * * * * *printf("ERROR.OPCION NO ES VALIDA. VUELVA A INTENTAR\n\n");
  13.  * * * *}
  14.  * *}while(liN<1||liN>kMAX_DISCOS);
  15.  * *return liN;
  16. }
  17.  
  18.  
  19. //Funcion incializa los arreglos a la condicion *que deben tener antes de jugar
  20. void g_CondicionInicialHanoi(int liNDiscos,int liTorreOrigen[kMAX],
  21.  * * * * * * * * * * * * * * int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  22. {
  23.  * *int i;
  24.  * *for (i=0;i<liNDiscos;i++)
  25.  * *{
  26.  * * * *liTorreOrigen[i]=i+1; * * * //Se colocan los discos desde el 1 en manera ascendente
  27.  * * * *liTorreIntermedia[i]=0; * * //Se hace cero
  28.  * * * *liTorreDestino[i]=0; * * * *//Se hace cero
  29.  * *}
  30. }
  31.  
  32.  
  33. void g_ImprimirDiscos(int liFilas,int liTorreOrigen[kMAX],
  34.  * * * * * * * * * * * *int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  35. {
  36.  * *int i;
  37.  
  38.  * *for (i=0;i<liFilas;i++)
  39.  * *{
  40.  
  41.  * * * *printf("%d\t",liTorreOrigen[i]);
  42.  * * * *printf("%d\t",liTorreIntermedia[i]);
  43.  * * * *printf("%d\t",liTorreDestino[i]);
  44.  * * * *printf("\n");
  45.  * *}
  46. }
  47.  
  48. int *main()
  49. {
  50.  * *int liTorreOrigen[kMAX];
  51.  * *int liTorreIntermedia[kMAX];
  52.  * *int liTorreDestino[kMAX];
  53.  * *int liNDiscos;
  54.  * *int liFilas; // Es igual al numero inicial de discos. Define el espacio
  55.  * * * * * * * * // de juego.
  56.  
  57.  
  58.  * *liNDiscos=giLeerDiscos();
  59.  * *liFilas=liNDiscos;
  60.  * *//Condicion inicial del juego
  61.  * *g_CondicionInicialHanoi(liNDiscos,liTorreOrigen,
  62.  * * * * * * * * * * * * * *liTorreIntermedia,liTorreDestino);
  63.  
  64.  * *//Imprimir condicion inicial del juego
  65.  * *system("cls");
  66.  * *g_ImprimirDiscos(liNDiscos,liTorreOrigen,
  67.  * * * * * * * * * * liTorreIntermedia,liTorreDestino);
  68.  * *g_TorreDeHanoiRecursivo(liFilas, liNDiscos,liTorreOrigen,
  69.  * * * * * * * * * * * * * *liTorreIntermedia,liTorreDestino);
  70.  * *printf("\n");
  71. return 0;
  72. }
  #2 (permalink)  
Antiguo 28/05/2013, 09:40
 
Fecha de Ingreso: mayo-2013
Mensajes: 4
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: [ansi c] torres de hanoi

Bump... Hay alguien ahí?

Última edición por CrashNebula; 28/05/2013 a las 09:40 Razón: typo
  #3 (permalink)  
Antiguo 28/05/2013, 12:54
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 12 años, 3 meses
Puntos: 83
Respuesta: [ansi c] torres de hanoi

"...Hay alguien ahí?..."

Si que hay alguien, pero me parece que has colgado algo poco amigable visualmente (dicho de otra forma has colgado un toston que no se lo mira ni ...)

Lo unico que he visto es que usas system("cls") que no es estandar ('system' si, pero 'cls' no). A parte de eso: como se supone que alguien puede diferenciar los * con los que has rellenado el codigo de los desreferenciadores? Supongo que te tomaste la molestia de ponerlos por pares, por lo tanto el * impar indicará desreferencia. Si lo aplico a tu linea 48 me encuentro que:

Código:
int *main() {
    ...
    return 0;
}
Entras a la aplicacion con una funcion de tipo puntero a entero??

Siento no ser de mas ayuda.

Saludos
vosk
  #4 (permalink)  
Antiguo 28/05/2013, 13:14
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: [ansi c] torres de hanoi

Cita:
Iniciado por vosk Ver Mensaje
Entras a la aplicacion con una funcion de tipo puntero a entero??
No seas irónico, sabes perfectamente que ha sido al copypastear el código

A ver, en situaciones como está conviene hacer una depuración más profunda del código... ¿Que es lo que pasa entre el paso 2 y 3?
  #5 (permalink)  
Antiguo 28/05/2013, 13:26
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 8 meses
Puntos: 1360
Respuesta: [ansi c] torres de hanoi

Yo se regex.

Código C:
Ver original
  1. #define kMAX 30
  2. void g_MoverDiscos(int liFilas,int liNDiscos, int liTorreOrigen[kMAX],int liTorreDestino[kMAX])
  3. {
  4.     int liPosOrigen =0;
  5.     int liPosDestino=liFilas-1;
  6.  
  7.     //Busqueda de la posicio del menor disco en el origen
  8.     while(liTorreOrigen[liPosOrigen]==0 && liPosOrigen<liFilas-1)
  9.     {
  10.         liPosOrigen++;
  11.     }
  12.  
  13.     //Busqueda de la posicion del tope de la torre destino
  14.     while(liTorreDestino[liPosDestino]!=0 && liPosDestino>0)//Menor o igual
  15.     {
  16.         liPosDestino--;
  17.     }
  18.     liTorreDestino[liPosDestino]=liTorreOrigen[liPosOrigen];//Transferencia del disco
  19.     liTorreOrigen[liPosOrigen]=0;//Al moverse el disco esta posicion se hace cero.
  20. }
  21.  
  22.  
  23. void g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX], int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  24. {
  25.  
  26.     if(liNDiscos==1)
  27.     {
  28.  
  29.     g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
  30.     system("cls");
  31.     g_ImprimirDiscos(liFilas, liTorreOrigen,
  32.      liTorreIntermedia, liTorreDestino);
  33.      
  34.     }//END if
  35.     else
  36.     {
  37.         g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreOrigen, liTorreDestino,liTorreIntermedia);
  38.         g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
  39.         system("cls");
  40.         g_ImprimirDiscos(liFilas, liTorreOrigen, liTorreDestino,liTorreIntermedia);
  41.  
  42.         g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1, liTorreIntermedia, liTorreOrigen, liTorreDestino);
  43.     }//END else
  44. }//END g_TorreDeHanoiRecursivo
  45.  
  46. /// Esta es para leer los discos
  47. int giLeerDiscos(void)
  48. {
  49.     int liN;
  50.     do
  51.     {
  52.         printf("\nIndique la cantidad de discos: ");
  53.         scanf("%d",&liN);
  54.         if(liN<1||liN>kMAX_DISCOS)
  55.         {
  56.             system("cls");
  57.             printf("ERROR.OPCION NO ES VALIDA. VUELVA A INTENTAR\n\n");
  58.         }
  59.     }while(liN<1||liN>kMAX_DISCOS);
  60.     return liN;
  61. }
  62.  
  63.  
  64. //Funcion incializa los arreglos a la condicion *que deben tener antes de jugar
  65. void g_CondicionInicialHanoi(int liNDiscos,int liTorreOrigen[kMAX], int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  66. {
  67.     int i;
  68.     for (i=0;i<liNDiscos;i++)
  69.     {
  70.         liTorreOrigen[i]=i+1; //Se colocan los discos desde el 1 en manera ascendente
  71.         liTorreIntermedia[i]=0; //Se hace cero
  72.         liTorreDestino[i]=0; //Se hace cero
  73.     }
  74. }
  75.  
  76.  
  77. void g_ImprimirDiscos(int liFilas,int liTorreOrigen[kMAX], int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  78. {
  79.     int i;
  80.  
  81.     for (i=0;i<liFilas;i++)
  82.     {    
  83.         printf("%d\t",liTorreOrigen[i]);
  84.         printf("%d\t",liTorreIntermedia[i]);
  85.         printf("%d\t",liTorreDestino[i]);
  86.         printf("\n");
  87.     }
  88. }
  89.  
  90. int main()
  91. {
  92.     int liTorreOrigen[kMAX];
  93.     int liTorreIntermedia[kMAX];
  94.     int liTorreDestino[kMAX];
  95.     int liNDiscos;
  96.     int liFilas; // Es igual al numero inicial de discos. Define el espacio
  97.      // de juego.
  98.      
  99.      
  100.     liNDiscos=giLeerDiscos();
  101.     liFilas=liNDiscos;
  102.     //Condicion inicial del juego
  103.     g_CondicionInicialHanoi(liNDiscos,liTorreOrigen, liTorreIntermedia,liTorreDestino);
  104.      
  105.     //Imprimir condicion inicial del juego
  106.     system("cls");
  107.     g_ImprimirDiscos(liNDiscos,liTorreOrigen, liTorreIntermedia,liTorreDestino);
  108.     g_TorreDeHanoiRecursivo(liFilas, liNDiscos,liTorreOrigen,
  109.     liTorreIntermedia,liTorreDestino);
  110.     printf("\n");
  111.     return 0;
  112. }
  #6 (permalink)  
Antiguo 28/05/2013, 20:12
 
Fecha de Ingreso: mayo-2013
Mensajes: 4
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: [ansi c] torres de hanoi

@Vosk: Como dijo amchacon fue al copiarlo que quedó así. Un error de novato posteando por primera vez en un foro de programación.Gracias de todos modos.

@razpeitia: Gracias por arreglar el código.

Si se fijan podran notar que la función en la linea 23 y la linea 37 tienen los últimos dos parametros intercambiados:

(linea 23) g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX], int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])

(linea 24) g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreOrigen, liTorreDestino,liTorreIntermedia);

(linea 42)g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1, liTorreIntermedia, liTorreOrigen, liTorreDestino);

@amchacon: Qué pasa entre el paso 2 y 3? No estoy completamente seguro así que voy a analizar.

En la funcion (linea 23) g_TorreDeHanoiRecursivo con liFilas=3, liNDiscos=3 la función se llama recursivamente tomando liNDiscos-1(linea 37) entonces el liNDiscos que se pasa será igual a 2. La funcion vuelve a llamarse para liNDiscos= 1 y se cumple la condición de la linea 26, se mueve un disco desde el origen hasta el destino y se imprime (paso 1) y termina esa función que fue llamada en la linea 37. En la linea 38 se hace un intercambio de disco y en la 40 se imprime nuevamente (paso2).

Al llamarse la función 2 veces. el orden de los parámetros no se vio afectado ya que si se intercambian las posiciones de dos elementos dos veces quedan en su estado original.
En la llamada de la linea 42 se cambian todos los parámetros de orden y la impresiones ya no quedan en el orden que le corresponde.

Creo que el problema son las impresiones y no la función recursiva porque la función imprime 7 veces y el resultado final está correcto. El numero mínimo de movimientos de la torre de hanoi se calcula como 2ˆn-1. Si n=3 entonces 2ˆn-1=7. Alguna idea de como indicarle a la función imprimir que el orden de los parámetros?
  #7 (permalink)  
Antiguo 28/05/2013, 21:56
 
Fecha de Ingreso: mayo-2013
Mensajes: 4
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: [ansi c] torres de hanoi

Ya solucioné el problema. Mi solución no es elegante pero funciona.

La función:
Código C:
Ver original
  1. void g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX],
  2.                              int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
  3. {
  4. .....
  5. }
Le agregue tres argumentos los cuales se mantendrán en la misma posición dentro de la función.

Código C:
Ver original
  1. void g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX],
  2.                              int liTorreIntermedia[kMAX],int liTorreDestino[kMAX],
  3.                              int O[kMAX],int I[kMAX], int D[kMAX])
  4. {
  5. .....
  6. }
Al ejecutarse el programa

Las posiciones de liTorreOrigen y O estarán ocupadas por el mismo arreglo
Las posiciones de liTorreIntermedia y I estarán ocupadas otro arreglo igual para las dos posiciones
Las posiciones de liTorreDestino y D es el mismo caso.

Todo el proceso recursivo estará a cargo de los parametros liTorreOrigen, liTorreIntermedia y liTorreDestino. Como O apuntará a la misma dirección de memoria que liTorreOrigen y así sucesivamente para los otros casos entonces puedo escribir
Código C:
Ver original
  1. g_ImprimirDiscos(liFilas,O,I,D);
y siempre se imprimirá en el orden correcto porque aprovecha que no se cambia de posición en la función y por ende apuntará correctamente a la dirección de memoria deseada.

Debajo posteare la nueva función:
Código C:
Ver original
  1. void g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX],
  2.                              int liTorreIntermedia[kMAX],int liTorreDestino[kMAX],
  3.                              int O[kMAX],int I[kMAX], int D[kMAX])
  4. {
  5.  
  6.     if(liNDiscos==1)
  7.     {
  8.  
  9.         g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
  10.         system("cls");
  11.         //g_ImprimirDiscos(liFilas,liTorreOrigen,liTorreIntermedia,liTorreDestino);
  12.         g_ImprimirDiscos(liFilas,O, I, D);
  13.         system("pause");
  14.  
  15.     }//END if
  16.     else
  17.     {
  18.         g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreOrigen,
  19.                                 liTorreDestino,liTorreIntermedia,O,I,D);
  20.  
  21.         g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
  22.         system("cls");
  23.          //g_ImprimirDiscos(liFilas,liTorreOrigen,liTorreIntermedia,liTorreDestino);
  24.          g_ImprimirDiscos(liFilas,O,I,D);
  25.  
  26.          system("pause");
  27.  
  28.         g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreIntermedia,
  29.                                 liTorreOrigen,liTorreDestino,O,I,D);
  30.     }//END else
  31. }//END g_TorreDeHanoiRecursivo

vosk ahora escribí todo sin los desreferenciadores =P

Gracias por todo amigos.
  #8 (permalink)  
Antiguo 29/05/2013, 04:52
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 12 años, 3 meses
Puntos: 83
Respuesta: [ansi c] torres de hanoi

Ves como al final todo se soluciona? Si ya se que no he aportada nada al tema, solo era cuestion de romper el hielo :)

Saludos
vosk

Etiquetas: recursividad
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:56.