Sucede y Precede

 

La manera en que Karel maneja las variables se hace a través de los comandos sucede y precede. Estos dos comandos tienen el objetivo de aumentar y disminuir, respectivamente, el valor de una ‘variable’ o identificador dentro del programa, en uno. Para ejemplificar lo anterior veremos el siguiente problema:

 

El manejo de las variables es limitado en Karel, solo deberán ser utilizados en la instrucción que fueron creadas, no podrán ser referenciadas desde afuera, al menos que esta instrucción llame a otra con el valor de esta variable. En esta segunda instrucción, la variable, será tomada como una nueva, es decir, independiente del nombre como fue tratada en la primera instrucción. Karel marca error de violación si se hace lo anterior.

La figura # 1 muestra a Karel con muchos montones de zumbadores enfrente, Karel deberá avanzar tantas calles como zumbadores existan en el montón donde esté y al que salte, y así sucesivamente, es decir, inicialmente se encuentra en un montón con dos zumbadores, deberá avanzar dos calles, luego, si en la calle donde se posicionó existen zumbadores, Karel deberá hacer lo mismo hasta que llegue a una calle donde no exista ninguno, ahí deberá apagarse. Para resolver este problema, podrá hacerse así:

 

iniciar-programa

    define-nueva-instruccion resta(num) como inicio

            si no si-es-cero(num) entonces inicio

                avanza;

                resta(precede(num));

            fin;

        fin;

    define-nueva-instruccion cuenta(num) como

        inicio

            si algun-zumbador-en-la-mochila entonces inicio

                deja-zumbador;

                cuenta(sucede(num));

            fin

            sino resta(num);

        fin;

    inicia-ejecucion

        mientras junto-a-zumbador hacer inicio

            mientras junto-a-zumbador hacer coge-zumbador;

            cuenta(0);

        fin;

        apagate;

    termina-ejecucion

finalizar-programa

 

Otro ejemplo podrá ser:

 

 

Indicar que montón es el menor. Aquí se limita el movimiento de Karel que impide realizar otros para resolver la situación. Por lo que se forza a utilizar precede y sucede. Las siguientes condiciones y peticiones existen:

 

* Karel se encuentra orientado hacia el este

* Karel está posicionado sobre un montón de zumbadores y enfrente de el está un segundo montón

* Karel deberá seleccionar y posicionarse sobre el montón sobre el cual existen menos zumbadores

* Existen paredes que limitan el movimiento de Karel como lo muestra la Figura #1.

 

De la siguiente manera será evaluado correctamente que montón tiene menos zumbadores:

 

a) Tomar los zumbadores del montón donde se encuentra Karel inicialmente

b) Dejar los zumbadores es esa misma posición e irlos contando – incrementando en uno – en una variable

c) Pasarse al siguiente montón y tomar esos zumbadores

d) Igualmente dejarlos en esta posición y disminuir en uno a la variable que se utilizó para contar los zumbadores del primer montón

e) Por último, si esa variable es cero (0) o negativa – se evaluará mediante la instrucción si-es-cero – querrá decir que el primer montón es el que contiene menos zumbadores, si esa variable es positiva, el montón que tiene más zumbadores es el segundo. Mediante el siguiente programa lograremos lo anterior:

 

 

iniciar-programa

    define-nueva-instruccion resta(num) como

        inicio

            si no si-es-cero(num) entonces

                si junto-a-zumbador entonces

                inicio

                    coge-zumbador;

                    resta(precede(num));

                fin;

            si no-junto-a-zumbador entonces apagate sino

            inicio

                gira-izquierda;

                gira-izquierda;

                avanza;

                apagate;

            fin;

        fin;

    define-nueva-instruccion cuenta(num) como

        inicio

            si algun-zumbador-en-la-mochila entonces

            inicio

                deja-zumbador;

                cuenta(sucede(num));

            fin

            sino

                inicio

                    avanza;

                    resta(num);

                fin;

        fin;

    inicia-ejecucion

        mientras junto-a-zumbador hacer coge-zumbador;

        cuenta(0);

        apagate;

    termina-ejecucion

finalizar-programa

 

Aquí, se cambió la mecánica, pero en esencia es lo mismo que en la solución anterior. Contar al dejar los zumbadores del primer montón, avanzar y contar los siguientes, pero al tomarlos no al dejarlos. Luego, mediante si-no-es-cero y; si hay zumbadores en el segundo montón al llegar a la cantidad del anterior y aún hay zumbadores en este segundo, respectivamente se dará: el primero es menor o el segundo es menor cuando ya no hay zumbadores aquí en el segundo montón.

 

Ya como un problema completo, se tiene el tercero de Morelia en 2004.

 

Encontrar el montón donde existen más zumbadores, si se sabe que el aumento/disminución es constante y no existen dos o más lugares en el cuadro con el mismo número, es decir, el cuadro está formado por montones de zumbadores cuyas cantidades están relacionadas unas con otras de forma regular.

Para resolver este problema se utilizará la técnica anterior, primero viajando al norte y encontrar el montón con más zumbadores de manera vertical; luego viajar al este y encontrar el montón de forma horizontal, donde se encuentre este montón, ahí será el que contenga más zumbadores.

 

 

iniciar-programa

    define-nueva-instruccion Resta(num) como

        si no si-es-cero(num) entonces inicio

            si junto-a-zumbador entonces inicio

                coge-zumbador;

                Resta(Precede(num));

            fin

            sino inicio

                mientras algun-zumbador-en-la-mochila hacer deja-zumbador;

                gira-izquierda;

                gira-izquierda;

                avanza;

            fin;

        fin;

    define-nueva-instruccion Cuenta(num) como

        si algun-zumbador-en-la-mochila entonces inicio

            deja-zumbador;

            Cuenta(Sucede(num));

        fin

        sino inicio

            avanza;

            Resta(num);

        fin;

    inicia-ejecucion

        mientras orientado-al-norte hacer inicio

            mientras junto-a-zumbador hacer coge-zumbador;

            Cuenta(0);

        fin;

        gira-izquierda;

        mientras orientado-al-este hacer inicio

            mientras junto-a-zumbador hacer coge-zumbador;

            Cuenta(0);

        fin;

        apagate;

    termina-ejecucion

finalizar-programa

 

Se dan dos gira-izquierda porque el montón donde está actualmente Karel, es el menor; si no, sigue avanzando porque en el que se estuvo al último, fue el mayor.

 

El problema número 3 de la X edición de la OMI en Durango en el año 2005, presentó uno que también puede resolverse con sucede y precede de forma recursiva. Este ya fue descrito en el documento de recursividad en Karel.

 

 

 

iniciar-programa

    define-nueva-instruccion TomaYEjecuta(cuantos) como inicio

        si junto-a-zumbador entonces inicio

            coge-zumbador;

            TomaYEjecuta(Sucede(cuantos));

        fin

        sino inicio

            si frente-libre entonces inicio

                avanza;

                TomaYEjecuta(0);

            fin;

            si si-es-cero(precede(cuantos)) entonces

                mientras no-orientado-al-norte hacer gira-izquierda;

            si si-es-cero(precede(precede(cuantos))) entonces

               mientras no-orientado-al-este hacer gira-izquierda;

            si si-es-cero(precede(precede(precede(cuantos)))) entonces

               mientras no-orientado-al-sur hacer gira-izquierda;

            si si-es-cero(precede(precede(precede(precede(cuantos))))) entonces

                mientras no-orientado-al-oeste hacer gira-izquierda;

            avanza;

        fin;

    fin;

    inicia-ejecucion

        mientras junto-a-zumbador y frente-libre hacer

            avanza;

        gira-izquierda;

        gira-izquierda;

        si no-junto-a-zumbador entonces

            avanza;

        TomaYEjecuta(0);

        apagate;

    termina-ejecucion

finalizar-programa

 

La secuencia del programa anterior es:

 

a) En el núcleo principal del programa, Karel se posiciona en la parte derecha de la fila de zumbadores, tal como se hizo en la solución con recursividad.

b) Acumula la variable cuantos dependiendo de la cantidad de zumbadores en donde Karel se encuentra posicionado

c) Si frente-libre avanza al siguiente montón para contar de nuevo.

d) Al ejecutar los puntos b) y c), se deja pendiente instrucciones que evaluaran el valor que se acumuló en cuantos, dependiendo del valor se orientará hacia la dirección correcta y avanzará. Este punto, d), se ejecuta cuando no hay zumbadores en la actual posición donde se encuentra Karel.