Post on 02-Jul-2015
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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