Muchas gracias por los comentarios.
Adjunto el código que venia desarrollando, e indico que gracias a las observaciones, decidí buscar alguna solución iterativa, la encontré y es muy interesante.
Primeramente el código con recursividad es el clásico que conocemos sin embargo, para MikroC adjunté el envío de pulsos al puerto B, indicándome de que torre (ini) a que torre (fin) debo mover los discos.
PHP:
void mover(int n, int ini, int aux, int fin)
{
if(n==1)
{
switch(ini)
{
case 1: portb.rb5=1, delay_ms(500), portb.rb5=0;break;
case 2: portb.rb4=1, delay_ms(500), portb.rb4=0;break;
default:portb.rb3=1, delay_ms(500), portb.rb3=0;
}
switch(fin)
{
case 1: portb.rb5=1, delay_ms(500), portb.rb5=0;break;
case 2: portb.rb4=1, delay_ms(500), portb.rb4=0;break;
default:portb.rb3=1, delay_ms(500), portb.rb3=0;
}
}
else
{
mover(n-1, ini, fin, aux);
switch(ini)
{
case 1: portb.rb5=1, delay_ms(500), portb.rb5=0;break;
case 2: portb.rb4=1, delay_ms(500), portb.rb4=0;break;
default:portb.rb3=1, delay_ms(500), portb.rb3=0;
}
switch(fin)
{
case 1: portb.rb5=1, delay_ms(500), portb.rb5=0;break;
case 2: portb.rb4=1, delay_ms(500), portb.rb4=0;break;
default:portb.rb3=1, delay_ms(500), portb.rb3=0;
}
mover(n-1, aux, ini, fin);
}
}
void main()
{
trisb=0;
portb=0;
while(1)
{
mover(3, 1, 2, 3);
}
}
Definitivamente una solución recursiva no esta dando buenos resultados, el problema, como indicaban Ardogan, y Dr. Zoidberg, creo que tiene que ver con la memoria (RAM).
Como comenté anteriormente, la solución iterativa que encontré usa operadores de bits, realizando algunas mejoras y pruebas en C, queda el siguiente código:
PHP:
#include<stdio.h>
#include<stdlib.h>
main()
{
short n, t, i;
system("CLS");
printf("Numero de discos: ");
scanf("%d", &n);
t=(1<<n)-1;
printf("Numero de movimientos: %d\nMOVIMIENTOS:\n", t);
for(i=1;i<=t;i++)
printf("%d°:\tMover de la torre %d a la torre %d\n", i, ((i&i-1)%3)+1, (((i|i-1)+1)%3)+1);
system("PAUSE");
}
Explicación:
Como indicaba, utiliza el manejo de bits, estos operadores convierten una cantidad a su equivalente en bits (número binario) y después realiza un desplazamiento, puede ser a la izquierda, a la derecha, según se indique. Entonces:
t=(1<<n)-1;
Quiere decir: “almacenar en “t” la diferencia entre: el desplazamiento a la izquierda de 1, n veces; y 1”.
El equivalente de 1 a bits es “…00000001”; el operador “<<” indica desplazar a la izquierda; por tanto, como n=3, desplazaremos “…00000001”, 3 veces a la izquierda.
Desplazar a la izquierda significa recorrer hacia la izquierda los bits e insertar nuevos bits ceros a derecha, es decir:
Bits a ser desplazados : 00000001
1° desplazamiento : 00000010
2° desplazamiento : 00000100
3° desplazamiento : 00001000
Se realizaron tres desplazamientos hacia la izquierda, el equivalente en base diez de “00001000” es “8”. Luego almacenamos en “t” la diferencia entre “8” y “1”
t = 8 – 1
t = 7
Esto quiere decir que para tres discos se realizarán siete movimientos.
((i&i-1)%3)+1
En este caso se emplea el operador AND para el manejo de bits.
(((i|i-1)+1)%3)+1)
En este caso se emplea el operador OR para el manejo de bits.
(Si se necesita la explicación de cual es el funcionamiento de los operadores AND y OR en el manejo de bits, estoy presto a hacerlo).
Realicé una prueba de escritorio y al ver que el programa responde correctamente, adapté el mismo a MikroC, ahora el nuevo código es el siguiente:
PHP:
#define T 250
void main()
{
short n, i, ini, fin;
trisb=0;
portb=0;
n=3;
while(1)
{
if(portb.rb0==1)
{
for(i=1;i<(1<<n);i++)
{
ini=(i&i-1)%3;
fin=((i|i-1)+1)%3;
switch(ini)
{
case 0: portb.rb4=1, delay_ms(T), portb.rb4=0, delay_ms(T); break;
case 1: portb.rb3=1, delay_ms(T), portb.rb3=0, delay_ms(T); break;
case 2: portb.rb2=1, delay_ms(T), portb.rb2=0, delay_ms(T);
}
switch(fin)
{
case 0: portb.rb4=1, delay_ms(T), portb.rb4=0, delay_ms(T); break;
case 1: portb.rb3=1, delay_ms(T), portb.rb3=0, delay_ms(T); break;
case 2: portb.rb2=1, delay_ms(T), portb.rb2=0, delay_ms(T);
}
}
portb.rb1=1, delay_ms(T), portb.rb1=0, delay_ms(T);
portb=0;
}
}
}
Y la simulación en Proteus es el siguiente (estoy estudiando como adjuntar una imagen o un archivo adjunto a este mensaje)
Por ahora este avance nos muestra a través de los led’s, los movimientos que tenemos que realizar; es decir: “mover de la torre X a la torre Y”, el led “FIN” indica que ya se realizaron todos los movimientos.
Aquí adjunto el archivo Th2.rar, incluye:
-> thiter.cpp (programa en C)
-> ths2 (simulación en Ptoteus 8.4)
-> thp2 (código en MicroC).
Por favor, cualquier sugerencia será bienvenida.