38
Agosto 2007 Facultad de Ciencias Físico-Matemáticas sede de la UANL Olimpiada Estatal de Informática de Nuevo León - 1 - KAREL OMI Versión 2.0 por Cesar Cepeda Para comentarios escriba a [email protected] Revisado por Eduardo Urias Barrientos AKA Wero Shinoda TUTORIAL DE KAREL 1. Introducción: Por qué programamos el robot Karel. 2. El mundo de Karel: Como visualizamos y configuramos el lugar que ocupa Karel. 3. Programando Karel: Como le decimos a Karel qué cosas debe hacer. 4. Comandos básicos de Karel: Las cosas que Karel es capaz de hacer incluso sin pensar. 5. Sentencias de Control de Karel: Las sentencias de control se usan para seleccionar que órdenes se deben ejecutar. 6. La sentencia si/entonces: A veces, Karel siente la necesidad de realizar algo sólo en ciertas condiciones. 7. Condiciones que puede detectar Karel: Una condición es una función de la situación actual de Karel, tal como él ejecuta las órdenes. 8. La sentencia repetir/veces: Es útil cuando se sabe exactamente cuantas veces se debe de realizar una cosa. 9. La sentencia si/entonces/sino: Karel puede darse cuenta que necesita realizar una cosa u otra. 10. La sentencia mientras/hacer: Extremadamente valiosa cuando no se sabe de antemano exactamente cuantas veces se necesita realizar una tarea. 11. La sentencia define-nueva-instruccion/como: Usando la taquigrafía de Karel para tareas que se realizan a menudo. 12. Parametros en instrucciones: Usando variables. 13. Las funciones sucede y precede: Incrementando y decrementando variables. 14. La función si-es-cero: ¿Es mi variable cero? 15. Recursividad: ¿Necesitas contar? ¡Usa recursividad!

Tutorial Karel avanzado Java

  • Upload
    navaeli

  • View
    564

  • Download
    4

Embed Size (px)

Citation preview

Page 1: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 1 -

KAREL OMI Versioacuten 20 por Cesar Cepeda

Para comentarios escriba a cesarauronixcom

Revisado por Eduardo Urias Barrientos AKA Wero Shinoda

TUTORIAL DE KAREL

1 Introduccioacuten Por queacute programamos el robot Karel

2 El mundo de Karel Como visualizamos y configuramos el lugar que ocupa Karel

3 Programando Karel Como le decimos a Karel queacute cosas debe hacer

4 Comandos baacutesicos de Karel Las cosas que Karel es capaz de hacer incluso sin

pensar

5 Sentencias de Control de Karel Las sentencias de control se usan para seleccionar

que oacuterdenes se deben ejecutar

6 La sentencia sientonces A veces Karel siente la necesidad de realizar algo soacutelo en

ciertas condiciones

7 Condiciones que puede detectar Karel Una condicioacuten es una funcioacuten de la situacioacuten

actual de Karel tal como eacutel ejecuta las oacuterdenes

8 La sentencia repetirveces Es uacutetil cuando se sabe exactamente cuantas veces se

debe de realizar una cosa

9 La sentencia sientoncessino Karel puede darse cuenta que necesita realizar una

cosa u otra

10 La sentencia mientrashacer Extremadamente valiosa cuando no se sabe de

antemano exactamente cuantas veces se necesita realizar una tarea

11 La sentencia define-nueva-instruccioncomo Usando la taquigrafiacutea de Karel para

tareas que se realizan a menudo

12 Parametros en instrucciones Usando variables

13 Las funciones sucede y precede Incrementando y decrementando variables

14 La funcioacuten si-es-cero iquestEs mi variable cero

15 Recursividad iquestNecesitas contar iexclUsa recursividad

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 2 -

Por queacute programamos Karel

Programar un ordenador en un lenguaje como JAVA requiere un secuenciamiento preciso

de los pasos uno detraacutes de otro escogiendo queacute pasos hay que seguir en cada caso y

controlando la repeticioacuten de ciertos pasos en el proceso de resolucioacuten de un problema

Aunque esta precisioacuten se requiere para las operaciones sin razonamiento de las

computadoras es extrantildea a los humanos Los humanos somos mucho menos riacutegidos en

nuestro comportamiento y podemos retroceder elegantemente si nuestros pasos no parecen

llevar a la consecucioacuten de un objetivo Debido a que son diferentes las habilidades de las

computadoras y lo humanos expresar la solucioacuten de un problema en instrucciones que una

computadora puede seguir estaacute comprobado que es difiacutecil para mucha gente Para conocer

estos conceptos nosotros empezaremos programando el Robot Karel Karel es una

herramienta de aprendizaje que presenta los conceptos de una forma visual lo cual es

menos abstracto que programar en un lenguaje como JAVA o C El Robot Karel fue

introducido por Richard Pattis en su libro Karel the Robot A Gentle Introduction to the Art

of Programming with Pascal John Wiley amp Sons Inc 1981 Aunque el lenguaje por

default es Pascal tambieacuten se puede programar en JAVA

Nosotros programaremos Karel un Robot simple que vive en un mundo simple Debido a

que Karel y su mundo son simulados iexclnosotros podemos realmente ver los resultados de un

programa en accioacuten El lenguaje con el que programaremos Karel es una versioacuten especial

de JAVA por lo tanto la mayor parte de lo que aprendamos podraacute ser aplicado

directamente al lenguaje de programacioacuten estaacutendar JAVA

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 3 -

El mundo de Karel

Karel puede orientarse en una de las cuatro direcciones Este Oeste Norte y Sur Soacutelo gira

90ordm cada vez por tanto no puede orientarse hacia en NordEste por ejemplo En el mundo

de Karel las calles van de Este a Oeste y son numeradas comenzando por 1 No hay

nuacutemeros de calle igual a 0 o negativos Las avenidas van de Norte a Sur y tambieacuten estaacuten

numeradas empezando por 1 Tampoco hay nuacutemeros de avenida igual a 0 o negativos Se le

llama esquina a la interseccioacuten de una calle con una avenida Karel va de una esquina a la

siguiente en un solo movimiento Ejecuta el programa Karelexe de la carpeta KarelOMI

Se iniciaraacute el simulador del Robot Ahora deberiacuteas ver la ventana de abajo

Esta ventana muestra las calles y avenidas que usa Karel para desplazarse Primero

debemos inicializar (o crear) el mundo que Karel va a ocupar La idea es que puedas

introducir algunos elementos en el mundo inicial de Karel

Puedes colocar y quitar muros en el Norte Sur Este u Oeste del cursor dando click con el

botoacuten izquierdo del ratoacuten en la interseccioacuten de las calles correspondientes Los muros que

limitan las calles y avenidas no se pueden quitar eacutestos son los que previenen que Karel se

salga del mundo Prueba a introducir algunos muros para ver que aspecto tienen

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 4 -

Otro elemento de intereacutes en el mundo de Karel son los zumbadores Un zumbador es una

forma de marca que Karel puede escuchar soacutelo cuando se encuentra en la misma esquina

que el zumbador Karel tiene una mochila que puede utilizar para poner los zumbadores

que vaya cogiendo Tambieacuten puede hacer lo contrario es decir sacar los zumbadores de su

mochila y depositarlos en las esquinas por las que va pasando Puedes ajustar el nuacutemero

inicial de zumbadores en cada esquina dando click con el botoacuten derecho del ratoacuten en la

calle deseada y seleccionando el nuacutemero de zumbadores deseados (para colocar entre 10 y

99 zumbadores selecciona la opcioacuten N zumbadores y escribe el nuacutemero deseado)

Prueba a poner algunos zumbadores para ver como se visualizan en el mundo Crea el

mundo inicial que se muestra a continuacioacuten Dado que hemos realizado todo el trabajo

necesario para crear un mundo para Karel iexclvamos a guardarlo Pulsa sobre el botoacuten

Guardar ve a tu directorio particular y guarda el mundo como ldquoNuevoMundomdordquo

Finalmente iexclKarel tiene su sitio en el mundo Mueve el cursor del ratoacuten hacia la esquina de

la Avenida 15 y Calle 1 y da click con el botoacuten derecho del mouse situa el puntero del

ratoacuten en la opcioacuten Situar a Karel y elige Orientado al Oeste Ahora deberiacuteas visualizar

el mundo de abajo Haz de nuevo click sobre el botoacuten Guardar para almacenar los

cambios

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 5 -

Programando Karel

Antes de poder empezar necesitamos dar a Karel un programa (serie de instrucciones) a

seguir Despueacutes de todo iexcles soacutelo un Robot Pulsa sobre la pestantildea Programa Ahora

deberiacuteas ver una ventana con el aspecto de esta de abajo La zona que estaacute vaciacutea es donde

escribiremos y veremos el programa de Karel

El lenguaje por default es Pascal para programar en JAVA selecciona la opcioacuten que viene

a la izquierda de los botones Ahora pulsa en el botoacuten Nuevo Un esqueleto del

programa seraacute creado automaacuteticamente Se crearaacute un programa inicial Este programa

inicial contiene los comandos baacutesicos que son necesarios en cada programa Ahora deberiacuteas

ver una ventana como la siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 6 -

Date cuenta de que el programa anterior soacutelo le dice a Karel que se apague Antes de

apagarlo vamos a mandarle algunas tareas La orden move le dice a Karel que se

mueva hacia adelante una esquina Escribe move() antes deturnoff() Date cuenta de

que el punto y coma se usa para separar oacuterdenes (tal como en JAVA) Ahora pulsa el botoacuten

Compilar Si no has cometido ninguacuten error tu programa tendraacutes el aspecto del de la

ventana siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 2: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 2 -

Por queacute programamos Karel

Programar un ordenador en un lenguaje como JAVA requiere un secuenciamiento preciso

de los pasos uno detraacutes de otro escogiendo queacute pasos hay que seguir en cada caso y

controlando la repeticioacuten de ciertos pasos en el proceso de resolucioacuten de un problema

Aunque esta precisioacuten se requiere para las operaciones sin razonamiento de las

computadoras es extrantildea a los humanos Los humanos somos mucho menos riacutegidos en

nuestro comportamiento y podemos retroceder elegantemente si nuestros pasos no parecen

llevar a la consecucioacuten de un objetivo Debido a que son diferentes las habilidades de las

computadoras y lo humanos expresar la solucioacuten de un problema en instrucciones que una

computadora puede seguir estaacute comprobado que es difiacutecil para mucha gente Para conocer

estos conceptos nosotros empezaremos programando el Robot Karel Karel es una

herramienta de aprendizaje que presenta los conceptos de una forma visual lo cual es

menos abstracto que programar en un lenguaje como JAVA o C El Robot Karel fue

introducido por Richard Pattis en su libro Karel the Robot A Gentle Introduction to the Art

of Programming with Pascal John Wiley amp Sons Inc 1981 Aunque el lenguaje por

default es Pascal tambieacuten se puede programar en JAVA

Nosotros programaremos Karel un Robot simple que vive en un mundo simple Debido a

que Karel y su mundo son simulados iexclnosotros podemos realmente ver los resultados de un

programa en accioacuten El lenguaje con el que programaremos Karel es una versioacuten especial

de JAVA por lo tanto la mayor parte de lo que aprendamos podraacute ser aplicado

directamente al lenguaje de programacioacuten estaacutendar JAVA

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 3 -

El mundo de Karel

Karel puede orientarse en una de las cuatro direcciones Este Oeste Norte y Sur Soacutelo gira

90ordm cada vez por tanto no puede orientarse hacia en NordEste por ejemplo En el mundo

de Karel las calles van de Este a Oeste y son numeradas comenzando por 1 No hay

nuacutemeros de calle igual a 0 o negativos Las avenidas van de Norte a Sur y tambieacuten estaacuten

numeradas empezando por 1 Tampoco hay nuacutemeros de avenida igual a 0 o negativos Se le

llama esquina a la interseccioacuten de una calle con una avenida Karel va de una esquina a la

siguiente en un solo movimiento Ejecuta el programa Karelexe de la carpeta KarelOMI

Se iniciaraacute el simulador del Robot Ahora deberiacuteas ver la ventana de abajo

Esta ventana muestra las calles y avenidas que usa Karel para desplazarse Primero

debemos inicializar (o crear) el mundo que Karel va a ocupar La idea es que puedas

introducir algunos elementos en el mundo inicial de Karel

Puedes colocar y quitar muros en el Norte Sur Este u Oeste del cursor dando click con el

botoacuten izquierdo del ratoacuten en la interseccioacuten de las calles correspondientes Los muros que

limitan las calles y avenidas no se pueden quitar eacutestos son los que previenen que Karel se

salga del mundo Prueba a introducir algunos muros para ver que aspecto tienen

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 4 -

Otro elemento de intereacutes en el mundo de Karel son los zumbadores Un zumbador es una

forma de marca que Karel puede escuchar soacutelo cuando se encuentra en la misma esquina

que el zumbador Karel tiene una mochila que puede utilizar para poner los zumbadores

que vaya cogiendo Tambieacuten puede hacer lo contrario es decir sacar los zumbadores de su

mochila y depositarlos en las esquinas por las que va pasando Puedes ajustar el nuacutemero

inicial de zumbadores en cada esquina dando click con el botoacuten derecho del ratoacuten en la

calle deseada y seleccionando el nuacutemero de zumbadores deseados (para colocar entre 10 y

99 zumbadores selecciona la opcioacuten N zumbadores y escribe el nuacutemero deseado)

Prueba a poner algunos zumbadores para ver como se visualizan en el mundo Crea el

mundo inicial que se muestra a continuacioacuten Dado que hemos realizado todo el trabajo

necesario para crear un mundo para Karel iexclvamos a guardarlo Pulsa sobre el botoacuten

Guardar ve a tu directorio particular y guarda el mundo como ldquoNuevoMundomdordquo

Finalmente iexclKarel tiene su sitio en el mundo Mueve el cursor del ratoacuten hacia la esquina de

la Avenida 15 y Calle 1 y da click con el botoacuten derecho del mouse situa el puntero del

ratoacuten en la opcioacuten Situar a Karel y elige Orientado al Oeste Ahora deberiacuteas visualizar

el mundo de abajo Haz de nuevo click sobre el botoacuten Guardar para almacenar los

cambios

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 5 -

Programando Karel

Antes de poder empezar necesitamos dar a Karel un programa (serie de instrucciones) a

seguir Despueacutes de todo iexcles soacutelo un Robot Pulsa sobre la pestantildea Programa Ahora

deberiacuteas ver una ventana con el aspecto de esta de abajo La zona que estaacute vaciacutea es donde

escribiremos y veremos el programa de Karel

El lenguaje por default es Pascal para programar en JAVA selecciona la opcioacuten que viene

a la izquierda de los botones Ahora pulsa en el botoacuten Nuevo Un esqueleto del

programa seraacute creado automaacuteticamente Se crearaacute un programa inicial Este programa

inicial contiene los comandos baacutesicos que son necesarios en cada programa Ahora deberiacuteas

ver una ventana como la siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 6 -

Date cuenta de que el programa anterior soacutelo le dice a Karel que se apague Antes de

apagarlo vamos a mandarle algunas tareas La orden move le dice a Karel que se

mueva hacia adelante una esquina Escribe move() antes deturnoff() Date cuenta de

que el punto y coma se usa para separar oacuterdenes (tal como en JAVA) Ahora pulsa el botoacuten

Compilar Si no has cometido ninguacuten error tu programa tendraacutes el aspecto del de la

ventana siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 3: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 3 -

El mundo de Karel

Karel puede orientarse en una de las cuatro direcciones Este Oeste Norte y Sur Soacutelo gira

90ordm cada vez por tanto no puede orientarse hacia en NordEste por ejemplo En el mundo

de Karel las calles van de Este a Oeste y son numeradas comenzando por 1 No hay

nuacutemeros de calle igual a 0 o negativos Las avenidas van de Norte a Sur y tambieacuten estaacuten

numeradas empezando por 1 Tampoco hay nuacutemeros de avenida igual a 0 o negativos Se le

llama esquina a la interseccioacuten de una calle con una avenida Karel va de una esquina a la

siguiente en un solo movimiento Ejecuta el programa Karelexe de la carpeta KarelOMI

Se iniciaraacute el simulador del Robot Ahora deberiacuteas ver la ventana de abajo

Esta ventana muestra las calles y avenidas que usa Karel para desplazarse Primero

debemos inicializar (o crear) el mundo que Karel va a ocupar La idea es que puedas

introducir algunos elementos en el mundo inicial de Karel

Puedes colocar y quitar muros en el Norte Sur Este u Oeste del cursor dando click con el

botoacuten izquierdo del ratoacuten en la interseccioacuten de las calles correspondientes Los muros que

limitan las calles y avenidas no se pueden quitar eacutestos son los que previenen que Karel se

salga del mundo Prueba a introducir algunos muros para ver que aspecto tienen

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 4 -

Otro elemento de intereacutes en el mundo de Karel son los zumbadores Un zumbador es una

forma de marca que Karel puede escuchar soacutelo cuando se encuentra en la misma esquina

que el zumbador Karel tiene una mochila que puede utilizar para poner los zumbadores

que vaya cogiendo Tambieacuten puede hacer lo contrario es decir sacar los zumbadores de su

mochila y depositarlos en las esquinas por las que va pasando Puedes ajustar el nuacutemero

inicial de zumbadores en cada esquina dando click con el botoacuten derecho del ratoacuten en la

calle deseada y seleccionando el nuacutemero de zumbadores deseados (para colocar entre 10 y

99 zumbadores selecciona la opcioacuten N zumbadores y escribe el nuacutemero deseado)

Prueba a poner algunos zumbadores para ver como se visualizan en el mundo Crea el

mundo inicial que se muestra a continuacioacuten Dado que hemos realizado todo el trabajo

necesario para crear un mundo para Karel iexclvamos a guardarlo Pulsa sobre el botoacuten

Guardar ve a tu directorio particular y guarda el mundo como ldquoNuevoMundomdordquo

Finalmente iexclKarel tiene su sitio en el mundo Mueve el cursor del ratoacuten hacia la esquina de

la Avenida 15 y Calle 1 y da click con el botoacuten derecho del mouse situa el puntero del

ratoacuten en la opcioacuten Situar a Karel y elige Orientado al Oeste Ahora deberiacuteas visualizar

el mundo de abajo Haz de nuevo click sobre el botoacuten Guardar para almacenar los

cambios

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 5 -

Programando Karel

Antes de poder empezar necesitamos dar a Karel un programa (serie de instrucciones) a

seguir Despueacutes de todo iexcles soacutelo un Robot Pulsa sobre la pestantildea Programa Ahora

deberiacuteas ver una ventana con el aspecto de esta de abajo La zona que estaacute vaciacutea es donde

escribiremos y veremos el programa de Karel

El lenguaje por default es Pascal para programar en JAVA selecciona la opcioacuten que viene

a la izquierda de los botones Ahora pulsa en el botoacuten Nuevo Un esqueleto del

programa seraacute creado automaacuteticamente Se crearaacute un programa inicial Este programa

inicial contiene los comandos baacutesicos que son necesarios en cada programa Ahora deberiacuteas

ver una ventana como la siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 6 -

Date cuenta de que el programa anterior soacutelo le dice a Karel que se apague Antes de

apagarlo vamos a mandarle algunas tareas La orden move le dice a Karel que se

mueva hacia adelante una esquina Escribe move() antes deturnoff() Date cuenta de

que el punto y coma se usa para separar oacuterdenes (tal como en JAVA) Ahora pulsa el botoacuten

Compilar Si no has cometido ninguacuten error tu programa tendraacutes el aspecto del de la

ventana siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 4: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 4 -

Otro elemento de intereacutes en el mundo de Karel son los zumbadores Un zumbador es una

forma de marca que Karel puede escuchar soacutelo cuando se encuentra en la misma esquina

que el zumbador Karel tiene una mochila que puede utilizar para poner los zumbadores

que vaya cogiendo Tambieacuten puede hacer lo contrario es decir sacar los zumbadores de su

mochila y depositarlos en las esquinas por las que va pasando Puedes ajustar el nuacutemero

inicial de zumbadores en cada esquina dando click con el botoacuten derecho del ratoacuten en la

calle deseada y seleccionando el nuacutemero de zumbadores deseados (para colocar entre 10 y

99 zumbadores selecciona la opcioacuten N zumbadores y escribe el nuacutemero deseado)

Prueba a poner algunos zumbadores para ver como se visualizan en el mundo Crea el

mundo inicial que se muestra a continuacioacuten Dado que hemos realizado todo el trabajo

necesario para crear un mundo para Karel iexclvamos a guardarlo Pulsa sobre el botoacuten

Guardar ve a tu directorio particular y guarda el mundo como ldquoNuevoMundomdordquo

Finalmente iexclKarel tiene su sitio en el mundo Mueve el cursor del ratoacuten hacia la esquina de

la Avenida 15 y Calle 1 y da click con el botoacuten derecho del mouse situa el puntero del

ratoacuten en la opcioacuten Situar a Karel y elige Orientado al Oeste Ahora deberiacuteas visualizar

el mundo de abajo Haz de nuevo click sobre el botoacuten Guardar para almacenar los

cambios

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 5 -

Programando Karel

Antes de poder empezar necesitamos dar a Karel un programa (serie de instrucciones) a

seguir Despueacutes de todo iexcles soacutelo un Robot Pulsa sobre la pestantildea Programa Ahora

deberiacuteas ver una ventana con el aspecto de esta de abajo La zona que estaacute vaciacutea es donde

escribiremos y veremos el programa de Karel

El lenguaje por default es Pascal para programar en JAVA selecciona la opcioacuten que viene

a la izquierda de los botones Ahora pulsa en el botoacuten Nuevo Un esqueleto del

programa seraacute creado automaacuteticamente Se crearaacute un programa inicial Este programa

inicial contiene los comandos baacutesicos que son necesarios en cada programa Ahora deberiacuteas

ver una ventana como la siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 6 -

Date cuenta de que el programa anterior soacutelo le dice a Karel que se apague Antes de

apagarlo vamos a mandarle algunas tareas La orden move le dice a Karel que se

mueva hacia adelante una esquina Escribe move() antes deturnoff() Date cuenta de

que el punto y coma se usa para separar oacuterdenes (tal como en JAVA) Ahora pulsa el botoacuten

Compilar Si no has cometido ninguacuten error tu programa tendraacutes el aspecto del de la

ventana siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 5: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 5 -

Programando Karel

Antes de poder empezar necesitamos dar a Karel un programa (serie de instrucciones) a

seguir Despueacutes de todo iexcles soacutelo un Robot Pulsa sobre la pestantildea Programa Ahora

deberiacuteas ver una ventana con el aspecto de esta de abajo La zona que estaacute vaciacutea es donde

escribiremos y veremos el programa de Karel

El lenguaje por default es Pascal para programar en JAVA selecciona la opcioacuten que viene

a la izquierda de los botones Ahora pulsa en el botoacuten Nuevo Un esqueleto del

programa seraacute creado automaacuteticamente Se crearaacute un programa inicial Este programa

inicial contiene los comandos baacutesicos que son necesarios en cada programa Ahora deberiacuteas

ver una ventana como la siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 6 -

Date cuenta de que el programa anterior soacutelo le dice a Karel que se apague Antes de

apagarlo vamos a mandarle algunas tareas La orden move le dice a Karel que se

mueva hacia adelante una esquina Escribe move() antes deturnoff() Date cuenta de

que el punto y coma se usa para separar oacuterdenes (tal como en JAVA) Ahora pulsa el botoacuten

Compilar Si no has cometido ninguacuten error tu programa tendraacutes el aspecto del de la

ventana siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 6: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 6 -

Date cuenta de que el programa anterior soacutelo le dice a Karel que se apague Antes de

apagarlo vamos a mandarle algunas tareas La orden move le dice a Karel que se

mueva hacia adelante una esquina Escribe move() antes deturnoff() Date cuenta de

que el punto y coma se usa para separar oacuterdenes (tal como en JAVA) Ahora pulsa el botoacuten

Compilar Si no has cometido ninguacuten error tu programa tendraacutes el aspecto del de la

ventana siguiente

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 7: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 7 -

Pulsa la pestantildea de Ejecutar y despueacutes haz click en el botoacuten Inicializar (Ejecutar inicia la

ejecucioacuten (correr) de nuestro programa Al Inicializar se muestra el mundo que habiacuteamos

creado previamente (NuevoMundomdo)) Ahora deberiacuteas ver la ventana de abajo

(asumiendo que el fichero ldquoNuevoMundomdordquo que creaste estaacute todaviacutea abierto Si no

pulsa en la pestantildea ldquoMundordquo y pulsando en el botoacuten ldquoAbrirrdquo selecciona el fichero

ldquoNuevoMundomdordquo que guardaste en el punto anterior)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 8: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 8 -

Cuando des click en adelante podraacutes darte cuenta que la instruccioacuten move() se colorea de

rojo En este punto haz click en ldquoAdelanterdquo para que Karel realice esa primera orden del

programa iexclWow Karel se ha movido solo Date cuenta que la instruccioacuten en rojo ahora es

turnoff() Haz click sobre ldquoAdelanterdquode nuevo Ahora el programa terminaraacute

correctamente Si quieres probarlo otra vez antes tendraacutes que pulsar sobre el botoacuten

Inicializar

Ejercicio 1 Escribe un programa de Karel para que se mueva a la esquina de la 1ordf Calle

con la 1ordf Avenida y se desconecte asumiendo que empieza en la esquina de la Calle 15 y la

Avenida 15 con orientacioacuten hacia el Oeste Guarda el programa con el nombre

ldquoprimerProgramatxtrdquo Como mundo utiliza el guardado anteriormente con el nombre

ldquoNuevoMundomdordquo

iexcliexcl Inteacutentalo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 9: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 9 -

Comandos baacutesicos de Karel

Hay cinco comandos baacutesicos para Karel estos son

1 move() (avanza una esquina)

2 turnleft() (gira a la izquierda)

3 pickbeeper() (coge un zumbador)

4 putbeeper() (deja un zumpador)

5 turnoff() (desconeacutectate)

La salud de Karel

Andar entre muros no es bueno para un robot por lo tanto Karel tiene algunos mecanismos

salvavidas dentro de eacutel Si un programa le dice a Karel que se mueva aunque haya un muro

delante de eacutel eacutel diraacute que hay un error y no realizaraacute la accioacuten Lo mismo ocurriraacute si le

decimos que coja un zumbador en una esquina y no existe ninguno Las uacutenicas oacuterdenes que

siempre lleva a cabo sin importar la situacioacuten en la que se encuentre son turnleft() y

turnoff() Cuando Karel nos dice que hay un error no tenemos que echarle la culpa sino

que probablemente habremos escrito mal alguna instruccioacuten

Ejercicio 2 Cada mantildeana Karel se levanta de la cama y tiene que recoger el perioacutedico

representado por un zumbador que estaacute en el porche de la casa Escribe un programa que

ordene a Karel que recoja el perioacutedico y lo lleve de vuelta a la cama La situacioacuten inicial es

la de la imagen de abajo y la situacioacuten final debe tener a Karel de vuelta en la cama (misma

esquina misma direccioacuten que cuando empezoacute) con el perioacutedico (zumbador en su mochila)

Crea un mundo como el de la imagen y guaacuterdalo como ldquoperiodicomdordquo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 10: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 10 -

Sentencias de Control de KAREL

Las sentencias de control se usan para elegir queacute hacer yo cuantas veces hacerlo Sin

embargo por si solos no causan que ocurra algo Simplemente controlan la ejecucioacuten de

otras sentencias o fragmentos de coacutedigo A continuacioacuten se lista una serie de sentencias de

control de Karel

if

iterate

ifelse

while

Siempre a continuacioacuten de las sentencias de control y despueacutes de la expresioacuten booleana se

debe colocar una llave que abre para iniciar el grupo de sentencias a ser realizado El

grupo de sentencias va seguido de una llave que cierra Utilizamos el par para un

soacutelo paraacutemetro o para varios no importa el nuacutemero de ellos El compilador devolveraacute una

advertencia en caso de que no se siga este estilo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 11: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 11 -

La sentencia if

En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este iquestY si supieacuteramos que

cuando se inicia estaacute orientado hacia el Oeste o hacia el Sur A veces necesitaremos girar

primero tres veces y a veces no En este caso la sentencia de control if es lo que

necesitamos en nuestro programa Aquiacute hay un ejemplo de como se debe escribir

if (facingSouth)

turnleft()

turnleft()

turnleft()

Las liacuteneas significan que pueden haber otras sentencias antes o despueacutes de la

sentencia if Nos da igual en esta explicacioacuten ya que no hay restricciones en cuanto a lo que

hay antes o despueacutes de la sentencia if

La forma maacutes general de la sentencia if es

if (xxx)

yyy

donde xxx es una condicioacuten y yyy es cualquier nuacutemero de sentencias a ejecutar si la

condicioacuten if es verdadera

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 12: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 12 -

Condiciones que puede detectar Karel

Date cuenta de que la condicioacuten facingSouth en el fragmento de programa de la paacutegina del

if

if (facingSouth)

turnleft()

turnleft()

turnleft()

La condicioacuten es una funcioacuten de la situacioacuten actual de Karel a medida que se ejecuta el

programa Si Karel estaacute actualmente orientado hacia el Sur el valor de la funcioacuten

facingSouth seraacute verdadero y el conjunto de sentencias entre las llaves se ejecutaraacute

De otra manera el valor facingSouth seraacute falso y el bloque de sentencias se saltaraacute Karel

comprende cualquier funcioacuten booleana que comprueba su situacioacuten actual Aquiacute hay un

listado

frontIsClear nextToABeeper facingEast

frontIsBlocked notNextToABeeper facingWest

leftIsClear anyBeepersInBeeperBag notFacingNorth

leftIsBlocked noBeepersInBeeperBag notFacingSouth

rightIsClear facingNorth notFacingEast

rightIsBlocked facingSouth notFacingWest

clear significa que no hay ninguacuten muro mientras que blocked significa que hay un

muro en esa direccioacuten Karel puede detectar si hay o no alguacuten zumbador en la esquina en la

que se encuentra actualmente asiacute como detectar si tiene alguacuten zumbador en la mochila o

no Tambieacuten tiene una bruacutejula para detectar hacia queacute direccioacuten estaacute orientado

Por si fuera poco podemos unir dos o maacutes funciones booleanas con los operadores loacutegicos

Y O y NO

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 13: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 13 -

Podemos ver la siacutentaxis de los operadores y sus valores con las siguientes tablas

Operador y (ampamp )

Siacutentaxis funcioacutenBooleana1 ampamp funcioacutenBooleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero falso

verdadero falso falso

verdadero verdadero verdadero

Operador o (||)

Siacutentaxis funcioacuten-booleana1 || funcioacuten-booleana2

Valor de la funcioacuten 1 Valor de la funcioacuten 2 Resultado final

falso falso falso

falso verdadero verdadero

verdadero falso verdadero

verdadero verdadero verdadero

Operador no ()

Siacutentaxis funcioacuten-booleana

Valor de la funcioacuten Resultado final

falso verdadero

verdadero falso

Los operadores ampamp y || se aplican sobre dos funciones y el operador solo sobre una

Lo mejor de los operadores loacutegicos es que si ponemos dentro de un par de pareacutentesis las

funciones con el operador loacutegico entonces toda la operacioacuten se vuelve una funcioacuten

booleana por lo que podemos aplicar maacutes operadores loacutegicos sobre ella iquestNo quedoacute claro

Revisa estos ejemplos

(facingNorth || facingSouth) ampamp frontIsClear

( (frontIsBlocked ampamp nextToABeeper)) || facingEast

(nextToABeeper ampamp frontIsClear)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 14: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 14 -

Ten mucho cuidado de colocar bien los pareacutentesis ya que si no lo haces no te marcaraacute

error pero seguramente haraacute algo extrantildeo que tu no quieres que haga

Por ejemplo si queremos que Karel avance si estaacute viendo al norte y el frente esteacute libre

podemos hacer lo siguiente

if (facingNorth ampamp frontIsClear)

move()

Ejercicio 3 Escribe un programa de Karel que haga que Karel esteacute orientado al Norte

desde cualquier direccioacuten inicial y a continuacioacuten se apague Deberiacutea terminar en la misma

interseccioacuten en la que empezoacute

iquestAlguna sugerencia

En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel estaacute orientado

hacia el Sur Pero iquestqueacute ocurre cuando no estaacute orientado hacia el Sur iexclPodriacutea estar

tambieacuten orientado hacia el Norte o el Este Entonces necesitas dos sentencias if

adicionales en las cuales se especifique que es lo que debe hacer Karel en esas situaciones

Modifica el mundo inicial de Karel para probar cualquiera de las 4 direcciones de inicio y

para cada una de ellas vuelve a ejecutar el programa

En esta seccioacuten hemos visto como usar las sentencias de control para adaptar Karel a cada

situacioacuten

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 15: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 15 -

La sentencia iterate

En el ejercicio 2 teniacuteas que contar la secuencia correcta de pasos para que Karel pudiese

resolver el problema En este caso probablemente no hay una forma maacutes corta de

resolverlo Sin embargo en algunos problemas hay aspectos del problema que tienen una

naturaleza repetitiva Por ejemplo para ir de la esquina 15 a la 1 tendriacuteamos que poner un

total de 14 ldquomove()rdquo iquestEs difiacutecil dar justo con el nuacutemero correcto El lenguaje de

programacioacuten de Karel ofrece un meacutetodo mejor la sentencia de control iterate Se escribe

como sigue

iterate (xxx)

yyy

donde xxx debe ser un nuacutemero entero positivo y yyy representa cualquier nuacutemero de

sentencias de Karel El problema de los 14 avances podriacutea haberse escrito

iterate (14)

move()

Ejercicio 4 Asume que Karel estaacute en la esquina de la 8ordf Avenida y la 8ordf Calle con el

escenario que se ve en la siguiente imagen Escribe un programa que haga a Karel recoger

todos los zumbadores y acabe en la 1ordf esquina orientado al Sur

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 16: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 16 -

iquestCrees que es muy difiacutecil

Bienhellip puede ser que un poco de ayuda venga bien Si puedes imaginar como hacerlo una

vez (el primer zumbador de la esquina 77) la sentencia repite lo haraacute tantas veces como tuacute

quieras

Crea un mundo como el de arriba y guaacuterdalo con el nombre ldquodiagonalmdordquo Escribe el

programa y guaacuterdalo con el nombre diagonaltxtrdquo Asegurate de utilizar la sentencia

iterate Prueba el programa en este mundo inicial Karel deberiacutea terminar en la esquina de la

primera Avenida con la primera Calle y llevando 7 zumbadores en la mochila

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 17: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 17 -

La sentencia ifelse

Aquiacute puedes ver como se escribe una sentencia ifelse

if (xxx)

yyy

else

zzz

donde xxx es una condicioacuten yyy son sentencias a realizar si xxx es verdadero y zzz son las

sentencias a ejecutar si xxx es falso

Ejercicio 5 Karel tiene la tarea de alinear una coleccioacuten de zumbadores en la primera

Calle que ha sido distribuida desigualmente Empieza en la 1ordf Calle y la 15ordf Avenida y estaacute

orientado al Oeste Se supone que en cada esquina hay exactamente un zumbador Sin

embargo Karel puede encontrar 0 1 o 2 zumbadores en cualquier interseccioacuten Su tarea es

asegurar que exactamente hay un zumbador antes de continuar hacia la siguiente esquina

Cuando llega a la esquina 11 debe apagarse

Disentildea el mundo inicial para que Karel comience en la esquina 115 orientado hacia el

Oeste Karel debe empezar con 15 zumbadores en la mochila Aleatoriamente situacutea 1 o 2

zumbadores en esquinas a lo largo de la 1ordf Calle y deja alguna sin zumbadores Guarda tu

mundo inicial con el nombre ldquolineaDeZumbadoresmdordquo

Escribe el programa para hacer que Karel complete la tarea descrita anteriormente Guarda

tu programa con el nombre ldquolineaDeZumbadorestxtrdquo Truco utiliza iterate un ifelse y un

if

Recuerda iexclno sabemos queacute esquinas tienen el nuacutemero equivocado de zumbadores Karel

debe hacer la tarea correctamente independientemente del nordm de zumbadores que haya en

cada esquina

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 18: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 18 -

La sentencia while

Desde el principio siempre se nos ha dicho la esquina exacta de inicio Nosotros queremos

programar Karel para que se adapte mejor a su mundo La sentencia while nos permite

repetir pasos mientras se cumple una condicioacuten y esto nos va a permitir programar a Karel

para que iexclno sea un chico tan riacutegido La sentencia while tiene la forma siguiente

while ( xxx)

yyy

donde xxx debe ser una condicioacuten (una de las funciones booleanas listadas anteriormente)

y yyy representa cualquier nuacutemero de sentencias de Karel El ejercicio 1 podriacutea haberse

escrito de la siguiente manera

while (frontIsClear)

move()

Esto soluciona el problema de caminar de nuevo a la 1ordf Calle sin importar como de lejos

se encuentre de esta Calle

Ejercicio 6 La tarea de Karel es dejar zumbadores a lo largo de una pista de carreras Un

ejemplo de dicha pista es la de la siguiente imagen Karel debe dar una vuelta completa y

depositar un zumbador en cada esquina a lo largo del camino Guarda el programa con el

nombre ldquopistaCarrerastxtrdquo Tu solucioacuten debe usar sentencias while Construye el mundo

inicial de la siguiente imagen con el nombre ldquopistaCarrerasmdordquo Asegurate de poner

dentro de la mochila suficientes zumbadores para todas las esquinas El ejemplo requiere 22

zumbadores Karel debe empezar en cualquier interseccioacuten de la pista

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 19: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 19 -

Aseguacuterate de que tu programa funciona en el mundo anterior y despueacutes prueba tu

programa modificando el mundo inicial Tambieacuten intenta iniciar a Karel desde diferentes

intersecciones a lo largo del camino iquestRealiza Karel su tarea correctamente en todos los

casos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 20: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 20 -

La sentencia void

Hasta ahora le hemos dicho a Karel exactamente lo que teniacutea que hacer tal como

necesitaacutebamos que lo hiciese Esto funciona bien pero te pudiste haber dado cuenta de que

siempre se utilizan secuencias de sentencias similares Un ejemplo es cuando Karel tiene

que girar a la derecha y nosotros le decimos turnleft() turnleft() turnleft() iquestNo seriacutea

maacutes faacutecil si le pudieacuteramos decir simplemente turnright()

En otras palabras diciendo turnright() Karel girariacutea tres veces hacia la izquierda para

alcanzar nuestro objetivo Es posible iquestEstaacutes suficientemente motivado para aprender una

nueva sentencia

Una de las razones de crear nuevas instrucciones es por evitar escribir tanto Otra es para

documentar mejor cual es nuestro objetivo cuando nosotros mismos u otra persona lee el

programa Como te estaraacutes dando cuenta programar es una tarea extremadamente

compleja y iexclnecesitamos toda la ayuda necesaria para hacer las cosas correctamente

Las sentencia void (que tambieacuten se puede escribir como define) estaacute situada en un sitio

especial dentro de un programa de Karel justo despueacutes de la sentencia class program

El siguiente es un programa vaacutelido para Karel

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 21: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 21 -

Puedes definir cualquier nuacutemero de instrucciones nuevas y despueacutes usarlas en el programa

donde las necesites Las instrucciones nuevas pueden contener sentencias de control si es

necesario Date cuenta de que la nueva instruccioacuten puede tambieacuten usar una instruccioacuten

definida previamente El ejercicio 5 podriacutea haberse escrito

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 22: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 22 -

Date cuenta de como la instruccioacuten iterate acaba moviendo a Karel una esquina hacia

adelante sin tener en cuenta en nordm de zumbadores Si haces esto 14 veces iexclestaraacutes en casa

Ejercicio 7 Re-escribe el programa para el ejercicio 4 pero esta vez puede no haber un

zumbador en cada esquina Guarda tu programa con el nombre ldquodiagonal2txtrdquo La nueva

instruccioacuten deberiacutea coger un zumbador en la posicioacuten actual si es que lo hay Deberiacuteas usar

esta instruccioacuten para coger todos los zumbadores mientras Karel va a su casa en diagonal

Asegurate de que tienes el mundo ldquodiagonalmdordquo cargado para probar tu programa Karel

deberiacutea finalizar en la esquina de la 1ordf Calle con la 1ordf Avenida con todos los zumbadores

que ha ido cogiendo por el camino y apagarse

Ejercicio 8 Escribe un programa que ayude a Karel a escapar de un laberinto que no

contiene islas (cuadrados aislados) La salida del laberinto estaacute marcada ubicando un

zumbador en la primera esquina que estaacute fuera del laberinto al lado del muro de la derecha

Una forma de resolver este problema es hacer que Karel avance a lo largo del laberinto

siguiendo el muro de su derecha ( imagina que estaacute tocando el muro y que nunca puede

despegar su mano de eacutel) En la siguiente imagen hay un ejemplo de un laberinto del cual

deberiacutea ser capaz de salir (no olvides que tu programa deberiacutea funcionar en todos los

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 23: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 23 -

laberintos no solo en el de la imagen) Guarda tu programa con el nombre ldquolaberintotxtrdquo

Esto parece muy muy complicado iquestPuedes darnos un mundo de ejemplo

Aquiacute tienes un mundo inicial de ejemplo La liacutenea roja muestra el camino que deberiacutea

seguir Karel para este mundo Recuerda que no sabes de antemano donde estaraacuten los

muros

Podriacutea hacerse maacutes faacutecil si definieras unas pocas nuevas instrucciones que hicieran parte

del trabajo Aquiacute teneacuteis un ejemplo

void sigueMuroDereha()

pon tu coacutedigo aquiacute

Esta instruccioacuten hace que Karel avance correctamente hacia el siguiente segmento de muro

Los diagramas de abajo muestran las 4 situaciones Karel podriacutea estar en cualquier punto

del laberinto Si sigueMuroDerecha() resuelve correctamente los 4 casos entonces has

solucionado la parte principal del problema Tambieacuten deberiacuteas definir turnright()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 24: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 24 -

Para probar tu programa crea un mundo como el del ejemplo y guaacuterdalo con el nombre

ldquolaberintomdordquo Una vez te funcione el programa para este mundo prueba a modificarlo

antildeadieacutendo o quitando muros iquestRealiza Karel la tarea bien en todos los casos

Situaciones iniciales Movimientos respectivos

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 25: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 25 -

Paraacutemetros en funciones

Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de coacutedigo un

determinado nuacutemero de veces pero siempre teniacuteamos que colocar un nuacutemero fijo en la

sentencia iquestte has puesto a pensar que pasariacutea si por ejemplo necesitara una instruccioacuten que

volteara a Karel 180deg Pues la respuesta natural seriacutea haz una instruccioacuten que haga que

Karel gire dos veces Pero iquestcrees que seriacutea posible usar la instruccioacuten que hicimos

anteriormente turnright() Si existiese alguna forma de que en vez de poner 3 en la

sentencia iterate pusiesemos un nuacutemero variable podriacuteamos usar la instruccioacuten tanto para

girar a la derecha como para dar media vuelta

iexclPues si existe Primero retomemos el coacutedigo para girar a la derecha

void turnright()

iterate(3)

turnleft()

Ahora todas las nuevas instrucciones declaradas pueden ademaacutes llevar un paraacutemetro iquestpero

que es un paraacutemetro pues es un numerito que le podemos mandar a la instruccioacuten cuando

la llamamos y como cuando declaramos la instruccioacuten no sabemos con que nuacutemero la

vamos a llamar reemplazamos el nuacutemero por una palabra iquestAlguna vez has oiacutedo la frase

los primeros n nuacutemeros pues precisamente eso son los paraacutemetros Podemos en vez de n

poner 1 2 oacute 3 quedando los primeros 3 nuacutemeros por ejemplo Este paraacutemetro puede

tener el nombre que sea siempre y cuando la primer letra no sea un nuacutemero y el nombre del

paraacutemetro no sea el mismo que una palabra del lenguaje por ejemplo no se puede llamar if

iterate move etc

Este paraacutemetro se puede usar en cualquier lugar dentro de la definicioacuten de la instruccioacuten en

cualquier sentencia o instruccioacuten que necesite un nuacutemero (justo como la sentencia iterate)

Redefinamos ahora la instruccioacuten turnright como la instruccion turn

void turn(n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 26: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 26 -

iterate(n)

turnleft()

De esta forma si escribimos en nuestro coacutedigo turn(3) Karel giraraacute a la derecha si

escribimos turn(2) daraacute media vuelta si escribimos turn(1) giraraacute a la izquierda y si

escribimos turn(0) no haraacute nada

Aqui puedes ver como se escribe una instruccioacuten con un paraacutemetro en general

void xxx (yyy)

zzz

donde xxx es el nombre de la instruccioacuten yyy es el nombre del paraacutemetro y zzz es

cualquier nuacutemero de instrucciones

Ejercicio 9 Escribe una nueva instruccioacuten que avance a Karel el nuacutemero de veces que se le

mande como paraacutemetro Debes de evitar que Karel choque con alguna pared

iquestTienes dudas Usa como base el coacutedigo de la instruccioacuten gira

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 27: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 27 -

Las funciones succ y pred

Ahora ya sabemos como mandarle un nuacutemero a un procedimiento y probablemente ya

habraacutes intentado poner operaciones como suma resta o multiplicacioacuten sin embargo

lamanto decirte que ninguna de estas operaciones estaacuten soportadas en Karel

Por otro lado existen dos funciones que nos permiten sumarle 1 a un nuacutemero y restarle 1

Pero iquestqueacute es una funcioacuten Una funcioacuten es una instruccioacuten que devuelve un valor es

decir reciben un paraacutemetro (o maacutes) que luego procesa para al final regresar un valor por

ejemplo la funcioacuten booleana junto-a-zumbador devuelve verdadero si Karel estaacute parado

junto a un zumbador y falso si no lo estaacute En Karel no se pueden declarar funciones nuevas

pero se pueden usar las que ya existen

Las funciones succ y pred son dos instrucciones que reciben un paraacutemetro posteriormente

devuelven un nuacutemero maacutes y un nuacutemero menos (respectivamente) que el que le enviamos

La funcioacuten succ se escribe asiacute

succ(xxx)

donde xxx es un nuacutemero o un paraacutemetro y la funcioacuten pred se escribe asiacute

pred(xxx)

donde xxx es un nuacutemero o un paraacutemetro

Debido a que devuelven un nuacutemero solo nos pueden servir poniendolas en alguna

instruccioacuten o sentencia que reciba un nuacutemero como iterate otro succ o pred o una

instruccioacuten personal que reciba un paraacutemetro

Por ejemplo el siguiente trozo de coacutedigo pone n + 1 zumbadores en donde Karel se

encuentra

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 28: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 28 -

iterate( succ(n) )

putbeeper()

nota que n se incrementa (se le suma uno) Si en vez de succ pusieramos pred Karel

dejariacutea n - 1 zumbadores porque la n se decrementa (se le quita uno) cuando se pone

dentro de una funcioacuten pred

Ejercicio 10 Escribe una nueva instruccioacuten que reciba un nuacutemero n y mueva a Karel n + 2

veces (validando el choque contra paredes) y posteriormente coloque n - 2 zumbadores en

la posicioacuten en donde estaacute PISTA Usa un iterate para mover a Karel y otro para colocar los

zumbadores NO se vale colocar instrucciones fuera de los ciclos iterate

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 29: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 29 -

La funcioacuten iszero

La uacuteltima funcioacuten en Karel es la funcioacuten iszero que nos ayuda a saber si un nuacutemero es

cero Devuelve verdadero si el nuacutemero es cero y falso si no lo es

Es evidente de que si ponemos iszero(0) no es muy uacutetil ya que sabemos perfectamente

que cero es cero ( S ) Sin embargo es muy uacutetil cuando se estaacute manejando paraacutemetros Por

ejemplo queremos hacer una instruccioacuten que avance n lugares pero si el paraacutemetro es

cero gire a la izquierda

Por razones didaacutecticas en esta ocasioacuten te daremos la solucioacuten

void avanzaSiNoEsCero (n)

if ( iszero(n) )

turnleft()

else

iterate (n)

move()

Ahora si te toca a ti

Ejercicio 11 Define una nueva instruccioacuten que haga que Karel ponga n zumbadores en

donde se encuentra pero si n es cero recoja 1 zumbador

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 30: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 30 -

Recursividad

Hemos llegado al uacuteltimo tema y no por eso el menos importante de hecho es el tema maacutes

complicado que veremos aqui y es muy uacutetil no solo para Karel sino para resolver

cualquier problema Debido a la complejidad del tema se han creado 5 subtemas

1 Fundamentos

2 Definicioacuten

3 Recursividad simple

4 Recursividad con paraacutemetros

5 Recursividad mixta

Fundamentos

Empecemos iquestTe has preguntado alguna vez queacute sucede cuaacutendo llamas a una instruccioacuten

que tu creaste Como te habraacutes dado cuenta se ejecuta la instruccioacuten que le pediste y luego

continua en el lugar en donde se quedoacute Pero en realidad iquestcoacutemo hace eso la computadora

Pues bien la computadora tiene una cosa que se llama pila de llamadas cuando un

programa se ejecuta y encuentra una instruccioacuten se guarda en la pila en que lugar se quedoacute

entonces ejecuta la instrccioacuten que le pediste y al terminar la instruccioacuten revisa en la pila en

donde estaba anteriormente para continuar en ese lugar iquestMuy enredado Mira este dibujo

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 31: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 31 -

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 32: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 32 -

Espero haya quedado claro ya que esto es el punto crucial de la recursividad Ahora que

sabemos como funciona el llamado a procedimientos o instrucciones Definamos lo que es

recursividad

Definicioacuten

Una instruccioacuten recursiva es aquella que en alguacuten momento se llama asiacute misma Por

ejemplo puedes revisar en libros y en muchos otros lados la definicioacuten recursiva del

factorial

factorial(1) = 1

factorial(n) = n factorial(n - 1)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 33: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 33 -

Como puedes ver para saber el factorial de un nuacutemero necesitas saber el factorial del

nuacutemero anterior Alliacute estaacute la recursividad

Toda instruccioacuten recursiva consta de dos partes

1- Base

Es un valor fijo al que eventualmente la recursioacuten debe de llegar normalmente es

un valor pequentildeo y no demostrable Por ejemplo factorial de 1 es 1 y no se puede

demostrar ademaacutes si quieres calcular el factorial de cualquier nuacutemero

eventualmente debes de saber el factorial de 1

2- Recursioacuten

Consiste en la parte en donde la instruccioacuten se llama asiacute misma ademaacutes de efectuar

algunas operaciones con el resultado Por ejemplo para el factorial de 3 se calcula

el factorial de 2 y eso se multiplica por 3

Ahora que sabes que es recursividad intenta hacer la definicioacuten recursiva de la serie de

Fibonacci la cual dice que sus primeros dos elementos (1 y 2) son 1 y para cualquier otro

nuacutemero de Fibonacci se debe sumar el Fibonacci de los dos nuacutemeros anteriores Por

ejemplo Fibonacci(3) = 2 Fibonacci(5) = 5

Pasemos de lleno a la recursividad en Karel

Recursividad simple

Intentemos ahora llamar a una instruccioacuten desde siacute misma recordemos que debe de tener

una base y una definicioacuten recursiva iquestte parece bien que la base sea si el frente esta

bloqueado termina iquesty te parece bien que si no avance una casilla y entonces se llame asi

misma iexclHagaacutemoslo

void recursiva ()

if (frontIsClear)

move()

recursiva()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 34: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 34 -

Nota que en Karel es imposible decirle que termine la instruccion asiacute que mejor invertimos

la condicioacuten y avanzamos si el frente estaacute libre iexcles otra forma de poner la base por que

en otras palabras la base es lo que hace que la recursioacuten termine y no sea infinita Nota

tambieacuten que en este caso las operaciones que hacemos son solamente move() Algo

diferente al factorial iquestno

iquestQueacute crees que haga esteacute coacutedigo Ponlo en el Simulador Karel y adivina

iexclAsiacute es Karel avanzaraacute mientras el frente este libre Entonces te preguntaraacutes iquestno seriacutea

mejor un ciclo mientras Y la respuesta es si solamente quieres hacer eso siacute sin embargo

iquestque tal si quieres contar con zumbadores cuantos pasos avanzaste iexclA verdad Si

queremos hacer eso debemos agregarle una liacutenea a nuestro coacutedigo

void recursiva ()

if (frontIsClear)

move()

recursiva()

putbeeper()

Ahora prueacutebalo

iexclWow iexclSorprendente iquestPor queacute funciona

Si recuerdas la seccioacuten de fundamentos cada vez que se llama una instruccioacuten la siguiente

instruccioacuten se guarda en la pila de llamadas como se va a llamar exactamente el nuacutemero de

veces que avanzaste cuando la recursividad termine al llegar a la base va a sacar una por

una las instrucciones que siguen y las que siguen siempre seraacuten putbeeper() En este

ejemplo solo hay una instruccioacuten antes y despueacutes de las llamadas recursivas pero puede

haber muchiacutesimas maacutes

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 35: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 35 -

Si auacuten no lo entiendes trata de simular la pila de llamadas de la misma forma que estaacute en la

imagen

Ejercicio 12 iquestRecuerdas el problema del perioacutedico del Ejercicio 2 Ahora imagina que el

perioacutedico estaacute en la posicioacuten 11 y que la casa de Karel puede estar ubicada en cualquier

posicioacuten del mundo eso siacute con la misma orientacioacuten y forma Haz un programa que haga

que Karel lleve el perioacutedico a su sala iexclUsa recursividad Recuerda piensa en que momento

la recursividad termina (BASE) y si hay que hacer algo en ese momento luego piensa en la

llamada recursiva y las operaciones que van a ir antes y las que van a ir despueacutes (las que

se van a guardar en la pila)

Recursividad con paraacutemetros

iquestRecuerdas los paraacutemetros iquestRecuerdas las funciones pred() y succ() iquestQue pasariacutea si a

una instruccioacuten con paraacutemtro la llamaramos usando pred() o succ()

Todo esto en Karel es posible definamos una instruccioacuten con paraacutemetros y volvaacutemosla

recursiva usando succ()

void recursiva2 (n)

if (frontIsClear)

move()

recursiva2 ( succ (n) )

else

iterate(n)

putbeeper()

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 36: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 36 -

Este coacutedigo hace exactamente lo mismo que el de la seccioacuten anterior con la diferencia de

que la complejidad que existiacutea en la pila de llamadas es eliminada y colocada como una

instruccioacuten base En cada paso de la recursioacuten se aumenta uno y cuando llegas a la base

tiene un nuacutemero que tal vez pudas usar para tu beneficio No te olvides que tambieacuten puedes

usar la funcioacuten pred() y iszero() y que en la llamada recursiva puedes llamarla con el

paraacutemetro sin modficar

Como punto importante hay que destacar que en la pila de llamdas ademaacutes de la

instruccioacuten que sigue tambieacuten se guarda el valor actual del paraacutemetro

Ejercicio 13 Realiza el Ejercicio 12 pero con Recursividad con paraacutemetros

Ejercicio 14 Realiza una instruccioacuten que avance a Karel tantas veces como zumbadores

tenga en su mochila utilizando Recursividad con paraacutemetros NO se vale usar un ciclo

mientras

Recursividad mixta

Si ya dominas los dos tipos de recursividad anteriores esto seraacute muy faacutecil para ti ya que la

recursividad mixta no es maacutes que usar los dos tipos de recursividad al mismo tiempo

Veamos el siguiente problema

Teniendo un mundo como el de arriba y con zumbadores infinitos en la mochila coloca en

11 el resultado de la multiplicacioacuten

Este es uno de los problemas maacutes claacutesicos de recursividad mixta sin ella la complejidad del

problema seriacutea muy elevada

Para este problema usaremos dos instrucciones uno con recursividad simple y el otro con

paraacutemetro

La mecaacutenica de solucioacuten es la siguiente Se van a tomar todos los zumbadores de una

posicioacuten con recursividad con paraacutemetros para que al llegar a la base el paraacutemetro tenga el

nuacutemero de zumbadores que hay en dicha posicioacuten posteriormente ese nuacutemero se pasa

como paraacutemetro a la instruccioacuten recursiva simple (si aunque la recursividad es simple

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 37: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 37 -

tambieacuten tiene paraacutemetro) y en cada paso se le va a llamar recursivamente con el mismo

paraacutemetro de esa forma en la pila de llamadas el paraacutemetro va a estar tantas veces como

zumbadores haya en la segunda posicioacuten y vuala Tal vez quede maacutes claro si ves las

instrucciones y las sigues paso a paso en Karel

void multiplica (n)

if (nextToABeeper)

pickbeeper()

multiplica(n)

iterate (n)

putbeeper()

else

veAlInicio()

void cuenta (n)

if (nextToABeeper)

pickbeeper()

cuenta( sucede (n) )

else

move()

multiplica (n)

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE

Page 38: Tutorial Karel avanzado Java

Agosto 2007 Facultad de Ciencias Fiacutesico-Matemaacuteticas sede de la UANL

Olimpiada Estatal de Informaacutetica de Nuevo Leoacuten

- 38 -

Esta casi completa pero le falta implementar la instruccioacuten veAlInicio (que debe ser de lo

maacutes trivial) y el posicionamiento inicial tal vez en un principio no entiendas bien revisa el

coacutedigo paso a paso hasta que lo comprendas iexclSuerte

Ejercicio 15 Teniendo un mundo como el de abajo

en donde puede haber cualquier cantidad de calles y cualquier ancho en las avenidas

(siempre cerrado el circuito y sin islas o bifurcaciones)deje en la esquina izquierda maacutes

inferior (21 en el ejemplo) tantos zumbadores como nuacutemero de calles de ancho 1 que hay

Karel lleva infinitos zumbadores en su mochila En resultado del ejemplo es 3

En este problema se usan casi todos los temas vistos en el curso emplealos y resueacutelvelo

Hemos llegado al fin del curso ahora debes ser capaz de participar en la Olimpiada

Mexicana de Informatica no olvides seguir resolviendo problemas para mejorar siempre

tus habilidades puedes encontrar ligas a las paacuteginas en donde hay problemas en la paacutegina

principal de la OMI

iexclSUERTE