Está en la página 1de 39

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL KAREL OMI Versin

2.0 por Cesar Cepeda Para comentarios escriba a cesar@auronix.co m Revisado por Eduardo Urias Barrientos AKA Wero Shinoda TUTORIAL DE KAREL 1. 2. 3. 4. Introduccin: Por qu programamos el robot Karel. El mundo de Karel: Como visualizam os y configuramos el lugar que ocupa Karel. Programando Karel: Como le decimos a Karel qu cosas debe hacer. Comandos bsicos de Karel: Las cosas que Karel es capaz de hacer incluso sin pensar. 5. Sentencias de Control de Karel: Las sentencias de control se usan para seleccionar que rdenes se deben ejecutar. 6. La sentencia si/entonces: A veces, Karel siente la necesidad de realizar algo slo en ciertas condiciones. 7. Condiciones que puede detectar Karel: Una condicin es una funcin d e la situacin actual de Karel, tal como l ejecuta las rdenes. 8. La sentencia repet ir/veces: Es til cuando se sabe exactamente cuantas veces se debe de realizar una cosa. 9. La sentencia si/entonces/sino: Karel puede darse cuenta que necesita r ealizar una cosa u otra. 10. La sentencia mientras/hacer: Extremadamente valiosa cuando no se sabe de antemano exactamente cuantas veces se necesita realizar un a tarea. 11. La sentencia define-nueva-instruccion/como: Usando la taquigrafa de Karel para tareas que se realizan a menudo. 12. Parametros en instrucciones: Usa ndo variables. 13. Las funciones sucede y precede: Incrementando y decrementando variables. 14. La funcin si-es-cero: Es mi variable cero? 15. Recursividad: Necesi tas contar? Usa recursividad! -1-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Por qu programamos Karel Programar un ordenador en un lenguaje como JAVA, requiere un secuenciamiento pre ciso de los pasos, uno detrs de otro, escogiendo qu pasos hay que seguir en cada c aso, y controlando la repeticin de ciertos pasos, en el proceso de resolucin de un problema. Aunque esta precisin se requiere para las operaciones sin razonamiento de las computadoras, es extraa a los humanos. Los humanos somos mucho menos rgido s en nuestro comportamiento y podemos retroceder elegantemente si nuestros pasos no parecen llevar a la consecucin de un objetivo. Debido a que son diferentes la s habilidades de las computadoras y lo humanos, expresar la solucin de un problem a en instrucciones que una computadora puede seguir est comprobado que es difcil p ara mucha gente. Para conocer estos conceptos, nosotros empezaremos programando el Robot Karel. Karel es una herramienta de aprendizaje que presenta los concept os 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 Kar el the Robot: A Gentle Introduction to the Art of Programming with Pascal, John Wiley & Sons, Inc., 1981. Aunque el lenguaje por default es Pascal, tambin se pue de programar en JAVA. Nosotros programaremos Karel, un Robot simple que vive en un mundo simple. Debido a que Karel y su mundo son simulados, nosotros podemos re almente ver los resultados de un programa en accin ! El lenguaje con el que progr amaremos Karel es una versin especial de JAVA, por lo tanto, la mayor parte de lo que aprendamos, podr ser aplicado directamente al lenguaje de programacin estndar JAVA. -2-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL El mundo de Karel Karel puede orientarse en una de las cuatro direcciones: Este, Oeste, Norte y Su r. Slo gira 90 cada vez, por tanto no puede orientarse hacia en NordEste, por ejem plo. En el mundo de Karel, las calles van de Este a Oeste, y son numeradas comen zando por 1. No hay nmeros de calle igual a 0 o negativos. Las avenidas van de No rte a Sur, y tambin estn numeradas empezando por 1. Tampoco hay nmeros de avenida i gual a 0 o negativos. Se le llama esquina a la interseccin de una calle con una a venida. Karel va de una esquina a la siguiente en un solo movimiento. Ejecuta el programa Karel.exe de la carpeta KarelOMI . Se iniciar el simulador del Robot. A hora deberas ver la ventana de abajo . Esta ventana muestra las calles y avenidas que usa Karel para desplazarse. Prime ro 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 botn izquierdo del ratn en la interseccin de las calles correspondientes. Los muros qu e limitan las calles y avenidas no se pueden quitar, stos son los que previenen q ue Karel se salga del mundo. Prueba a introducir algunos muros para ver que aspe cto tienen. -3-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Otro elemento de inters en el mundo de Karel son los zumbadores. Un zumbador es u na forma de marca que Karel puede escuchar slo cuando se encuentra en la misma es quina que el zumbador. Karel tiene una mochila que puede utilizar para poner los zumbadores que vaya cogiendo. Tambin puede hacer lo contrario, es decir, sacar l os zumbadores de su mochila y depositarlos en las esquinas por las que va pasand o. Puedes ajustar el nmero inicial de zumbadores en cada esquina dando click con el botn derecho del ratn en la calle deseada y seleccionando el nmero de zumbadores deseados (para colocar entre 10 y 99 zumbadores, selecciona la opcin N zumbadore s y escribe el nmero deseado). Prueba a poner algunos zumbadores para ver como se visualizan en el mundo. Crea el mundo inicial que se muestra a continuacin. Dado que hemos realizado todo el trabajo necesario para crear un mundo para Karel, va mos a guardarlo ! Pulsa sobre el botn Guardar, ve a tu directorio particular y gu arda el mundo como NuevoMundo.mdo Finalmente, Karel tiene su sitio en el mundo! Mueve el cursor del ratn hacia la es quina de la Avenida 15 y Calle 1 y da click con el botn derecho del mouse, situa el puntero del ratn en la opcin "Situar a Karel" y elige "Orientado al Oeste". Aho ra deberas visualizar el mundo de abajo. Haz de nuevo click sobre el botn "Guardar " , para almacenar los cambios. -4-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Programando Karel Antes de poder empezar, necesitamos dar a Karel un programa (serie de instruccio nes) a seguir. Despus de todo, es slo un Robot!. Pulsa sobre la pestaa "Programa" Ah ora deberas ver una ventana con el aspecto de esta de abajo. La zona que est vaca e s donde escribiremos y veremos el programa de Karel. El lenguaje por default es Pascal, para programar en JAVA, selecciona la opcin qu e viene a la izquierda de los botones. Ahora pulsa en el botn "Nuevo ". Un esquel eto del programa ser creado automticamente. Se crear un programa inicial. Este prog rama inicial contiene los comandos bsicos que son necesarios en cada programa. Ah ora deberas ver una ventana como la siguiente. -5-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Date cuenta de que el programa anterior slo le dice a Karel que se apague. Antes de apagarlo, vamos a mandarle algunas tareas. La orden "move" le dice a Karel qu e se mueva hacia adelante una esquina. Escribe "move();" antes de"turnoff();" . Date cuenta de que el punto y coma se usa para separar rdenes (tal como en JAVA). Ahora pulsa el botn "Compilar". Si no has cometido ningn error, tu programa tendrs el aspecto del de la ventana siguiente: -6-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL

Pulsa la pestaa de Ejecutar, y despus haz click en el botn Inicializar . (Ejecutar inicia la ejecucin (correr) de nuestro programa. Al Inicializar, se muestra el mu ndo que habamos creado previamente (NuevoMundo.mdo)). Ahora deberas ver la ventana de abajo (asumiendo que el fichero NuevoMundo.mdo que creaste est todava abierto. S i no, pulsa en la pestaa Mundo, y pulsando en el botn Abrir, selecciona el fichero N oMundo.mdo que guardaste en el punto anterior). -7-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Cuando des click en adelante podrs darte cuenta que la instruccin "move();" se col orea de rojo. En este punto haz click en Adelante para que Karel realice esa prime ra orden del programa. Wow, Karel se ha movido solo ! Date cuenta que la instrucc in en rojo ahora es "turnoff();". Haz click sobre Adelantede nuevo. Ahora el progra ma terminar correctamente. Si quieres probarlo otra vez, antes tendrs que pulsar s obre el botn "Inicializar". Ejercicio 1 : Escribe un programa de Karel para que s e mueva a la esquina de la 1 Calle con la 1 Avenida y se desconecte, asumiendo que empieza en la esquina de la Calle 15 y la Avenida 15 con orientacin hacia el Oes te. Guarda el programa con el nombre primerPrograma.txt. Como mundo utiliza el gua rdado anteriormente con el nombre NuevoMundo.mdo. Intntalo !! -8-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Comandos bsicos de Karel Hay cinco comandos bsicos para Karel, estos son: 1. 2. 3. 4. 5. move() turnleft() pickbeeper() putbeeper() turnoff() (avanza una esquina) (gira a la izquierda) (coge un zumbador) (deja un zumpador) (desconctate ) La salud de Karel Andar entre muros no es bueno para un robot, por lo tanto Kare l tiene algunos mecanismos salvavidas dentro de l. Si un programa le dice a Karel que se mueva aunque haya un muro delante de l, l dir que hay un error y no realiza r la accin. Lo mismo ocurrir si le decimos que coja un zumbador en una esquina y no existe ninguno. Las nicas rdenes que siempre lleva a cabo sin importar la situacin en la que se encuentre son turnleft() y turnoff(). Cuando Karel nos dice que ha y un error, no tenemos que echarle la culpa, sino que probablemente habremos esc rito mal alguna instruccin. Ejercicio 2 : Cada maana Karel se levanta de la cama y tiene que recoger el peridico, representado por un zumbador, que est en el porche de la casa. Escribe un programa que ordene a Karel que recoja el peridico y lo l leve de vuelta a la cama. La situacin inicial es la de la imagen de abajo, y la s ituacin final debe tener a Karel de vuelta en la cama (misma esquina, misma direc cin que cuando empez) con el peridico (zumbador en su mochila). Crea un mundo como el de la imagen y gurdalo como periodico.mdo. -9-

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Sentencias de Control de KAREL Las sentencias de control se usan para elegir qu hacer, y/o cuantas veces hacerlo . Sin embargo, por si solos no causan que ocurra algo. Simplemente controlan la ejecucin de otras sentencias o fragmentos de cdigo. A continuacin se lista una seri e de sentencias de control de Karel: if iterate if/else while Siempre a continuacin de las sentencias de control y despus de la expresin booleana , se debe colocar una llave que abre "{" para iniciar el grupo de sentencias a s er realizado. El grupo de sentencias va seguido de una llave que cierra "}". Uti lizamos el par "{ }" para un slo parmetro o para varios, no importa el nmero de ell os. El compilador devolver una advertencia en caso de que no se siga este estilo. - 10 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL La sentencia if En el Ejercicio 1 asumimos que Karel estaba orientado hacia el Este. Y si supiramo s que cuando se inicia est orientado hacia el Oeste o hacia el Sur ? A veces nece sitaremos girar primero tres veces, y a veces no. En este caso, la sentencia de control if es lo que necesitamos en nuestro programa. Aqu hay un ejemplo de como se debe escribir: ... if (facingSouth) { turnleft(); turnleft(); turnleft(); } . .. Las lneas " ... " significan que pueden haber otras sentencias antes o despus d e la sentencia if. Nos da igual en esta explicacin ya que no hay restricciones en cuanto a lo que hay antes o despus de la sentencia if. La forma ms general de la sentencia if es: ... if (xxx) { yyy } ... donde xxx es una condicin y yyy es cual quier nmero de sentencias a ejecutar si la condicin if es verdadera. - 11 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Condiciones que puede detectar Karel Date cuenta de que la condicin facingSouth, en el fragmento de programa de la pgin a del if ... if (facingSouth) { turnleft(); turnleft(); turnleft(); } ... La con dicin es una funcin de la situacin actual de Karel, a medida que se ejecuta el prog rama. Si Karel est actualmente orientado hacia el Sur, el valor de la funcin facin gSouth ser verdadero, y el conjunto de sentencias entre las llaves "{ }", se ejec utar. De otra manera, el valor facingSouth ser falso y el bloque de sentencias se saltar. Karel comprende cualquier funcin booleana que comprueba su situacin actual. Aqu hay un listado: frontIsClear leftIsClear leftIsBlocked rightIsClear nextToABeeper anyBeepersInBeeperBag noBeepersInBeeperBag facingNorth facingEast facingWest notFacingNorth notFacingSouth notFacingEast notFacingWest frontIsBlocked notNextToABeeper rightIsBlocked facingSouth "clear" significa que no hay ningn muro, mientras que "blocked" significa que hay un muro en esa direccin. Karel puede detectar si hay o no algn zumbador en la esq uina en la que se encuentra actualmente, as como detectar si tiene algn zumbador e n la mochila o no. Tambin tiene una brjula para detectar hacia qu direccin est orient ado. Por si fuera poco podemos unir dos o ms funciones booleanas con los operador es lgicos Y, O, y NO. - 12 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Podemos ver la sntaxis de los operadores y sus valores con las siguientes tablas: Operador y ("&&" ) Sntaxis: funcinBooleana1 && funcinBooleana2 Valor de la funcin 1 falso falso verdade ro verdadero Valor de la funcin 2 falso verdadero falso verdadero Resultado final falso falso falso verdadero Operador o (" ") Sntaxis: funcin-booleana1 funcin-booleana2 Valor de la funcin 1 falso falso verda dero verdadero Valor de la funcin 2 falso verdadero falso verdadero Resultado fin al falso verdadero verdadero verdadero Operador no ("!") Sntaxis: ! funcin-booleana Valor de la funcin falso verdadero Resultado final verda dero falso Los operadores "&&" y " " se aplican sobre dos funciones y el operador "!" solo sobre una. Lo mejor de los operadores lgicos es que si ponemos dentro de un par de parntesis las funciones con el operador lgico, entonces toda la operacin se vuel ve una funcin booleana, por lo que podemos aplicar ms operadores lgicos sobre ella. No qued claro? Revisa estos ejemplos: (facingNorth facingSouth) && frontIsClea r (! (frontIsBlocked && nextToABeeper)) facingEast ! (nextToABeeper && frontI sClear) - 13 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Ten mucho cuidado de colocar bien los parntesis, ya que si no lo haces, no te mar car error, pero seguramente har algo extrao que tu no quieres que haga. Por ejemplo , si queremos que Karel avance si est viendo al norte y el frente est libre, podem os hacer lo siguiente: ... if (facingNorth && frontIsClear) { move(); } ... Ejer cicio 3 : Escribe un programa de Karel que haga que Karel est orientado al Norte, desde cualquier direccin inicial, y a continuacin se apague. Debera terminar en la misma interseccin en la que empez. Alguna sugerencia? En un mundo nuevo inserta el ejemplo visto arriba para el caso en que Karel est orientado hacia el Sur. Pero, qu ocurre cuando no est orientado hacia el Sur?. Podra estar tambin orientado hacia l Norte o el Este !. Entonces necesitas dos sentencias if adicionales, en las cu ales 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 seccin hemos vi sto como usar las sentencias de control para adaptar Karel a cada situacin. - 14 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL

La sentencia iterate En el ejercicio 2, tenas que contar la secuencia correcta de pasos para que Karel pudiese resolver el problema. En este caso probablemente no hay una forma ms cor ta de resolverlo. Sin embargo, en algunos problemas hay aspectos del problema qu e tienen una naturaleza repetitiva. Por ejemplo, para ir de la esquina 15 a la 1 tendramos que poner un total de 14 move(). Es difcil dar justo con el nmero correcto . El lenguaje de programacin de Karel ofrece un mtodo mejor, la sentencia de contr ol iterate. Se escribe como sigue: ... iterate (xxx) { yyy } ... donde xxx debe ser un nmero entero positivo, y yyy representa cualquier nmero de sentencias de Ka rel. El problema de los 14 avances podra haberse escrito : ... iterate (14) { mov e(); } ... Ejercicio 4: Asume que Karel est en la esquina de la 8 Avenida y la 8 Ca lle, 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 1 esquina orientado al Su r. - 15 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Crees que es muy difcil? Bien puede ser que un poco de ayuda venga bien. Si puedes imaginar como hacerlo una vez (el primer zumbador de la esquina 7,7), la sentenc ia repite lo har tantas veces como t quieras. Crea un mundo como el de arriba y gur dalo con el nombre diagonal.mdo. Escribe el programa y gurdalo con el nombre "diago nal.txt. Asegurate de utilizar la sentencia iterate. Prueba el programa en este m undo inicial. Karel debera terminar en la esquina de la primera Avenida con la pr imera Calle, y llevando 7 zumbadores en la mochila. - 16 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL La sentencia if/else Aqu puedes ver como se escribe una sentencia if/else: ... if (xxx) { yyy } else { zzz } ... donde xxx es una condicin, yyy son sentencias a realizar si xxx es ver dadero, y zzz son las sentencias a ejecutar si xxx es falso. Ejercicio 5 : Karel tiene la tarea de alinear una coleccin de zumbadores en la primera Calle que ha sido distribuida desigualmente. Empieza en la 1 Calle y la 15 Avenida y est orienta do al Oeste. Se supone que en cada esquina hay exactamente un zumbador. Sin emba rgo, Karel puede encontrar 0, 1 o 2 zumbadores en cualquier interseccin. Su tarea es asegurar que exactamente hay un zumbador antes de continuar hacia la siguien te esquina. Cuando llega a la esquina 1,1 debe apagarse. Disea el mundo inicial p ara que Karel comience en la esquina 1,15 orientado hacia el Oeste. Karel debe e mpezar con 15 zumbadores en la mochila. Aleatoriamente sita 1 o 2 zumbadores en e squinas a lo largo de la 1 Calle, y deja alguna sin zumbadores. Guarda tu mundo i nicial con el nombre lineaDeZumbadores.mdo. Escribe el programa para hacer que Kar el complete la tarea descrita anteriormente. Guarda tu programa con el nombre lin eaDeZumbadores.txt. Truco: utiliza iterate, un if/else, y un if. Recuerda, no sabe mos qu esquinas tienen el nmero equivocado de zumbadores! Karel debe hacer la tare a correctamente independientemente del n de zumbadores que haya en cada esquina. - 17 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL La sentencia while Desde el principio, siempre se nos ha dicho la esquina exacta de inicio. Nosotro s queremos programar Karel para que se adapte mejor a su mundo. La sentencia whi le nos permite repetir pasos mientras se cumple una condicin, y esto nos va a per mitir programar a Karel para que no sea un chico tan rgido!. La sentencia while ti ene la forma siguiente: ... while ( xxx) { yyy } ... donde xxx debe ser una cond icin (una de las funciones booleanas listadas anteriormente), y yyy representa cu alquier nmero de sentencias de Karel. El ejercicio 1 podra haberse escrito de la s iguiente manera: ... while (frontIsClear) { move() ; } ... Esto soluciona el pro blema de caminar de nuevo a la 1 Calle, sin importar como de lejos se encuentre d e esta Calle. Ejercicio 6: La tarea de Karel es dejar zumbadores a lo largo de u na pista de carreras. Un ejemplo de dicha pista es la de la siguiente imagen. Ka rel debe dar una vuelta completa y depositar un zumbador en cada esquina a lo la rgo del camino. Guarda el programa con el nombre pistaCarreras.txt. Tu solucin debe usar sentencias while. Construye el mundo inicial de la siguiente imagen con el nombre pistaCarreras.mdo. Asegurate de poner dentro de la mochila suficientes zum badores para todas las esquinas. El ejemplo requiere 22 zumbadores. Karel debe e mpezar en cualquier interseccin de la pista. - 18 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Asegrate de que tu programa funciona en el mundo anterior, y despus prueba tu prog rama modificando el mundo inicial. Tambin, intenta iniciar a Karel desde diferent es intersecciones a lo largo del camino. Realiza Karel su tarea correctamente en todos los casos? - 19 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL La sentencia void Hasta ahora, le hemos dicho a Karel exactamente lo que tena que hacer tal como ne cesitbamos que lo hiciese. Esto funciona bien, pero te pudiste haber dado cuenta de que siempre se utilizan secuencias de sentencias similares. Un ejemplo es cua ndo Karel tiene que girar a la derecha, y nosotros le decimos " turnleft(); turn left(); turnleft(); ". No sera ms fcil si le pudiramos decir simplemente "turnright() " ?. En otras palabras, diciendo "turnright(); " Karel girara tres veces hacia la izquierda para alcanzar nuestro objetivo. Es posible. Ests suficientemente motiva do para aprender una nueva sentencia? Una de las razones de crear nuevas instruc ciones, es por evitar escribir tanto. Otra es para documentar mejor cual es nues tro objetivo, cuando nosotros mismos u otra persona lee el programa. Como te est ars dando cuenta, programar es una tarea extremadamente compleja, y necesitamos to da la ayuda necesaria para hacer las cosas correctamente ! Las sentencia void (q ue tambin se puede escribir como define) est situada en un sitio especial dentro d e un programa de Karel, justo despus de la sentencia "class program {". El siguie nte es un programa vlido para Karel: - 20 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Puedes definir cualquier nmero de instrucciones nuevas, y despus usarlas en el pro grama donde las necesites. Las instrucciones nuevas pueden contener sentencias d e control, si es necesario. Date cuenta de que la nueva instruccin puede tambin us ar una instruccin definida previamente. El ejercicio 5 podra haberse escrito: - 21 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Date cuenta de como la instruccin iterate acaba moviendo a Karel una esquina haci a adelante, sin tener en cuenta en n de zumbadores. Si haces esto 14 veces, estars 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 dia gonal2.txt. La nueva instruccin debera coger un zumbador en la posicin actual, si es que lo hay. Deberas usar esta instruccin para coger todos los zumbadores mientras Karel va a su casa en diagonal. Asegurate de que tienes el mundo diagonal.mdo car gado para probar tu programa. Karel debera finalizar en la esquina de la 1 Calle c on la 1 Avenida, con todos los zumbadores que ha ido cogiendo por el camino, y ap agarse. Ejercicio 8: Escribe un programa que ayude a Karel a escapar de un laber into que no contiene islas (cuadrados aislados). La salida del laberinto est marc ada ubicando un zumbador en la primera esquina que est fuera del laberinto, al la do del muro de la derecha. Una forma de resolver este problema es hacer que Kare l avance a lo largo del laberinto siguiendo el muro de su derecha ( imagina que est tocando el muro y que nunca puede despegar su mano de l). En la siguiente imag en hay un ejemplo de un laberinto del cual debera ser capaz de salir (no olvides que tu programa debera funcionar en todos los - 22 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL laberintos, no solo en el de la imagen). Guarda tu programa con el nombre laberin to.txt. Esto parece muy, muy complicado. Puedes darnos un mundo de ejemplo? Aqu tie nes un mundo inicial de ejemplo. La lnea roja muestra el camino que debera seguir Karel para este mundo. Recuerda que no sabes de antemano donde estarn los muros. Podra hacerse ms fcil si definieras unas pocas nuevas instrucciones que hicieran pa rte del trabajo. Aqu tenis un ejemplo: ... void sigueMuroDereha() { /*pon tu cdigo aqu*/ } ... Esta instruccin hace que Karel avance correctamente hacia el siguiente segmento de muro. Los diagramas de abajo muestran las 4 situaciones, Karel podra estar en cualquier punto del laberinto. Si sigueMuroDerecha() resuelve correcta mente los 4 casos, entonces has solucionado la parte principal del problema. Tam bin deberas definir turnright(). - 23 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Para probar tu programa crea un mundo como el del ejemplo y gurdalo con el nombre laberinto.mdo. Una vez te funcione el programa para este mundo, prueba a modifica rlo aadindo o quitando muros. Realiza Karel la tarea bien en todos los casos? Situaciones iniciales Movimientos respectivos - 24 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Parmetros en funciones Hemos visto ya la sentencia iterate que nos ayuda a iterar un bloque de cdigo un determinado nmero de veces, pero siempre tenamos que colocar un nmero fijo en la se ntencia, te has puesto a pensar que pasara si por ejemplo necesitara una instruccin que volteara a Karel 180? Pues la respuesta natural sera "haz una instruccin que h aga que Karel gire dos veces". Pero... crees que sera posible usar la instruccin qu e hicimos anteriormente turnright()? Si existiese alguna forma de que en vez de poner 3 en la sentencia iterate pusiesemos un nmero variable, podramos usar la ins truccin tanto para girar a la derecha como para dar media vuelta. Pues si existe! Primero retomemos el cdigo para girar a la derecha: ... void turnright() { iterat e(3) { turnleft(); } } ... Ahora, todas las nuevas instrucciones declaradas pued en adems llevar un parmetro, pero que es un parmetro?, pues es un numerito que le po demos mandar a la instruccin cuando la llamamos, y como cuando declaramos la inst ruccin no sabemos con que nmero la vamos a llamar, reemplazamos el nmero por una pa labra. Alguna vez has odo la frase "los primeros n nmeros"?, pues precisamente eso son los parmetros. Podemos en vez de n poner 1, 2 3, quedando "los primeros 3 nmer os" por ejemplo. Este parmetro puede tener el nombre que sea, siempre y cuando la primer letra no sea un nmero y el nombre del parmetro no sea el mismo que una pal abra del lenguaje, por ejemplo no se puede llamar if, iterate, move, etc. Este p armetro se puede usar en cualquier lugar dentro de la definicin de la instruccin, e n cualquier sentencia o instruccin que necesite un nmero (justo como la sentencia iterate). Redefinamos ahora la instruccin turnright como la instruccion turn: ... void turn(n) { - 25 -

Agosto 2007 iterate(n) { turnleft(); } } ... Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL De esta forma si escribimos en nuestro cdigo "turn(3);" Karel girar a la derecha, si escribimos "turn(2);" dar media vuelta, si escribimos "turn(1);" girar a la izq uierda y si escribimos "turn(0);" no har nada. Aqui puedes ver como se escribe un a instruccin con un parmetro en general: ... void xxx (yyy) { zzz } ... donde xxx es el nombre de la instruccin, yyy es el nombre del parmetro y zzz es cualquier nme ro de instrucciones. Ejercicio 9: Escribe una nueva instruccin que avance a Karel el nmero de veces que se le mande como parmetro. Debes de evitar que Karel choque con alguna pared. Tienes dudas? Usa como base el cdigo de la instruccin gira. - 26 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Las funciones succ y pred Ahora ya sabemos como mandarle un nmero a un procedimiento, y probablemente ya ha brs intentado poner operaciones como suma, resta o multiplicacin, sin embargo lama nto decirte que ninguna de estas operaciones estn soportadas en Karel. Por otro l ado, existen dos funciones que nos permiten sumarle 1 a un nmero y restarle 1. Pe ro... qu es una funcin? Una funcin es una instruccin que devuelve un valor, es decir, reciben un parmetro (o ms) que luego procesa, para al final regresar un valor; po r ejemplo, la funcin booleana junto-a-zumbador devuelve verdadero si Karel est par ado junto a un zumbador y falso si no lo est. En Karel no se pueden declarar func iones nuevas, pero se pueden usar las que ya existen. Las funciones succ y pred son dos instrucciones que reciben un parmetro, posteriormente, devuelven un nmero ms y un nmero menos (respectivamente) que el que le enviamos. La funcin succ se esc ribe as: ... succ(xxx); ... donde xxx es un nmero o un parmetro, y la funcin pred se escribe as: ... pred(xxx); ... donde xxx es un nmero o un parmetro. Debido a que d evuelven un nmero, solo nos pueden servir poniendolas en alguna instruccin o sente ncia que reciba un nmero, como iterate, otro succ o pred o una instruccin personal que reciba un parmetro. Por ejemplo, el siguiente trozo de cdigo pone n + 1 zumba dores en donde Karel se encuentra: ... - 27 -

Agosto 2007 iterate( succ(n) ) { putbeeper(); } ... Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL nota que n se "incrementa" (se le suma uno). Si en vez de succ, pusieramos pred, Karel dejara n - 1 zumbadores, porque la n se "decrementa" (se le quita uno) cua ndo se pone dentro de una funcin pred. Ejercicio 10: Escribe una nueva instruccin que reciba un nmero n y mueva a Karel n + 2 veces (validando el choque contra par edes), y posteriormente, coloque n - 2 zumbadores en la posicin en donde est. PIST A: Usa un iterate para mover a Karel y otro para colocar los zumbadores. NO se v ale colocar instrucciones fuera de los ciclos iterate. - 28 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL La funcin iszero La ltima funcin en Karel, es la funcin iszero, que nos ayuda a saber si un nmero es cero. Devuelve verdadero si el nmero es cero y falso si no lo es. Es evidente de que si ponemos "iszero(0)" no es muy til, ya que sabemos perfectamente que cero e s cero ( :S ). Sin embargo es muy til cuando se est manejando parmetros. Por ejempl o, queremos hacer una instruccin que avance "n" lugares, pero si el parmetro es ce ro, gire a la izquierda. Por razones didcticas, en esta ocasin te daremos la soluc in: ... void avanzaSiNoEsCero (n) { if ( iszero(n) ) { turnleft(); } else { itera te (n) { move(); } } } ... Ahora si, te toca a ti: Ejercicio 11: Define una nuev a instruccin que haga que Karel ponga "n" zumbadores en donde se encuentra, pero si "n" es cero, recoja 1 zumbador. - 29 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Recursividad Hemos llegado al ltimo tema, y no por eso el menos importante, de hecho, es el te ma ms complicado que veremos aqui, y es muy til no solo para Karel, sino para reso lver cualquier problema. Debido a la complejidad del tema, se han creado 5 subte mas: 1. 2. 3. 4. 5. Fundamentos Definicin Recursividad simple Recursividad con pa rmetros Recursividad mixta Fundamentos Empecemos. Te has preguntado alguna vez qu sucede cundo llamas a una instruccin que tu creaste? Como te habrs dado cuenta, se ejecuta la instruccin que le pediste y l uego continua en el lugar en donde se qued. Pero en realidad, cmo hace eso la compu tadora? Pues bien, la computadora tiene una cosa que se llama "pila de llamadas" , cuando un programa se ejecuta y encuentra una instruccin, se guarda en la pila en que lugar se qued, entonces ejecuta la instrccin que le pediste y al terminar l a instruccin, revisa en la pila en donde estaba anteriormente, para continuar en ese lugar. Muy enredado? Mira este dibujo: - 30 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL - 31 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Espero haya quedado claro, ya que esto es el punto crucial de la recursividad. A hora que sabemos como funciona el llamado a procedimientos o instrucciones. Defi namos lo que es recursividad. Definicin Una instruccin recursiva, es aquella que en algn momento, se llama as misma. Por ej emplo, puedes revisar en libros y en muchos otros lados, la definicin recursiva d el factorial: factorial(1) = 1 factorial(n) = n * factorial(n - 1) - 32 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Como puedes ver, para saber el factorial de un nmero, necesitas saber el factoria l del nmero anterior. All est la recursividad. Toda instruccin recursiva, consta de dos partes: 1.- Base Es un valor fijo al que eventualmente, la recursin debe de l legar, normalmente, es un valor pequeo y no demostrable. Por ejemplo, factorial d e 1, es 1, y no se puede demostrar, adems, si quieres calcular el factorial de cu alquier nmero, eventualmente, debes de saber el factorial de 1. 2.- Recursin Consiste en la parte en donde la instruccin se llama as misma, adems de efectuar algunas operaciones con el resultado. Por ejemplo, para el factorial d e 3, se calcula el factorial de 2 y eso se multiplica por 3. Ahora que sabes que es recursividad, intenta hacer la definicin recursiva de la serie de Fibonacci, la cual dice que sus primeros dos elementos (1 y 2) son 1, y para cualquier otro nmero de Fibonacci, se debe sumar el Fibonacci de los dos nmeros anteriores, Por ejemplo: Fibonacci(3) = 2, Fibonacci(5) = 5. Pasemos de lleno a la recursividad en Karel. Recursividad simple Intentemos ahora llamar a una instruccin desde s misma, recordemos que debe de ten er una base y una definicin recursiva, te parece bien que la base sea si el frente esta bloqueado termina?, y te parece bien que si no avance una casilla y entonce s se llame asi misma?, Hagmoslo! ... void recursiva () { if (frontIsClear) { move( ); recursiva(); } - 33 -

Agosto 2007 } ... Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Nota que en Karel es imposible decirle que termine la instruccion, as que mejor i nvertimos la condicin y avanzamos si el frente est libre, es otra forma de poner la base!, por que, en otras palabras, la base es lo que hace que la recursin termin e y no sea infinita. Nota tambin que en este caso las operaciones que hacemos son solamente "move();". Algo diferente al factorial no? Qu crees que haga est cdigo? Po nlo en el Simulador Karel y adivina... As es! Karel avanzar mientras el frente este libre. Entonces te preguntars no sera mejor un ciclo mientras? Y la respuesta es: si solamente quieres hacer eso, s, sin embargo, que tal si quieres contar con zumb adores cuantos pasos avanzaste? A verdad! Si queremos hacer eso, debemos agregarl e una lnea a nuestro cdigo: ... void recursiva () { if (frontIsClear) { move(); re cursiva(); putbeeper(); } } ... Ahora prubalo. Wow! Sorprendente! Por qu funciona? Si recuerdas la seccin de fundamentos, cada vez que se llama una instruccin, la sigu iente instruccin se guarda en la pila de llamadas, como se va a llamar exactament e el nmero 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 siem pre sern "putbeeper();". En este ejemplo, solo hay una instruccin antes y despus de las llamadas recursivas, pero puede haber muchsimas ms. - 34 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Si an no lo entiendes, trata de simular la pila de llamadas de la misma forma que est en la imagen. Ejercicio 12: Recuerdas el problema del peridico del Ejercicio 2 ? Ahora imagina que el peridico est en la posicin 1,1 y que la casa de Karel, puede estar ubicada en cualquier posicin del mundo, eso s, con la misma orientacin y for ma. Haz un programa que haga que Karel lleve el peridico a su sala. Usa recursivid ad! 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 operacion es que van a ir antes, y las que van a ir despus (las que se van a guardar en la pila). Recursividad con parmetros Recuerdas los parmetros? Recuerdas las funciones pred() y succ()? Que pasara si a una instruccin con parmtro la llamaramos usando pred() o succ()? Todo esto, en Karel es posible, definamos una instruccin con parmetros y volvmosla recursiva usando suc c(): ... void recursiva2 (n) { if (frontIsClear) { move(); recursiva2 ( succ (n) ); } else { iterate(n) { putbeeper(); } } } ... - 35 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Este cdigo hace exactamente lo mismo que el de la seccin anterior, con la diferenc ia de que la complejidad que exista en la pila de llamadas es eliminada, y coloca da como una instruccin base. En cada paso de la recursin, se aumenta uno, y cuando llegas a la base, tiene un nmero que tal vez pudas usar para tu beneficio. No te olvides que tambin puedes usar la funcin pred() y iszero() y que en la llamada re cursiva puedes llamarla con el parmetro sin modficar. Como punto importante, hay que destacar que en la pila de llamdas, adems de la instruccin que sigue, tambin se guarda el valor actual del parmetro. Ejercicio 13: Realiza el Ejercicio 12 pero con Recursividad con parmetros. Ejercicio 14: Realiza una instruccin que avance a Karel tantas veces como zumbadores tenga en su mochila utilizando Recursividad c on parmetros, NO se vale usar un ciclo mientras. Recursividad mixta Si ya dominas los dos tipos de recursividad anteriores, esto ser muy fcil para ti, ya que la recursividad mixta no es ms 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, co loca en 1,1 el resultado de la multiplicacin. Este es uno de los problemas ms clsic os de recursividad mixta, sin ella la complejidad del problema sera muy elevada. Para este problema usaremos dos instrucciones, uno con recursividad simple y el otro con parmetro. La mecnica de solucin es la siguiente: Se van a tomar todos los zumbadores de una posicin con recursividad con parmetros, para que al llegar a la base, el parmetro tenga el nmero de zumbadores que hay en dicha posicin, posteriorm ente, ese nmero se pasa como parmetro a la instruccin recursiva simple (si, aunque la recursividad es simple, - 36 -

Agosto 2007 Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL tambin tiene parmetro), y en cada paso, se le va a llamar recursivamente con el mi smo parmetro, de esa forma, en la pila de llamadas, el parmetro va a estar tantas veces como zumbadores haya en la segunda posicin, y vuala. Tal vez quede ms 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) { pickbeepe r(); cuenta( sucede (n) ); } else { move(); multiplica (n); - 37 -

Agosto 2007 } } ... Facultad de Ciencias Fsico-Matemticas sede de la Olimpiada Estatal de Informtica de Nuevo Len UANL Esta casi completa, pero le falta implementar la instruccin veAlInicio (que debe ser de lo ms trivial) y el posicionamiento inicial, tal vez en un principio no en tiendas bien, revisa el cdigo paso a paso hasta que lo comprendas, Suerte! Ejercic io 15: Teniendo un mundo como el de abajo: en donde puede haber cualquier cantidad de calles y cualquier ancho en las aveni das (siempre cerrado el circuito y sin "islas" o bifurcaciones),deje en la esqui na izquierda ms inferior (2,1 en el ejemplo), tantos zumbadores como nmero de call es de ancho 1 que hay, Karel lleva infinitos zumbadores en su mochila. En result ado del ejemplo es 3. En este problema se usan casi todos los temas vistos en el curso, emplealos y resulvelo. Hemos llegado al fin del curso, ahora debes ser capaz de participar en la Olimpi ada Mexicana de Informatica, no olvides seguir resolviendo problemas para mejora r siempre tus habilidades, puedes encontrar ligas a las pginas en donde hay probl emas en la pgina principal de la OMI. SUERTE! - 38 -