Glaas2

Hanoi

Oct 30th, 2012
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.38 KB | None | 0 0
  1. /*
  2.     5x07-Torres_de_Hanoi_parte_2
  3.     24/01/2012
  4.     Escribe un programa (se recomienda que sea recursivo) que dé solución al problema de las torres de Hanoi.
  5.     El enunciado es el siguiente: Se dispone de una torre formada por varios discos de diferentes diámetros denominada torre O (origen),
  6.     donde cada disco es de diámetro inferior a todos los que están por debajo. Se dispone de otras dos torres para dejar discos, una denominada torre A (auxiliar) y otra torre D (destino).
  7.     El problema consiste en pasar todos los discos de la torre O a la torre D respetando dos normas muy simples:
  8.     Los discos se pasan de una torre a otra de uno en uno.
  9.     Nunca un disco de mayor diámetro puede estar sobre otro de menor diámetro.
  10.     Se preguntará al inicio del programa por el tamaño de la torre O (entendiendo que tendrá el número de discos indicados, con algún límite preestablecido).
  11.     Las torres A y D estarán inicialmente vacías.
  12.     Se debe ofrecer la solución que da el programa a este problema paso a paso, mostrando el resultado de una forma gráfica. El inicio podría ser algo así:
  13.             *
  14.            ***
  15.           *****
  16.          *******
  17.         *********
  18.        ===========        ==========        ==========
  19.             O                A                D
  20. */
  21. /*
  22.     Formula para calcular movimientos mínimos necesarios:
  23.     m = 2^n -1
  24.     http://www.rodoval.com/heureka/hanoi/
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. void imprime( int *tab, int fil, int col, int ultNum )
  29. {
  30.     /*
  31.     Precondición:
  32.                     *tab    Puntero a una matriz de tipo entero.
  33.                     fil        Entero que indica el numero de filas de la matriz.
  34.                     col        Entero que indica el numero de columnas de la matriz.
  35.                     disc    Parámetro de tipo entero que indica el numero de discos usados.
  36.                     ultNum    Entero que indica el numero que esta usando el disco mas grande.
  37. */
  38.     int f, c;
  39.     int i, esp;
  40.     for( c=col-1; c >= 0; c-- )
  41.     {
  42.         for( f=0; f < fil; f++ )
  43.         {
  44.             esp = ( ultNum - tab[col*f+c] )/2;
  45.             // Espacios a la izquierda
  46.             for( i=0; i < esp; i++ )
  47.                 printf( " " );
  48.             // Imprime los comodines
  49.             for( i=0; i < tab[col*f+c]; i++ )
  50.                 printf( "*" );
  51.             // Espacios a la derecha
  52.             for( i=0; i < esp; i++ )
  53.                 printf( " " );
  54.             printf( "\t" );
  55.         };
  56.         printf( "\n" );
  57.     };
  58. };
  59. void mueveDisco( int *tab, int fil, int col, int ultNum, int filOrig, int filDest )
  60. {
  61.     /*
  62.     Precondición:
  63.                     *tab    Puntero a una matriz de tipo entero.
  64.                     fil        Entero que indica el numero de filas de la matriz.
  65.                     col        Entero que indica el numero de columnas de la matriz.
  66.                     disc    Parámetro de tipo entero que indica el numero de discos usados.
  67.                     ultNum    Entero que indica el numero que esta usando el disco mas grande.
  68.                     filOrig    Entero que indica el numero de fila de la matriz en la cual hay que coger el numero/disco
  69.                     filDest    Entero que indica el numero de fila de la matriz en la cual hay que dejar el numero/disco.
  70.     Poscondición:
  71.                     Se mueve el disco y se llama a la función que imprime el tablero.
  72.     */
  73.     int cO=col-1, cD=col-1;
  74.     // Se busca el disco que se encuentre mas arriba y por lo tanto el mas pequeño de la fila de origen.
  75.     while( cO >= 0  &&  tab[col*filOrig+cO] == 0 )
  76.     {
  77.         cO--;
  78.     };
  79.     if( cO < 0 )
  80.         cO = 0;
  81.     // Ahora se calcula cual es la posición libre mas arriba de la fila de destino
  82.     while( cD >= 0  &&  tab[col*filDest+cD] == 0 )
  83.     {
  84.         cD--;
  85.     };
  86.     // Se mueve el disco de la fila de origen a la de destino:
  87.     tab[col*filDest+cD+1] = tab[col*filOrig+cO];
  88.     tab[col*filOrig+cO] = 0;
  89.     // Se imprime el tablero:
  90.     imprime( tab, fil, col, ultNum );
  91. };
  92. void hanoi( int *tab, int fil, int col, int disc, int ultNum, int O, int A, int D )
  93. {
  94. /*
  95. Precondición:
  96.                 *tab    Puntero a una matriz de tipo entero.
  97.                 fil        Entero que indica el numero de filas de la matriz.
  98.                 col        Entero que indica el numero de columnas de la matriz.
  99.                 disc    Parámetro de tipo entero que indica el numero de discos usados.
  100.                 ultNum    Entero que indica el numero que esta usando el disco mas grande.
  101.                 O,A,D    Tres enteros que indican la fila desde donde se ha de coger el disco y a donde se ha de traspasar. La primera vez que se llama a hanoi tienen los valores de: 0 ,1 y 2 respectivamente.
  102. Poscondición:
  103.                 Se llama recursivamente a hanoi hasta resolver el tablero.
  104. */
  105.     if( disc==1 )
  106.     {
  107.         // Se borra la pantalla, se imprime la tabla y se hace una pausa que varia dependiendo del numero de discos:
  108.         system("clear");
  109.         mueveDisco( tab, fil, col, ultNum, O, D );
  110.         if(col<=5) system("sleep 0.8"); else if(col<=10) system("sleep 0.3"); else if(col<=15) system("sleep 0.06"); else if(col>15) system("sleep 0.02");
  111.     }
  112.     else
  113.     {
  114.         hanoi( tab, fil, col, disc-1, ultNum, O, D, A );
  115.         system("clear");
  116.         mueveDisco( tab, fil, col, ultNum, O, D );
  117.         if(col<=5) system("sleep 0.8"); else if(col<=10) system("sleep 0.3"); else if(col<=15) system("sleep 0.06"); else if(col>15) system("sleep 0.02");
  118.         hanoi( tab, fil, col, disc-1, ultNum, A, O, D );
  119.     };
  120. };
  121. main()
  122. {
  123.     int fil=3, col, *tablero = NULL;
  124.     int f, c, disc=1, ultNum;
  125.     printf( "Indique el numero de discos: " );
  126.     scanf( "%i", &col );
  127.     tablero = (int *)malloc( sizeof(int)*fil*col );
  128.     // Resetea las torres poniendo "los discos" en una de ellas y 0 en el resto.
  129.     for( f=0; f < fil; f++ )
  130.         for( c=col-1; c >= 0; c-- )
  131.             if( f==0 )
  132.             {
  133.                 tablero[col*f+c] = disc;
  134.                 disc+=2;
  135.             }
  136.             else
  137.                 tablero[col*f+c] = 0;
  138.     ultNum = disc;
  139.     // Se imprime el tablero antes de iniciar ningún movimiento:
  140.     system("clear");
  141.     imprime( tablero, fil, col, ultNum );
  142.     system("sleep 1");
  143.     // Se llama a hanoi para comenzar "la partida":
  144.     hanoi( tablero, fil, col, col, ultNum, 0, 1, 2 );
  145. };
Advertisement
Add Comment
Please, Sign In to add comment