Está en la página 1de 345

Ejercicio 2: El Tablerohttps://www.youtube.com/watch?

v=mb5127xJE30
Para empezar a programar, el primer elemento que vamos a usar es
un tablero cuadriculado, similar al del Ajedrez, Damas o Go.

Estos tableros pueden ser de cualquier tamaño, por ejemplo,

4x4 3x2

Siempre vamos a necesitar un tablero sobre el


cual ejecutar nuestros programas, ¡pero despreocupate! nos vamos a
encargar de crearlos por vos en cada uno de los ejercicios. Lo interesante es
que un mismo programa puede ejecutarse sobre distintos tableros,
potencialmente produciendo resultados diferentes. 

Para que veas lo que te decimos, presioná el botón Continuar, y vamos a generar tu
primer tablero: un tablero de 3x3. 
 ¡Muy bien!
Tablero final

0 1 2

2 2

1 1

0 0

0 1 2

Perfecto, ¡este es tu primer tablero de 3x3! 

Notá que ahora la celda (casillero) de la esquina inferior izquierda está


pintada de otra forma. En el próximo ejercicio veremos por qué. 

Ejercicio 3: El Cabezal
El tablero generado en el ejercicio anterior tenía una celda marcada:

0 1 2

2 2

1 1

0 0

0 1 2

¿Y eso por qué?  Porque nuestra máquina tiene un cabezal, que en todo


momento está situado sobre una de las celdas del tablero y puede realizar
distintas operaciones sobre ella (paciencia, ya las vamos a conocer ).

Por ejemplo, el siguiente es un tablero de 5x2, con el cabezal en la segunda


fila y la cuarta columna.

0 1 2 3 4
1 1

0 0

0 1 2 3 4

¡Algo importante! Contamos las filas hacia arriba, y las columnas hacia la
derecha. La primera fila es la de abajo de todo, y la primera columna es la
de la izquierda.

Vamos a ver otro ejemplo?

Presioná Continuar y generaremos un tablero 3x3 con el cabezal en la segunda


columna y tercera fila.

 ¡Muy bien!
Tablero final

0 1 2

2 2

1 1

0 0

0 1 2

Como podrás ver podemos crear muchísimos tableros distintos, pero ¿el
cabezal se va a quedar siempre en el mismo casillero?

Ejercicio 4: Que comience el movimiento


Hasta ahora lo que vimos no fue muy emocionante, porque no te
enseñamos cómo darle instrucciones a la máquina y sólo te mostramos un
tablero . En este ejercicio vamos a aprender una de las órdenes que
podemos darle a la máquina: mover el cabezal.
Por ejemplo, partiendo de un tablero inicial vacío con el cabezal en el origen
(abajo a la izquierda), podemos fácilmente crear un programa que mueva el
cabezal una posición hacia el norte:
Inicial Final

0 1 2 0 1 2

2 2 2 2

1 1 1 1

0 0 0 0

0 1 2 0 1 2

El código del programa (es decir, el texto de la descripción de la solución


que le daremos a la computadora) que logra esto es el siguiente:

program {
Mover(Norte)
}

¿No nos creés? Escribí el código anterior en el editor y dale Enviar.


 ¡Dame una pista!

Program {Mover(Norte)}
Muy bien! Tu solución pasó todas las pruebas

Tablero inicial

0 1 2

2 2

1 1

0 0

0 1 2

Tablero final

0 1 2
2 2

1 1

0 0

0 1 2

Ejercicio 5: Que siga el movimiento


Entendamos qué es lo que acabamos de hacer: ¡crear un programa!

Todo programa tiene exactamente un program: una sección del código que
declara los comandos (acciones) que queremos que la máquina realice sobre
el tablero inicial. Al ejecutar un programa obtendremos un tablero final.

La sintaxis de un program es bastante simple:

1. escribimos una línea (renglón) que diga program, seguido de una llave


de apertura: {
2. a continuación, los comandos: uno por línea
3. y finalmente, una última llave que cierra la que abrimos
anteriormente }

Vamos a ver algunos ejemplos de programs:


 uno que no hace nada

program {
}

 uno que mueve el cabezal una posición hacia el norte

program {
Mover(Norte)
}

 uno que mueve el cabezal dos posiciones hacia el norte


program {
Mover(Norte)
Mover(Norte)
}

¡Te toca a vos!

Creá un programa que en un tablero de 2x4 con el cabezal en el origen (la celda de
abajo a la izquierda), mueva el cabezal tres veces hacia el norte:
Inicial Final

0 1 0 1

3 3 3 3

2 2 2 2

1 1 1 1

0 0 0 0

0 1 0 1

 ¡Dame una pista!

program {Mover(Norte)Mover(Norte)Mover(Norte)}
¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial
0 1

3 3

2 2

1 1

0 0

0 1

Tablero final

0 1
3 3

2 2

1 1

0 0

0 1

Los lenguajes de programación son creados con algunas palabras que solo se
pueden utilizar con un fin determinado. Se las llama palabras reservadas .
En Gobstones, el lenguaje que estamos utilizando, program es una palabra
reservada.

Como ya sabemos que nuestros programas son ejecutados por la máquina,


de ahora en más diremos "creá un programa que haga ..." en vez de "creá un
programa que provoque que la máquina haga ...".

Pero ojo: la máquina sigue estando ahí y no hay que olvidarla, sólo hacemos esto para
escribir un poco meno
Ejercicio 6: Para todos lados
Como te imaginarás, el cabezal no sólo se puede mover hacia el Norte, y un programa
puede combinar cualquier tipo de movimientos.
Creá un programa que mueva el cabezal dos posiciones hacia el Este y una hacia el Sur,
produciendo el siguiente efecto:
Inicial Final
0 1 2 0 1 2

2 2 2 2

1 1 1 1

0 0 0 0

0 1 2 0 1 2

program {Mover(Este) Mover(Este)Mover(Sur)}


 ¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial
0 1 2

2 2

1 1

0 0

0 1 2

Tablero final

0 1 2

2 2

1 1

0 0

0 1 2

Notá que estos dos programas hacen lo mismo:

program {
Mover(Este)
Mover(Este)
Mover(Sur)
}
program {
Mover(Este)
Mover(Sur)
Mover(Este)
}

Moraleja: como te decíamos al principio ¡no hay una sóla forma de resolver un problema!
Y además, el orden, a veces, no es tan importante. Acompañanos a entender mejor esto.

SIGUIENTE EJERCICIO EL ORDEN DE LAS COSAS


Ejercicio 7: El orden de las cosas

Cuando trabajamos en Gobstones, hacemos las cosas en un cierto orden. Por


ejemplo, si tenemos este programa:
program {
Mover(Norte)
Mover(Este)
}

una forma posible de leerlo (llamada operacional) es como lo haría una


máquina, en orden, de arriba hacia abajo:

1. primero se mueve al norte: Mover(Norte)


2. luego se mueve al este: Mover(Este)

Y de hecho se ejecuta de esa forma. Esto es cómo lo hace.

Pero, los humanos, solemos pensar en función del resultado final, es decir,
resaltamos el objetivo del programa. Nos importa más qué hace, y no cómo.
Esta manera denotacional nos llevaría a decir que, simplemente, mueve el
cabezal al noreste.

Por eso hay varias formas de resolver un mismo problema: podemos crear
varios programas que hagan lo mismo (el qué), pero que lo hagan de forma
diferente (el cómo).

Veamos si entendiste esto: creá otro programa que haga lo mismo que el de arriba
(mover hacia el noreste), pero de manera distinta. Ojo: tiene que funcionar en un
tablero de 2x2.
 ¡Dame una pista!

Recordá que no existe la dirección Noreste, pero sí Norte y Este.

Probá invertir el orden de los comandos. Si bien la máquina lo ejecutará en


un orden diferente, el resultado final será el mismo. 
1
program {Mover(Este)Mover(Norte)}
Muy bien! Tu solución pasó todas las pruebas
Tablero inicial

0 1

1 1
0 0

0 1

Tablero final

0 1

1 1

0 0

0 1

¡Perfecto!

Recién creamos un programa en el que el orden no afecta lo que queremos


hacer. Pero esto no será siempre así, en breve nos toparemos con problemas
en los que hay que tener más cuidado con el orden de los comandos.

Ejercicio 8: Sí, esto también se puede


romper
Hasta ahora veníamos tratando de esquivar el asunto, pero seguro ya habrás
pensado que tiene que haber alguna forma de romper esto (incluso es
posible que ya te haya pasado).

Si bien nunca vamos a querer que nuestro programa se rompa, es algo que


definitivamente te va a pasar muchas veces. Pero no es motivo para
frustrarse ni mucho menos, te aseguramos que a todo el mundo le pasó
alguna vez (bueno, también 2, 3, 100, 800 veces...).

Dicho esto, te vamos a mostrar una forma de hacerlo, simplemente para que
no te asustes tanto cuando te pase de verdad .

¿Y cómo es esa forma? Descubrilo vos: partiendo del tablero que te mostramos acá
abajo, creá un programa que provoque que el cabezal se salga fuera de los límites.
0 1 2

2 2

1 1
0 0

0 1 2

program {Mover(Este)Mover(Este)Mover(Este)}
 ¡Muy bien! Tu solución pasó todas las pruebas
¡BOOM!
Tablero inicial

0 1 2

2 2

1 1

0 0

0 1 2

Tablero final

EXPLOSIÓN

[1:31]: No se puede mover hacia la dirección Este: cae afuera del tablero.
¡BOOOOOOOOOOOOOOOOOM!   
Ey, ¿qué pasó?
Tu programa falló, se rompió, o como lo llamamos en el universo Gobstones: hizo BOOM.
Y, ¿qué significa esto?
Que los comandos que le diste a la computadora no se pueden ejecutar, y hay algo que
vas a tener que cambiar para que funcione. En este ejercicio eso no tiene sentido porque
lo hicimos a propósito, pero tenelo en cuenta para cuando falles en el futuro.

Siguiente Ejercicio: Nuestras primeras bolitas

Ejercicio 9: Nuestras primeras bolitas


Genial, ya entendiste cómo mover el cabezal del tablero usando la
operación Mover y las direcciones (Sur, Oeste, etc). Vayamos un paso más allá:
las bolitas.

En cualquier celda de nuestro tablero podemos poner bolitas. Las hay de


distintos colores:

 rojas (Rojo);
 azules (Azul);
 negras (Negro);
 y verdes (Verde).

Por ejemplo, este es un tablero con una bolita roja y una negra:

0 1
1
1 1

0 0
1

0 1

Además de moverse, el cabezal también puede poner bolitas en la celda


actual. Para eso contamos con la operación Poner, que le dice al cabezal que
deposite una bolita del color dado:

0 1 2

2 2

1 1

0 0

0 1 2

program { Poner(Rojo) }
¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial

0 1 2

2 2

1 1

0 0

0 1 2

Tablero final

0 1 2

2 2

1 1

0 0
1

2
0 1

¡Felicitaciones! Acabás de escribir un programa que pone una bolita roja en


la celda actual.

Ejercicio 10: Más y más bolitas


Algo interesante de nuestros tableros es que en sus celdas podemos poner
cualquier cantidad de bolitas de cualquier color.

Por ejemplo, si tenemos este tablero:

0 1 2 3 4

1 1

0 0

0 1 2 3 4
y ejecutamos el siguiente programa:
program {
Poner(Rojo)
Poner(Rojo)
Poner(Azul)
Poner(Verde)
Poner(Rojo)
}
el cabezal colocará en la celda actual tres bolitas rojas, una azul y una verde.

¡Escribí este programa en el editor y fijate cómo queda el tablero!


 ¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial

0 1 2 3 4

1 1

0 0

4
0 1 2 3

Tablero final
3r 1
1
1

Notá que en este problema, si cambiamos el orden en que llamamos (usamos


a) Poner, el resultado no cambia: siempre nos terminará quedando un tablero
con tres bolitas rojas, una azul y una verde.
Por ejemplo, los siguientes dos programas también resuelven este mismo
problema:

program {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Verde)
Poner(Azul)
}

program {
Poner(Rojo)
Poner(Azul)
Poner(Rojo)
Poner(Verde)
Poner(Rojo)
}

Ejercicio 11: Poné tus primeras bolitas


Como te habrás dado cuenta, estos tableros son un poco mágicos, podemos
poner en una celda tantas bolitas como queramos: 2, 4, 12, 50, 1000. ¡No hay
ningún límite!

Esto es algo muy interesante que ocurre al programar: podemos trabajar con
cantidades tan grandes como queramos.

Ah, y ahora te toca a vos: creá un programa que ponga cuatro bolitas rojas y tres
bolitas negras en la celda actual.
program{Poner(Rojo)Poner(Rojo)Poner
(Rojo)Poner(Rojo)Poner(Negro)Poner(Negro)Poner(Negro)}

Tablero inicial

0 1 2

2 2

1
1

0 0

0 1 2

4r 3n
aaa

¡Muy bien! Tu solución pasó todas las pruebas

Ejercicio 12: Sacar Bolitas


De la misma forma que hay un "poner bolita" (Poner), tenemos un "sacar
bolita" (Sacar), que quita exactamente una bolita del color dado.
Por ejemplo, el siguiente programa saca dos bolitas de la posición inicial.

program { Sacar(Rojo) Sacar(Rojo)}

Sabiendo esto, creá un programa que elimine sólo la bolita roja de este


tablero. ¡Tené cuidado! Prestá atención a la posición del cabezal .
0 1

1
1 1

0 0
1

0 1

program {Mover (Sur) Sacar(Rojo)}


¡Muy bien! Tu solución pasó todas las pruebas
Tablero final
0 1

1
1

0 0
1

0 1

¿Y si no hubiera ninguna bolita para sacar?

Ejercicio 13: Cuando no hay bolitas


Cada vez que usamos Sacar, tenemos que tener más cuidado que con Poner,
porque...

¿Querés saber por qué? Intentá sacar una bolita verde o azul de este tablero y
descubrilo.

Tablero inicial
0 1
program{Sacar(Verde)}
1
1

0 0
1

0 1

 ¡Muy bien! Tu solución pasó todas las pruebas

¡BOOM!
Tablero inicial Tablero final
0 1
DESASTRE
1 BOOM
1

0 [1:9]: No se puede sacar una bolita de color Verde: no hay


0 1

bolitas de ese color.


0 1
Claro, otra vez BOOM.

Esta vez lo que pasó fue que el cabezal intentó sacar una bolita de un color
que no había, y como no sabía qué hacer se autodestruyó. Esto te va a pasar
siempre que intentes sacar una bolita que no exista, así que ¡a prestar
atención!

Ejercicio 14: Sacar bolitas


0 1

1
1 1

0 0
1

0 1
Un último esfuercito: usando Sacar, creá un programa que elimine todas las
bolitas de este tablero:
¡Muy bien! Tu solución pasó todas las pruebas
Tablero final program{Sacar(Verde)Sacar(Azul)Sacar(
0 1
Rojo)Sacar(Negro)}
1 1

0 0

0 1

Programas!
¡Felicitaciones, terminaste esta guía! Eso significa que ya sabés de bolitas,
tableros y cabezales, y que podés controlar a éste último con los comandos

 Poner
 Sacar
 Mover

Y además, sabés como definir un programa (program)

Sin embargo, hay muchas más cosas que podés hacer en el


lenguaje Gobstones con este tablero. En las próximas guías seguiremos
aprendiendo más comandos y nuevas herramientas de programación.

Y lo más importante: modularizar a nuestros programas usando


procedimientos y funciones. ¡Acompañanos!

Práctica Primeros Programas


Ahora que ya conocés a Poner, Mover y Sacar, ya estamos en condiciones de
pedirte que los combines. 

Acompañanos a resolver algunos desafíos.


Ejercicios

  1. Calentando motores


  2. Combinando comandos
  3. La fila roja
  4. Una escalerita
  5. Portugal
  6. Y ahora una de más cerquita
  7. Limpiando el jardín
  8. Reemplazar bolitas

Ejercicio 1: Calentando motores


¡Veamos un primer ejemplo!

El siguiente programa coloca una bolita roja en la posición inicial y una


negra al este.

program { Poner(Rojo) Mover(Este) Poner(Negro)}

Probá escribir y ejecutar este programa. Te mostraremos el resultado al


ejecutarlo en un tablero de 2x2, y en otro de 3x2, ambos con el cabezal
inicialmente en el origen.

program{Poner(Rojo)Mover(Este)Poner(Negro)}

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

  Tablero de 2x2
Tablero inicial

0 1

1 1

0 0
0 1

Tablero final

0 1

1 1

1
0 0
1

0 1

  Tablero de 3x2
Tablero inicial
0 1 2

1 1

0 0

0 1 2

Tablero final

0 1 2

1 1

1
0 0
1

0 1 2

Ahora que combinamos operaciones, la cosa se pone un poco mas


complicada, porque hay que tener más cuidado con el orden.

Por ejemplo, mirá el programa que escribiste:

program {
Poner(Rojo)
Mover(Este)
Poner(Negro)
}
Operacionalmente:

1. pone una roja


2. luego se mueve al este
3. luego pone una negra

Es decir: pone una roja en la posicion inicial, y una negra al este

Y ahora mirá este otro:

program { Mover(Este) Poner(Rojo) Poner(Negro)}

Operacionalmente:

1. se mueve al este
2. luego pone una roja
3. luego pone una negra

Es decir: pone una roja y una negra al este de la posición inicial.

Moraleja: ¡no hacen lo mismo! Cambiar el orden nos cambió el qué.

https://mumuki.io/identity/realms/
Mumuki/protocol/openid-connect/auth?
client_id=Mumuki&redirect_uri=https
%3A%2F%2Fmumuki.io%2Fauth
%2Fidentity
%2Fcallback&response_type=code&state
=0adff49ac9c56ef53e840173a24a587172
b61ea8d62e6699
Ejercicio 2: Combinando comandos
Creá un programa que ponga dos bolitas en la posición inicial, y otras dos en
la celda de al lado hacia el Este. Todas las bolitas deben ser rojas.
Acá te dejamos un ejemplo de cómo debería quedar el tablero:

program {
Poner(Rojo)
Poner(Rojo)
Mover(Este)
Poner(Rojo)
Poner(Rojo)
}

 ¡Muy bien! Tu solución pasó todas las pruebas


Tablero inicial Tablero final

0 1

1
1

0 0
1

0 1

0 1

1 1

0
2
222 2
1 0

2 2
0 1
Ejercicio 3: La fila roja
Creá un programa que a partir de un tablero vacío con el cabezal en el origen,
dibuje una linea de cuatro celdas hacia el Este. Las bolitas deben ser rojas y
debe poner una bolita por celda.
Ademas, el cabezal debe quedar en el extremo final de la línea, como se ve
en la imagen:
0 1 2 3

1
1

0 1 1 1 1 0
1 1 1 1

0
2 1
2 2
2
2
3

Program {
Poner(Rojo)
Mover(Este)
Poner(Rojo)
Mover(Este)
Poner(Rojo)
Mover(Este)
Poner(Rojo)
}
 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero inicial
0 1 2 3

1
1

0 0
1 1 1

0 1 2 3

Tablero final
0 1 2 3

1 1

0 1 1 1 1 0
1 1 1 1

0
2 1
2 2
2 3
2

Ejercicio 4: Una escalerita


Usando las herramientas que ya conocés, creá un programa que dibuje una
escalera azul como la que se ve en la imagen. El cabezal empieza en el
origen (o sea, en el borde Sur-Oeste) y debe quedar en el extremo inferior
derecho de la escalera.
Mirá la imagen:
0 1 2 3

3 3

2 1 2

1
1
2 1

1 1 1

0 1 1 1 0

0
2 2
1
2
2 3

program{
Poner(Azul)
Mover(Norte)
Poner(Azul)
Mover(Norte)
Poner(Azul)
Mover(Sur)
Mover(Este)
Poner(Azul)
Mover(Sur)
Poner(Azul)
Mover(Este)
Poner(Azul)
}

 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero inicial
0 1 2 3

3 3

2 2

1 1
1 1

1 1 1
0 0

0 1 2 3
Tablero final

0 1 2 3

3 3

2
1 1
2 1

1
2 1 2 2
1
1 1 1 1

1
2 1 2 1 2
0 1 0

2 0 1 2 3

Ejercicio 5: Portugal
Creá un programa que dibuje una bandera portuguesa.
La bandera de Portugal se ve así:

Como no nos vamos a poner tan quisquillosos, te vamos a pedir una versión
simplificada, que se tiene que ver así: (tablero final)

0 1 2

1 1 1 1
1
2 2
1 1 1

2
0 1 0

2
1 1 1

0 1 2

Ah, el cabezal empieza en el origen.

program{
Poner(Verde)
Mover(Norte)
Poner(Verde)
Mover(Este)
Poner(Rojo)
Mover(Sur)
Poner(Rojo)
Mover(Este)
Poner(Rojo)
Mover(Norte)
Poner(Rojo)
}
 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial
0 1 2

1 1
1 1

0 0
1 1 1

0 1 2

Tablero final
0 1 2
1 1
1 1 1

0 1 1 1 0

2 2 2
1 1 1

0 1 2

Ejercicio 6: Y ahora una de más cerquita


Ya lograste dibujar la bandera de Portugal con Gobstones. Ahora probemos
hacer una bandera de Latinoamérica. ¿Te animás a dibujar la de Argentina?

Aunque como en Gobstones no hay amarillo, nos vamos a tomar el


atrevimiento de cambiarlo por rojo (perdón Belgrano, no nos queda otra ).

Con el cabezal en el origen, tu tarea es dibujar esta pseudo-bandera argentina:

0 1 2 3 4

1 1 1 1 1

2 1 1 1 1 2
1

2 2 2 2 2
1 1 1

2
1

1 1 1 1 1

0
1 1 0
1 1 1

2 2 2 2 4 2
0 1 2 3

program{Poner (Azul)
Mover(Norte)
Mover(Norte)
Poner(Azul)
Mover(Este)
Poner(Azul)
Mover(Sur)
Mover(Sur)
Poner(Azul)
Mover(Este)
Poner(Azul)
Mover(Norte)
Poner(Rojo)
Mover(Norte)
Poner(Azul)
Mover(Este)
Poner(Azul)
Mover(Sur)
Mover(Sur)
Poner(Azul)
Mover(Este)
Poner(Azul)
Mover(Norte)
Mover(Norte)
Poner(Azul)
}
¡Muy bien! Tu solución pasó todas las pruebas Tablero Inicial
0 1 2 3 4
1 1 1 1 1
2 2

1 1
1

1 1 1 1 1
0 0

4
0 1 2 3

Tablero Final
0 1 2 3 4

1 1 1 1 1

2 1 1 1 1 2
1

2 2 2 2 2
1 1 1

2
1

1 1 1 1 1

0
1 1 0
1 1 1

2 2 2 2 4 2
0 1 2 3

No quedó muy lindo el programa, ¿no?


Por ahora no podemos hacer nada mejor, pero para que lo vayas pensando:
una particularidad de nuestra bandera es su simetría, la franja de arriba es
exactamente igual a la de abajo. Si pudieramos crear un comando que dibuje
la franja celeste nuestro programa quedaría mucho más simple...

Ejercicio 7: Limpiando el jardín


¡Necesitamos podar este jardín!

0 1 2

2 1 1 1 2

2
1 1 1

1 1
2 2 1 1
1 1

0
21 1
21 0
1 1 1

02 1 2 22
Guille se dedica a la jardinería y, aunque no sabemos bien por qué, piensa
que nuestro tablero es un jardín, mejor hagámosle caso así no se enoja.

Con el cabezal en el origen, creá un programa que se encargue de "podar" el tablero


de la imagen: sacar todas las bolitas verdes. Al finalizar, el cabezal debe terminar
donde empezó.

program {
Sacar(Verde)
Mover(Norte)
Sacar(Verde)
Mover(Norte)
Sacar(Verde)
Mover(Este)
Sacar(Verde)
Mover(Este)
Sacar(Verde)
Mover(Sur)
Sacar(Verde)
Mover(Sur)
Sacar(Verde)
Mover(Oeste)
Sacar(Verde)
Mover(Oeste)
}
 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero inicial
0 1 2

2 1 2
1 1 1
1 1

1
12 1 2 2
1 1
1

0
21 1 1
1 21 1
0

0
2 1
2 2
2
Tablero final
0 1 2

2 2
1 1 1

1 1
1 1

0 0
1 1 1

0 1 2

Ejercicio 8: Reemplazar bolitas


¿Ya te estás durmiendo? 
Pasemos a algo un poco más difícil entonces. Te vamos a dar un tablero
de 2x2 (o sea, con 4 celdas) donde cada una de ellas tiene una bolita roja.

Tu tarea es crear un programa que reemplace todas las bolitas rojas por verdes.


 ¡Dame una pista!

La idea de reemplazar una bolita por otra es algo que nosotros, los


humanos, podemos entender.

Por el contrario, Gobstones sólo entiende de Poner y Sacar. Pensá cómo podés


combinar esas operaciones para lograr el efecto deseado.

program{
Sacar(Rojo)
Poner(Verde)
Mover(Este)
Sacar(Rojo)
Poner(Verde)
Mover(Norte)
Sacar(Rojo)
Poner(Verde)
Mover(Oeste)
Sacar(Rojo)
Poner(Verde)}
¡Muy bien! Tu solución pasó todas las pruebas

Inicial
0 1

1 1 1 1

2 2
1 1

0 1 1 0

2
1 1

0 1 2
Final

0 1

1
1
1 1
1 1

2 2
0
1
1 1
0

0
2 1

Procedimientos
Si llegaste hasta acá, entonces ya sabés:

 cómo escribir un programa (program);


 cómo poner y sacar bolitas, usando Poner y Sacar;
 cómo desplazar el cabezal por el tablero, usando Mover.

Como te imaginarás, con estas 3 cosas ya podés resolver muchos problemas:


dibujar banderas de países , escribir tu nombre , hacer un plano de tu casa ,
etc, etc. Pero más temprano que tarde esas herramientas no te van a
alcanzar, y tu programa se va a volver tan complejo que no va a ser fácil
entenderlo. 

¿No nos creés? ¡Acompañanos! 

Ejercicios

  1. ¿De qué se trata?


  2. Un programa un poco largo
  3. Las cosas por su nombre
  4. Enseñándole tareas a la computadora
  5. Procedimientos en acción
  6. Escribiendo procedimientos
  7. Procedimiento, ¡te invoco!
  8. Una definición, "infinitos" usos
  9. Procedimientos dentro de otros
  10. Dibujamos con imaginación
  11. De punta a punta
  12. Rojo al borde
  13. Adornando el tablero
  14. Colores, colores, colores
  15. Cuadrado de colores
¡Terminaste Práctica Primeros Programas!
Todo muy lindo esto de Poner, Mover y Sacar, pero seguro que ya estás
empezando a pensar que te estamos estafando.
¿No era que la programación se trataba de crear cosas y usar la imaginación?
¿Cómo es esto posible si sólo puedo usar unos pocos comandos que pensó
alguien más?
¡No desesperes! En la siguiente guía vamos a dejar un poco de lado
las primitivas para pasar a algo más interesante.

Ejercicio 1: ¿De qué se trata?


Tomate unos minutos (no más de 3 ) para tratar de descubrir qué es lo que
hace el programa a continuación.

program {
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Oeste)
Poner(Negro)
Mover(Oeste)
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
}

1
1 1
1 1 1
1 1 1
¿Lo pensaste? Decinos qué es lo que hace 

Llena cualquier tablero de bolitas negras

Dibuja una línea de bolitas negras

Dibuja una cruz de bolitas negras

Dibuja un cuadrado de bolitas negras

Pone 9 bolitas negras en una celda


 ¡La respuesta es correcta!

Costó un poco, ¿no?

Bueno, eso es normal porque los humanos no somos máquinas  y nos cuesta


ejecutar un programa en nuestra cabeza. ¡Por suerte existen las
computadoras, que se encargan de resolverlo!

Ejercicio 2: Un programa un poco largo


Ahora tenés la posibilidad de ver en acción el programa.

program {
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Oeste)
Poner(Negro)
Mover(Oeste)
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
}

¡Muy bien!

Tablero Inicial

0 1 2 3
3 3

2 2

1 1
1 1

1 1 1
0 0

0 1 2 3

Tablero final
0 1 2 3

3 3

2 1 1 2

1 1
1 1 1
1
1 1 1
0 1 1
0

0 1 2 3

Aunque ahora pudimos probarlo, sigue siendo un poco confuso saber de


qué se trata el programa con solo leerlo ¿no sería mejor si también fuera
fácil de entender para un humano?

Ejercicio 3: Las cosas por su nombre


Mirá esta nueva versión del mismo programa. Aunque todavía hay
elementos de la sintaxis que no conocés, confiamos en que vas a tardar
mucho menos en descubrir qué hace.

Enviá el código, así nos aseguramos de que hace exactamente lo mismo que el


anterior.
procedure DibujarCuadradoNegroDeLado3() {
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Oeste)
Poner(Negro)
Mover(Oeste)
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
}

program {
DibujarCuadradoNegroDeLado3()
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial

0 1 2 3

3 3

2 2
1 1
1 1

1 1 1
0 0

0 1 2 3

Tablero final
0 1 2 3

3 3

2 1 1 2

1 1
1 1 1
1
1 1 1
0 1 1
0

0 1 2 3

Mucho más fácil de entender, ¿no? 

Probablemente te estés preguntando ¿cómo supo la computadora


lo que tenía que hacer DibujarCuadradoNegroDeLado3 ? ¿Qué es
eso de procedure? 

¡Vamos a averiguarlo!

Ejercicio 4: Enseñándole tareas a la


computadora
Como viste en el ejemplo del cuadrado, se puede empezar a diferenciar dos
tipos de comandos dentro de un programa:

 los que vienen definidos por el lenguaje y nos sirven para expresar


operaciones básicas, como Mover, Poner y Sacar. A estos los
llamaremos comandos primitivos, o simplemente primitivas;
 y los que definimos nosotros, que nos sirven para expresar tareas
más complejas. Como el nombre de esta lección sugiere, estos son
los procedimientos.

Cuando definimos un procedimiento estamos "enseñándole" a la


computadora  a realizar una tarea nueva, que originalmente no estaba
incluida en el lenguaje.

 Prestale atención a la sintaxis del ejemplo para ver bien cómo


definimos un procedimiento y cómo lo invocamos en un program.

procedure Poner3Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

program {
Poner3Rojas()
}
¿Qué te parece que hace el nuevo procedimiento?  Copiá y enviá el código para ver
qué pasa.

procedure Poner3Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

program {
Poner3Rojas()
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero inicial
0 1 2

2 2

1
1

0 0

0 1 2
Tablero final
0 1 2

2 2

1
1
0
0
3
0 1 2

Ahora que ya probamos cómo funcionan, podemos ver las diferencias entre
las sintaxis de programas y procedimientos.

El procedimiento se define con la palabra procedure seguida por un nombre


y paréntesis ( ). Luego escribimos entre llaves {} todas las acciones que
incluya. Para ver un procedimiento en acción hay que invocarlo dentro de un
programa, sino sólo será una descripción que nunca se va a ejecutar. 

El programa se crea con la palabra program seguida de llaves {}, y adentro


de ellas lo que queremos que haga la computadora. ¡No lleva nombre ni
paréntesis!

Ejercicio 5: Procedimientos en acción


Si bien las palabras que utilizamos para crear programas (program) y definir
procedimientos (procedure) se escriben parecido son cosas muy distintas.

Cuando creamos un programa nuevo le estamos diciendo a la


computadora lo que queremos que suceda luego de tocar Enviar.
Pero si queremos crear una tarea nueva podemos agrupar las acciones que
requiere en un procedimiento. Los procedimientos se definen con
un nombre que describa lo que hace.

Veamos cómo creamos un nuevo procedimiento llamado PonerVerdeYAzul. 

procedure PonerVerdeYAzul() {
Poner(Verde)
Poner(Azul)
}
La computadora solo va a seguir las instrucciones dentro de un
procedimiento cuando sea invocado dentro de un program. ¿Cómo
lo invocamos? Escribimos su nombre seguido por paréntesis ().
program {
PonerVerdeYAzul()
}

Completá el código para que además de definir el


procedimiento PonerNegroYRojo luego lo invoque en el program.

procedure PonerNegroYRojo() {
Poner(Negro)
Poner(Rojo)
}
program {
PonerNegroYRojo …….
}
Error No paso las pruebas falto paréntesis derecho e izquierdo
antes del cierre con }
procedure PonerNegroYRojo() {
Poner(Negro)
Poner(Rojo)
}
program {
PonerNegroYRojo ()
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial
0 1

1 1

0 0

0 1

Tablero final
0 1

1 1

0 0

0 1

A la hora de definir e invocar procedimientos tenemos que prestar


mucha atención a la sintaxis para no perder de vista el objetivo del
problema por un error de escritura.

Ejercicio 6: Escribiendo procedimientos


Llegó el momento de programar desde cero. ¡No te preocupes!
Como recién estamos empezando, repasemos lo que aprendimos.
A esta altura ya sabemos que para programar siempre tenemos que
tener en cuenta la sintaxis y que para definir nuevos
procedimientos también tenemos reglas:

 empezamos con la palabra reservada procedure;


 elegimos un nombre que lo describa y lo escribimos con
mayúscula seguido de paréntesis ();
 encerramos las acciones que queremos que haga entre
llaves {}.

Entonces, un procedimiento que se mueve cuatro celdas al Norte se


va a definir así:

procedure Mover4AlNorte() {
Mover(Norte)
Mover(Norte)
Mover(Norte)
Mover(Norte)
}

Y si lo queremos utilizar, tenemos que invocarlo dentro


del program escribiendo su nombre tal cual y sin olvidar los
paréntesis() ¡Prestá atención a la sintaxis!

program {
Mover4AlNorte()
}
Definí un procedimiento Poner3Verdes que ponga 3 bolitas verdes
en la celda actual e invocalo en el program.

Procedure Poner3Verdes(){
Poner(Verde)
Poner(Verde)
Poner(Verde)
}
program{
Poner3Verde()
}
Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que escribiste Procedure en lugar de procedure.


¡Recordá que debe comenzar en minúsculas!

 Detalles
No entiendo, ¡necesito ayuda!

procedure Poner3Verdes(){
Poner(Verde)
Poner(Verde)
Poner(Verde)
}
program{
Poner3Verde()
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  program debe utilizar Poner3Verdes
  La solución parece tener un error de tipeo: debe usar Poner3Verdes,
pero usa Poner3Verde. ¿Quizás quisiste decir Poner3Verdes?

Resultados:

[7:3]: El procedimiento "Poner3Verde" no está definido.


procedure Poner3Verdes(){
Poner(Verde)
Poner(Verde)
Poner(Verde)
}
program{
Poner3Verdes()
3
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial 1
0 1

1 1

0 0

0 1

Tablero Final
0 1

1 1

0 0
3
0 1

Resumiendo, en lo que a un procedimiento respecta, se pueden distinguir


dos momentos:
 la definición, que es cuando ponemos procedure Poner3Verdes() y el
bloque de código que especifica qué hace.
 el uso o invocación, que es cuando escribimos Poner3Verdes() en
alguna parte de program (o de otro procedimiento).

Ejercicio 7: Procedimiento, ¡te invoco!


Algo MUY importante es que un procedimiento se define una sola vez y
luego se puede usar todas las veces que necesitemos, como cualquier otro
comando.

Por eso, su nombre debe ser único dentro de todo el programa. Recordá que


la computadora no hace más que seguir órdenes y si existiera más de un
procedimiento con el mismo nombre, no sabría cuál elegir. 

Para facilitarte las cosas, a veces te ofreceremos partes del problema


resuelto, para que sólo tengas que enfocarte en lo que falta resolver. ¿Y
dónde están? Mirá el editor y fijate si encontrás la pestaña Biblioteca . Lo
que aparece en la Biblioteca no hace falta que lo escribas en el código, ¡si
está ahí podés invocarlo directamente! 

¡Vamos a probarlo! Queremos poner 3 bolitas verdes en dos celdas


consecutivas como muestra el tablero:
0 1 2

1 1

0 3 3 0
3 3

0 1 2

Creá un programa que lo haga invocando el procedimiento Poner3Verdes.


Recordá que ya te lo damos definido ¡no tenés que volver a escribirlo!

 Biblioteca
procedure Poner3Verdes() {
Poner(Verde)
Poner(Verde)
Poner(Verde)
}

Solución:
procedure Poner3Verdes() {
Poner(Verde)
Poner(Verde)
Poner(Verde)
}
program{
Poner3Verdes()
}

¡Ups! Tu solución no se puede ejecutar

Ver detalles

Objetivos que no se cumplieron:

  la solución no debe declarar Poner3Verdes


Parece que algo no anduvo bien 
El procedimiento "Poner3Verdes ya está definido en la Biblioteca,
no tenés que volver a escribir su definición.
¡Intentemos de nuevo!
Resultados:
[9:11]: El procedimiento "Poner3Verdes" está definido dos veces:
en (?):1:1 y en (?):9:1.
No entiendo, ¡necesito ayuda!
program{
Poner3Verdes()
}
Tu solución no pasó las pruebas
Se obtuvo un tablero distinto al esperado.
Tablero final obtenido ( mal)

0 1 2

1 1

0 3 0
3 3

0 1 2

SOLUCION CORRECTA

Tablero inicial

0 1 2

1 1

0 0
3 3

0 1 2
Tablero final esperado

0 1 2

1 1
0 0
3 3

0 1 2

program{

Poner3Verdes()

Mover(Este)

Poner3Verdes()

Tablero Final logrado Bien con la casilla donde queda el cursor en


amarillo
0 1 2

1 1

0 3 0
3
3
3

0 1 2

Repasemos:

 Para definir un procedimiento nuevo usamos procedure y le


ponemos un nombre que describa lo que hace seguido por
paréntesis (). A continuación y entre llaves {} lo que
querramos que haga.
 Los procedimientos se definen una sola vez. Si ya están
definidos en la Biblioteca o en alguna parte del código no hay
que volver a hacerlo (no se pueden repetir los nombres,  si se
define un procedimiento más de una vez nuestro programa va
a fallar).
 Para invocar un procedimiento escribimos su nombre (sin
olvidar los paréntesis() al final). ¡Y podemos hacerlo todas las
veces que sean necesarias! 
 Aunque también se escribe entre llaves {},
el program nunca lleva nombre ni paréntesis.

Ejercicio 8: Una definición, "infinitos" usos


Otro procedimiento que ya usamos antes es Poner3Rojas, que pone tres
bolitas rojas en una celda. Te ahorramos el trabajo de escribirlo, si lo buscás
vas a ver que está definido en la Biblioteca. ¡Ahora podés utilizarlo tantas
veces como quieras!

Creá un programa que ponga 9 bolitas rojas en la celda actual


invocando el procedimiento Poner3Rojas todas las veces que sea
necesario.
Para repasar cómo definir e invocar procedimientos, mirá este
video: esta en los videos guardados

Biblioteca

procedure Poner3Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}
 Solución

program{

Poner3Verdes()

Poner3Verdes()

Poner3Verdes()

¡Ups! Tu solución no se puede ejecutar (Me equivoque a propósito)


Objetivos que no se cumplieron:

 program debe utilizar Poner3Rojas

Resultados:

[2:3]: El procedimiento "Poner3Verdes" no está definido.

Solución Valida del programa

program{

Poner3Rojas()

Poner3Rojas()

Poner3Rojas()

}
¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial

0 1

1 1

0 0
1
0

Tablero final

0 1

1 1

0
9
9 0

0 1

No te olvides de revisar las herramientas que nos ofrece la Biblioteca para


saber cuáles podemos aprovechar cuando resolvamos nuestro problema.

Ejercicio 9: Procedimientos dentro de


otros
Cuando creamos procedimientos agrupamos varias acciones en una tarea
que podemos reconocer y nombrar. Eso hace nuestros programas más
claros, legibles y nos ahorra repeticiones innecesarias.

Ya vimos que un procedimiento puede ser invocado tantas veces como


querramos dentro de un programa , pero como su objetivo es agrupar los
pasos de una tarea para usarla cuando haga falta, también lo podemos
invocar dentro de otros procedimientos. ¡Vamos a probarlo!

Definí el procedimiento Poner9Rojas que, utilizando Poner3Rojas,


ponga nueve bolitas rojas en una celda. Una vez definido, invocá el
nuevo procedimiento en un program.
 ¡Dame una pista!
No tenés que volver a definir Poner3Rojas(), recordá que si un
procedimiento está en la Biblioteca y lo querés utilizar solamente
tenés que invocarlo.

Biblioteca

procedure Poner3Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

Solucion
program{
Poner(3Rojas)
Poner(3Rojas)
Poner(3Rojas)
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[2:10]: Se esperaba alguna de las siguientes alternativas:


una coma (",")
un paréntesis derecho (")").
Se encontró: un identificador con mayúsculas.
Solución
program{
Poner3Rojas()
Poner3Rojas()
Poner3Rojas()
}
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:

  program debe utilizar Poner9Rojas
  Poner9Rojas debe utilizar Poner3Rojas
  la solución debe declarar Poner9Rojas
  La solución parece tener un error de tipeo: debe
usar Poner9Rojas, pero usa Poner3Rojas. ¿Quizás quisiste
decir Poner9Rojas?

Resultados de las pruebas:

 Tablero inicial

0 1

1 1

0 0

1
0

 Tablero final

0 1

1 1

0
9
9 0

0 1
Tablero inicial

0 1 2

1 1

0 9 0

0 1 2
Tablero final

0 1 2

1 1

0
9
9 0

0 1 2

Solución
program{
Poner9Rojas()
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  Poner9Rojas debe utilizar Poner3Rojas
  la solución debe declarar Poner9Rojas
  La solución parece tener un error de tipeo: debe usar Poner3Rojas,
pero usa Poner9Rojas. ¿Quizás quisiste decir Poner3Rojas?

Resultados:

[2:3]: El procedimiento "Poner9Rojas" no está definido.

Solución
program Poner9Rojas{
Poner3Rojas()
Poner3Rojas()
Poner3Rojas()
}
¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que llamaste Poner9Rojas a program, pero los program no


llevan nombre.

 Detalles
Resultados:

[1:9]: Se esperaba una llave izquierda ("{").


Se encontró: un identificador con mayúsculas.

Delfina G. MENTORÍA hace 12 días


¡Hola, Isabel Carolina! ¿Cómo va?
Sí, ¡podemos ayudarte! Veamos un poco el ejercicio:
En el mismo nos piden que hagamos un procedimiento que ponga 9 bolitas
rojas; tal como hiciste en tu solución tenemos que crear un procedureque se
llame Poner9Rojas(), pero ¿qué tiene que hacer este procedimiento?
Deberíamos tener dentro del procedimiento todas las tareas necesarias para
que se coloquen 9 bolitas: así, cuando lo llamamos desde nuestro program(),
ya sabe qué es lo que tiene que hacer para cumplir con su tarea. En la
solución planteada, el procedimiento Poner9Rojas()se define de la siguiente
manera:

procedure Poner9Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

Si, acto seguido, desde nuestro program()invocáramos el procedimiento de la


siguiente manera:
program{
Poner9Rojas()
}

Lo que estaríamos logrando es que nuestro programa únicamente coloque 3


bolitas; esto ocurre porque, más allá de que el procedimiento se llame
Poner9Rojas(), la definición del mismo dice que tiene que Poner(Rojo) 3
veces. Por un lado, deberíamos revisar que el procedimiento haga
efectivamente lo que buscamos. Por el otro, el ejercicio además nos pide que
usemos el procedimiento Poner3Rojas() y ¿Como haríamos esto? si desde
nuestro program()pedimos usar ese procedimiento 3 veces de la siguiente
manera:

program{
Poner3Rojas()
Poner3Rojas()
Poner3Rojas()
}

La solución funcionaría pero no estaríamos usando nuestro


procedimiento Poner9Rojas() y esto es lo que nos pide el ejercicio.
Lo que busca con esto es que veamos que desde un procedimiento
también se puede ejecutar las tareas de otro procedimiento. Es
decir, podríamos (y deberíamos) crear un procedimiento que se
llame Poner9Rojas() y dentro de éste se invoque al procedimiento
Poner3Rojas() la cantidad de veces que sea necesario para
conseguir poner las 9 bolitas. Y así luego nuestro program()sólo
tendría que invocar al procedimiento Poner9Rojas() y éste ya sabría
qué hacer. Entonces, en vez de usar Poner(Rojo) en
Poner9Rojas()podríamos intentar usar Poner3Rojas(). ¿Te animás a
probarlo?
Otra resolución

program {
Poner3Rojas()
Poner3Rojas()
Poner3Rojas()
}
procedure Poner9Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}
Me dice que funciona pero tengo que mejorar y ya no se que solucion
darle... ayuda por favor..

Macarena Rocio G. hace 4 meses


¡Hola, Sabrina! ¿Cómo estás? Venís bien, pero hay detalles que revisar. El
resultado hace referencia a que: Tu solución funcionó, pero hay cosas que mejorar.
¿Que quiere decir? Tu solución funciona, pero, No cumplió con todos los
objetivos del ejercicio: ¡Podés darle una vuelta más y mejorarla para que
pase a estar en color verde! Evitar repetir líneas de código siempre que se
pueda, en especial, poné atención sobre las veces que: Poner3Rojas se repite y
si esa repetición es correcta o innecesaria.
¿Es necesario utilizar Poner3Rojas o podríamos, en cambio, aprovechar
Poner9Rojas? ¡Ánimo!

program {
Poner9Rojas()
}
procedure Poner9Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}
 Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:

  Poner9Rojas debe utilizar Poner3Rojas
  La solución parece tener un error de tipeo: debe usar Poner3Rojas, pero
usa Poner9Rojas. ¿Quizás quisiste decir Poner3Rojas?

Resultados de las pruebas


Tablero inicial

0 1 2

1 1

0 9 0

0 1 2
Tablero final

0 1 2

1 1

0
9
9 0

0 1 2

Al pedirnos que invoquemos un procedimiento puede referir a que lo


utilicemos dentro de un procedimiento como de un programa. En este ejercicio
se nos pide que definamos el procedimiento Poner9Rojas invocando el
procedimiento que ya tenemos definido en Biblioteca Poner3Rojas, es decir,
que utilicemos Poner3Rojas dentro de Poner9Rojas. Y finalmente lo que vamos a
invocar en el program va a ser el nuevo procedimiento Poner9Rojas.

Solución Final Resuelta


procedure Poner9Rojas(){
Poner3Rojas()
Poner3Rojas()
Poner3Rojas()
}
program{
Poner9Rojas()
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
Tablero inicial

0 1 2

1 1

0 9 0

0 1 2
Tablero final
0 1 2

1 1

0
9
9 0

0 1 2
Bueno, ya sabemos cómo crear procedimientos, pero ¿por qué querríamos
hacerlos? 

Algunas posibles respuestas:

 para simplificar código, escribiendo una sola vez y en un solo lugar


cosas que vamos a hacer muchas veces;
 para escribir menos, por qué querríamos hacer cosas de más; 
 para que el propósito de nuestro programa sea más entendible para
los humanos, como vimos en el ejemplo
de DibujarCuadradoNegroDeLado3. Para esto es fundamental pensar
buenos nombres, que no sean muy largos
(DibujarCuadradoNegroDeLado3FormadoPor9BolistasDeArribaAAbajo)
, ni demasiado cortos (DibCuaNeg), y sobre todo que dejen en claro
qué hace nuestro procedimiento;
 para comunicar la estrategia que pensamos para resolver
nuestro problema;
 y como consecuencia de todo esto: para poder escribir programas más
poderosos.
Ejercicio 10: Dibujamos con imaginación
Vamos a usar un poco la imaginación y vamos a hacer un procedimiento que
dibuje una "punta" negra en la esquina inferior izquierda de esta forma:

0 1 2

1 1 1

0
0 1 1
1
0 1 2

procedure DibujarPuntaNegra(){
PonerNegro()
}
program{
DibujarPuntaNegra()
Mover(Sur)
DibujarPuntaNegra()
Mover(Este)
DibujarPuntaNegra()
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[2:3]: El procedimiento "PonerNegro" no está definido.

Otra resolución mal

procedure DibujarPuntaNegra(){
Poner(Negro)
}
program{
DibujarPuntaNegra()
Mover(Sur)
DibujarPuntaNegra()
Mover(Este)
DibujarPuntaNegra()
}
Tu solución no pasó las pruebas

El programa hizo BOOM.


BOOM
[7:3]: No se puede mover hacia la dirección Sur: cae afuera del tablero.

Respuesta correcta

Respuesta:

procedure DibujarPuntaNegra(){
  Poner(Negro)
}
program{
  DibujarPuntaNegra()
  Mover(Norte)
  DibujarPuntaNegra()
  Mover(Sur)
  Mover(Este)
  DibujarPuntaNegra()
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial
1
1 2
0 1 2

1 1

0 0

0 1 2

Tablero Final
0 1 2

1 1 1
2

0 1 1 0

0 1 2

Ejercicio 11: De punta a punta


En el ejercicio anterior ya dibujamos una punta, ahora vamos a pensar cómo
aprovechar el procedimiento que hicimos para crear un tablero como este:

0 1 2 3

1
3 3
1

1 1
2 2
1 1
2
1
1 1
1
2
1 1
0 1 0
1
2
2
0 1 2 3

Definí el procedimiento DibujarDosPuntas e invocalo dentro un program.


Acordate de utilizar DibujarPuntaNegra.
Biblioteca
procedure DibujarPuntaNegra() {
Poner(Negro)
Mover(Norte)
Poner(Negro)
Mover(Sur)
Mover(Este)
Poner(Negro)
}

procedure DibujarDosPuntas(){
DibujarPuntaNegra()}
program{
DibujarPuntaNegra)()
Mover(Norte)
DibujarPuntaNegra()
Mover(Sur) Esto esta
Mover(Este) mal incluido por eso dice que la llave
DibujarPuntaNegra() { anterior esta abierta pero nunca
Mover(Este) se cierra
Mover(Norte)
Mover(Norte)
DibujarPuntaNegra()
Mover(Norte)
DibujarPuntaNegra()
Mover(Sur)
Mover(Este)
DibujarPuntaNegra()
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[3:8]: Se encontró una llave abierta "{" pero nunca se cierra.

Esto esta mal porque repito dos veces y complico el ejercicio.


La siguiente es la resolución correcta al poner dos puntas

procedure DibujarDosPuntas() {
  DibujarPuntaNegra()
  Mover(Norte)
  Mover(Norte)
  Mover(Este)
  DibujarPuntaNegra()
}
program{
  DibujarDosPuntas()

SOLUCIÓN
procedure DibujarDosPuntas() {
DibujarPuntaNegra()
Mover(Norte)
Mover(Norte)
Mover(Este)
DibujarPuntaNegra()
}
program{
DibujarDosPuntas()
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial
0 1 2 3

3 3
2 2

1 1
1 1

1 1 1
0 0

0 1 2 3

Tablero Final
0 1 2 3

1
3 3
1

1 1
2 2
1 1
2
1
1 1
1
2
1 1
0 1 0
1
2
2
0 1 2 3

Para resolver este problema lo que hicimos fue separarlo en partes,


identificando las tareas más pequeñas que ya teníamos resueltas. 
Los procedimientos son muy útiles para esto, se ocupan de resolver
una subtarea y nos permiten repetirla o combinarla para solucionar un
problema mayor que la incluya.

Ejercicio 12: Rojo al borde


Ya vimos que los comandos que vienen definidos por el lenguaje se
llaman primitivas. Hay una primitiva que no usaste hasta ahora que
queremos presentarte.

Imaginate que no sabés ni dónde está el cabezal ni qué tamaño


tiene el tablero pero querés llegar a una esquina: La primitiva
Mover no te va a ser de mucha ayuda. 

Por suerte  existe una primitiva  llamada IrAlBorde, que toma una


dirección, y se mueve todo lo que pueda en esa dirección, hasta
llegar al borde.

¿Cómo? Mirá el resultado del siguiente programa:

program {
IrAlBorde(Este)
}

Inicial

0 1 2 3

1 1

0 0

3
0 1 2
Final

0 1 2 3

1 1

0 0

3
0 1 2

¡Vamos a aprovecharlo!

Definí el procedimiento RojoAlBorde que ponga una bolita roja en


la esquina superior izquierda del tablero e invocalo en el program.

 ¡Dame una pista!

En este caso tenés que lograr que el cabezal quede en una esquina,
por lo tanto tenés que pensar en dos bordes: Norte y Oeste. 

program{
Mover(Norte)
IrAlBorde(Oeste)
}
Tu solución no pasó las pruebas. Además no coloque el procedimiento
Objetivos que no se cumplieron:
  program debe utilizar RojoAlBorde
  RojoAlBorde debe utilizar IrAlBorde
Resultados de las pruebas:
  Tablero de 2x3 con el cabezal abajo a la izquierda: Se obtuvo un
tablero distinto al esperado.

Tablero inicial
0 1

2 2

1 1
0 0

0 1

Tablero final esperado


0 1

2 2
1 2

1 1

0 0

0 1

Tablero final obtenido


0 1

2 2

1 1

0 0

0 1

Tablero de 3x3 con el cabezal en el medio: Se obtuvo un tablero distinto al


esperado.

Tablero inicial
0 1 2

2 2
1 1

0 0

2
0 1

Tablero final esperado


0 1 2

2 2 2

1 1

0 0

2
0 1

Tablero final obtenido


0 1 2

2 2

1 1

0 0

2
0 1

Solución con error en la consulta hecha


por otro
procedure RojoAlBorde() {
IrAlBorde(Oeste)
Mover(Norte)
Poner(Rojo)
}

program {
RojoAlBorde()
}
Lautaro Daniel A. hace 9 meses
La solución me da bien en un tablero pero me da mal en el otro.
Cómo hago para mover ambos cabezales de manera distinta?
Guillermo Ignacio B. MENTORÍA hace 9 meses
¡Hola Lautaro! Fijate que estás usando el comando Mover(Norte),
el cual mueve el cabezal una sola posición hacia el Norte, pero la
idea es que se mueva hasta el borde Norte (así como se mueve
hasta el borde Oeste).
La solución perfecta del ejercicio es:

procedure RojoAlBorde() {
IrAlBorde(Oeste)
IrAlBorde(Norte)
Poner(Rojo)
}

program {
RojoAlBorde()
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Tablero de 2x3 con el cabezal abajo a la izquierda

Tablero inicial
0 1

2 2
1 1

0 0

0 1

Tablero final
0 1

2 2
2
1 1

0 0

0 1

Tablero de 3x3 con el cabezal en el medio


Tablero inicial
0 1 2

2 2

1 1

0 0

2
0 1

Tablero final
0 1 2

2 2 2

1 1

0 0

2
0 1

¡Excelente! 
IrAlBorde es una primitiva muy útil para cuando no conocemos las
condiciones de nuestro tablero. 

Ejercicio 13: Adornando el tablero


Para resolver un problema nos conviene comprender bien de qué se trata
para elegir una estrategia. Es el momento de empezar a hacerlo
aprovechando los procedimientos.

Uno de los objetivos al usar procedimientos es identificar y nombrar las


subtareas  que conforman un problema y combinar sus soluciones para
poder resolverlo. Veamos un ejemplo:

Queremos decorar con guirnaldas las dos esquinas superiores


de cualquier tablero como muestra la imagen.
0 1 2 3

2 2
3 3
3 3 3 3
3 3
1 1

0 0

0 1 2 3

Pensemos una estrategia distinguiendo subtareas:

Cada guirnalda se compone de 3 bolitas rojas y 3 bolitas verdes. Ya


resolvimos cómo hacerlo en otros ejercicios , hacer una guirnalda solo
requerirá combinar esas soluciones. Y ponerla donde corresponda, claro.

¿Y que más? el procedimiento que decore el tablero debería poder


aprovechar la creación de una guirnalda para usarla varias veces en las
posiciones que querramos decorar. Nos vendría muy bien alguna primitiva
que nos ayude a llegar a los bordes.

¡Manos a la obra!
Definí dos procedimientos: el procedimiento PonerGuirnalda que coloque 3
bolitas rojas y 3 bolitas verdes en una celda y el
procedimiento DecorarTablero que lo utilice y ponga una guirnalda en cada
esquina superior. Invocá DecorarTablero en el program. Tené en cuenta que
no sabemos la posición inicial donde se encontrará el cabezal.
 ¡Dame una pista!

En la Biblioteca ya tenés definidos procedimientos  que te pueden ayudar.

No te olvides de utilizar IrAlBorde.

biblioteca

procedure Poner3Verdes(){
Poner(Verde)
Poner(Verde)
Poner(Verde)
}

procedure Poner3Rojas(){
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

SOLUCIÓN

procedure PonerGuirnalda(){
Poner3Verdes()
Poner3Rojas()
}
procedure DecorarTablero(){
IrAlBorde(Norte)
IrAlBorde(Oeste)
PonerGuirnalda()
IrAlBorde(Norte)
IrAlBorde(Este)
PonerGuirnalda()
}
program {
DecorarTablero()
}
¡Muy bien! Tu solución pasó todas las pruebas

TABLERO iNICIAL
0 1 2 3

2 2
3 3 3 3

1 1

0 0

0 1 2 3

TABLERO FINAL
0 1 2 3

2 2
3 3
3 3 3 3
3 3
1 1

0 0

0 1 2 3

TABLERO INICIAL
0 1 2 3 4
4 4
3 3

2 2

1 1

0 0

0 1 2 3 4

TABLERO FINAL
0 1 2 3 4

4 3 3 3 3 4

3 3

2 2

1 1

0 0

0 1 2 3 4

Cuanto más complejo sea el problema, más útil nos va a ser pensar una
estrategia y organizar la solución en subtareas ¡y los procedimientos están
para ayudarnos!

Ejercicio 14: Colores, colores, colores


Vamos a darle un poco más de color a todo esto haciendo líneas
multicolores como esta:

1 2
0 3 4

1 1 1 1 1 1 1

2 2 2 1 2 2 2 2 2
1 1
1 1 1 1 1
1
2 1 2 2 2 2 1
2 2 2
0 0

4
0 1 2 3

Como se ve en la imagen, cada celda de la línea debe tener una bolita de


cada color (una roja, una negra, una verde y una azul).

¿Cómo podemos dibujarla? ¿Cuál es la tarea que se repite? ¿Se puede definir
un nuevo procedimiento para resolverla y aprovecharlo para construir nuestra
solución?

Definí un procedimiento DibujarLineaColorida que dibuje una línea


multicolor de cuatro celdas hacia el Este y al finalizarla ubique el
cabezal en la celda inicial. Invocá el nuevo procedimiento en
un program.

Te compartimos este video para ayudarte a elegir buenos nombres


y que tu código más expresivo:

 ¡Dame una pista!

Sería interesante definir un procedimiento que ponga una bolita de


cada color en la celda actual, ¿no?

Procedure DibujarLineaColorida(){ Esta mal pq lo que ponemos es un color

Poner (Verde)

Poner(Azul)

Poner(Roja)

Poner(Negra)}
Procedure Dibujar4Bolitas(){ Esta mal porque se debe definir la consigna
DibujarLineaColorida

IrAlBorde(Norte)Mal

Poner DibujarLineaColorida()Mal

Mover (Este)

Respuesta:

procedure Color(){
  Poner(Rojo)
  Poner(Verde)
  Poner(Negro)
  Poner(Azul)
}
procedure DibujarLineaColorida(){
  Color()
  Mover(Este)
  Color()
  Mover(Este)
  Color()
  Mover(Este)
  Color()
  IrAlBorde(Oeste)
}
program{
  DibujarLineaColorida()
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

Tablero inicial

0 1 2 3
3 3

2 2

1 1

0 0

0 1 2 3
Tablero final

0 1 2 3

3 3

2 2

2 2 2 2 2 2 22 2
1 1
2 2 2 2 2 2 2

0 0

0 1 2 3

Tablero inicial

0 1 2 3 4

1 1
0 0

4
0 1 2 3

Tablero final

0 1 2 3 4

2 2 2 2 2 2 2 2
1 1
2 2
2 2 2 2 2 2

0 0

4
0 1 2 3

2 2 2 2
2 2 2
2
2
2 2 2 2 2
2 2 2
2
2 2 2
2 2 2 2

2 2
2
2
2
2
2
2

2 2

Ejercicio 15: Cuadrado de colores


Vamos a crear un procedimiento que nos permita dibujar un tablero como
este:

0 1 2 3 4

4 4

1 1 1 1 1

2 2 1 2 1 2 1 2
3 3
1 1 1 1 1 1 1 1

2
2

1 1 1 1 1 1 1 1

1 1
1 1 1 1 1 1 1 1

1 1 1 1 1

2 2 1 2 1 2 1 2
0 0
1 1

2 2 1 1 1 1 1 1

0 1 2 3 4
Definí un procedimiento DibujarCuadradoColorido que dibuje un
cuadrado de 4×4 celdas en el que cada celda tenga una bolita de
cada color e invocalo en el program. El cabezal debe quedar en la
celda inicial.

Si querés repasar las diferencias entre programas y procedimientos podés


ver este video:

¡Dame una pista!

En la Biblioteca tenés el procedimiento DibujarLineaColorida que hiciste en el


ejercicio anterior, ¡no tenés que volver a definirlo! 

Biblioteca

procedure DibujarLineaColorida() {
PonerCeldaColorida()
Mover(Este)
PonerCeldaColorida()
Mover(Este)
PonerCeldaColorida()
Mover(Este)
PonerCeldaColorida()
IrAlBorde(Oeste)
}

procedure PonerCeldaColorida() {
Poner(Verde)
Poner(Rojo)
Poner(Negro)
Poner(Azul)
}
procedimiento DibujarLineaColorida del ejercicio anterior

procedure Color(){
  Poner(Rojo)
  Poner(Verde)
  Poner(Negro)
  Poner(Azul)
}
procedure DibujarLineaColorida(){
  Color()
  Mover(Este)
  Color()
  Mover(Este)
  Color()
  Mover(Este)
  Color()
  IrAlBorde(Oeste)
}
program{
  DibujarLineaColorida()
}

Solución
procedure DibujarCuadradoColorido(){
DibujarLineaColorida()
Mover(Norte)
DibujarLineaColorida()
Mover(Norte)
DibujarLineaColorida()
Mover(Norte)
DibujarLineaColorida()
IrAlBorde(Sur)
}
program {DibujarCuadradoColorido()
}
 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero inicial

0 1 2 3

3 3

2 2

1 1

0 0

3
0 1 2

Tablero final(Todas las celdas llenas con las 4 bolitas en cada una de
colores:Azul-Negra-Verde y Roja

Tablero Final

0 1 2 3

3 2 2 2 2 3
2 2 2 2 2 2

2 2

1 1

0 2 2 2 2 2 2 0
2 2 2 2 2 2
3
0 1 2

A diferencia de la guía anterior, donde sólo usamos comandos que venían


con Gobstones, en esta lección aprendiste a crear tus propios comandos . Y
eso es lo más lindo de programar, poder inventar tus propias tareas para
resolver los problemas. 

Esta poderosa herramienta nos va a permitir reutilizar más código, ya que


al usar un procedimiento podremos descomponer un problema en
subproblemas más pequeños y manejables. 

Repetición Simple
Como te contábamos cuando empezaste, programar nos da un gran
poder: nos permite automatizar tareas repetitivas y tediosas.

¿Y qué quiere decir eso de "repetitivas"? Pensemos, por ejemplo, cómo


haríamos un programa que ponga 5 bolitas azules:

program {
Poner(Azul)
Poner(Azul)
Poner(Azul)
Poner(Azul)
Poner(Azul)
}

¿Notás qué es lo que se repite? Sí, estamos haciendo 5 veces lo mismo:


poner una bolita azul. Sin dudas, sería mucho más interesante que la
computadora hiciera eso por nosotros... ¡o si no te estaríamos mintiendo con
lo de automatizar!

En esta guía vamos a aprender cómo decirle a la computadora que repita


varias veces lo mismo, y también algunos trucos más.
Ejercicios

  1. MoverOeste10
  2. La computadora repite por nosotros
  3. MoverOeste5 usando repeat
  4. No todo es repetir
  5. También vale después
  6. Repitiendo varios comandos
  7. ¿Dónde está el error?
  8. Diagonal con una bolita
  9. Diagonal "pesada"
  10. El caso borde
  11. De lado a lado, dibujamos un cuadrado

Ejercicio 1: MoverOeste10
Entremos en calor: definí un procedimiento MoverOeste10 que mueva el cabezal 10 veces
hacia el Oeste.
 ¡Dame una pista!

Todavía no te dimos ninguna herramienta nueva, así que vas a tener que
resolverlo con lo que sabés hasta ahora. Y sí, es bastante fea la solución que
podés hacer. 

procedure MoverOeste10(){
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
}
program{MoverOeste10()}
¡Ups! Tu solución no se puede ejecutar Esta mal por agregarle esto

Resultados:
[15:1]: Ya había un programa definido en (?):13:1.
No se puede definir un programa en (?):15:1.

¡Muy bien! Tu solución pasó todas las pruebas


Tablero inicial

0 1 2 3 4 5 6 7 8 9 10

1 1

0 0

0 1 2 3 4 5 6 7 8 9 10
Tablero final

0 1 2 3 4 5 6 7 8 9 10

1 1

0 0

0 1 2 3 4 5 6 7 8 9 10

¿Te imaginás cómo hacer lo mismo pero 20, 100 o 5000 veces? Sería
bastante molesto, ¿no?

Evidentemente tiene que haber una forma mejor de hacerlo, si no eso de


"automatizar tareas repetitivas" sería una mentira. Y bueno, de hecho la hay:
¡vayamos al siguiente ejercicio!

Ejercicio 2: La computadora repite por


nosotros
Como te adelantamos en el ejercicio anterior, en Gobstones existe una forma
de decir "quiero que estos comandos se repitan esta cantidad de veces".

Entonces, cuando es necesario repetir un comando


(como Mover, Poner, DibujarLineaNegra, etc) un cierto número de veces, en
lugar de copiar y pegar como veníamos haciendo hasta ahora, podemos
utilizar la sentencia repeat.

Sabiendo esto, así es como quedaría MoverOeste10 usando repeat:


procedure MoverOeste10() {
repeat(10) {
Mover(Oeste)
}
}
Pero no tenés por qué creernos: ¡escribí este código en el editor y fijate si funciona!

¡Muy bien! Tu solución pasó todas las pruebas


Tablero inicial

0 1 2 3 4 5 6 7 8 9 10

1 1

0 0

0 1 2 3 4 5 6 7 8 9 10
Tablero final

0 1 2 3 4 5 6 7 8 9 10

1 1

0 0

0 1 2 3 4 5 6 7 8 9 10

Ahora sí se empieza a poner interesante esto de la programación.

Ejercicio 3: MoverOeste5 usando


repeat
Llegó tu turno de nuevo: definí un procedimiento MoverOeste5 que se
mueva 5 veces al Oeste.
Obvio, esta vez tenés que usar repeat.

 ¡Dame una pista!

El código del ejercicio anterior puede ayudarte un poco 


procedure MoverOeste10() {
repeat(10) {
Mover(Oeste)
}
}

Solución

procedure MoverOeste5() {
repeat(5) {
Mover(Oeste)
}
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial

0 1 2 3 4 5

1 1

0 0

0 1 2 3 4 5
Tablero final

0 1 2 3 4 5

1 1

0 0

0 1 2 3 4 5

Como ya descubriste, el comando repeat consta básicamente de dos


elementos:

Un número entero (o sea, sin decimales), que indica cuántas veces hay que
repetir. Este número va entre paréntesis (()) luego de la palabra repeat.
Y un bloque de código, que va encerrado entre llaves ({}) y especifica qué
comandos se quieren repetir. Es MUY importante que no te los olvides,
porque sino la computadora no va a saber qué es lo que quisiste repetir (y
fallará ).

Ejercicio 4: No todo es repetir


Los ejemplos que hiciste en los ejercicios anteriores se solucionaban
simplemente repitiendo cosas. Pero no todo es repetir, también podemos
poner comandos tanto antes como después del repeat, al igual que veníamos
haciendo hasta ahora.

Por ejemplo, este es un programa que se mueve al Sur, luego pone 4 bolitas


de color Rojo y por último vuelve a moverse al Norte:

program {
Mover(Sur)
repeat(4) {
Poner(Rojo)
}
Mover(Norte)
}

Fijate que Mover(Sur) lo
pusimos antes del repeat y Mover(Norte) lo pusimos después. Por
lo tanto cada movimiento se ejecuta solo una vez. Teniendo en
cuenta esto:

Definí el procedimiento Poner3AlNoreste(), que ponga 3 bolitas


negras en la primera celda al Noreste del cabezal.
Tablero inicial

0 1 2

2 2

1 1

0 0

2
0 1

Tablero final

0 1 2

2 2

1 1

0 0

2
0 1

 ¡Dame una pista!

Recordá que no existe la dirección Noreste  en Gobstones, pero si


tenemos Norte y Este.

procedure MoverNoreste3(){
Mover(Norte)
repeat(3){
Poner(Negra)
}
Mover(Este)
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  Poner3AlNoreste debe usar repeat
  la solución debe declarar Poner3AlNoreste
Problemas que encontramos:

 Parece que escribiste Negra. ¿Quisiste referirte al color Negro?

 Detalles
No entiendo, ¡necesito ayuda!

Solución Valida
procedure Poner3AlNoreste(){

Mover(Norte)

Mover(Este)

repeat(3){

Poner(Negro)

 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero inicial
0 1 2 3

3 3

2 2

1 1

0 0

0 1 2 3

Tablero final
0 1 2 3

3 3

2 2

1 1

0 0

0 1 2 3

¿Viste qué importante es definir bien qué comandos hay que repetir y cuáles
no?

Es muy común, al principio, olvidarse de colocar las llaves o incluso pensar


que no son importantes. Pero tené mucho cuidado: poner las llaves en el
lugar erróneo puede cambiar por completo lo que hace tu programa. Mirá
qué distinto sería el resultado si hubieras puesto el Mover(Este) adentro
del repeat:

procedure Poner3AlNoreste() {
Mover(Norte)

repeat(3) {
Mover(Este)
Poner(Negro)
}
}

0 1 2 3

3 3
2 2

1 1 1
1 1

0 0

3
0 1 2

Ejercicio 5: También vale después


Definí el procedimiento PonerAzulLejos, que coloque una bolita Azul 4 celdas
hacia el Este:
0 1 2 3 4

1 1

0 0

0 1 2 3 4

0 1 2 3 4

1 1 1

0
2 0

0 1 2 3 4

¡Dame una pista!

Como te dijimos, también es posible ejecutar comandos después del repeat.

Procedure PonerAzulLejos() {
repeat (4){
Mover(Este)
Mover(Este)
Mover(Este)
Mover(Este)
Poner(Azul)
}
}
Program PonerAzulLejos()
¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que escribiste Procedure en lugar de procedure. ¡Recordá que debe


comenzar en minúsculas!
 Parece que escribiste Program en lugar de program. ¡Recordá que debe
comenzar en minúsculas!

procedure PonerAzulLejos() {
repeat (4){
Mover(Este)
Mover(Este)
Mover(Este)
Mover(Este)
Poner(Azul)
}
}
program PonerAzulLejos()
¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que llamaste PonerAzulLejos a program, pero los program no llevan


nombre.

procedure PonerAzulLejos() {
repeat (4){
Mover(Este)
Mover(Este)
Mover(Este)
Mover(Este)
Poner(Azul)
}
}
program {
Repeat(4)
Mover(Este){
Poner(Azul)}
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[17:1]: Ya había un programa definido en (?):10:1.


No se puede definir un programa en (?):17:1.

procedure PonerAzulLejos() {
repeat (4){
Mover(Este)
Mover(Este)
Mover(Este)
Mover(Este)
Poner(Azul)
}
}
Tu solución no pasó las pruebas

El programa hizo BOOM.

SOLUCIÓN VALIDA
procedure PonerAzulLejos(){
repeat(4){
Mover(Este)
}
Poner(Azul)
}
¡Muy bien! Tu solución pasó todas las pruebas
Tablero Inicial

0 1 2 3 4

1 1

0 0

0 1 2 3 4

Tablero Final

0 1 2 3 4

1 1 1

0
2 0

0 1 2 3 4

Como ya experimentaste, pueden ponerse comandos tanto antes como


después del repeat. En definitiva... ¡es sólo un comando más!

Ejercicio 6: Repitiendo varios


comandos
Hasta el momento los ejemplos que vimos sólo repetían un comando, pero
como mencionamos al comenzar es posible repetir cualquier secuencia de
comandos - en definitiva lo que se repite es un bloque y, como ya sabíamos,
en un bloque puede haber tantos comandos como se nos ocurra.

Miremos el código de DibujarLineaNegra6 que podríamos haber hecho sin


usar repeat, con algunos espacios en blanco para ayudarnos a reconocer la
secuencia que se repite:

procedure DibujarLineaNegra6() {
Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)
}

¿Notás qué es lo que se repite y cuántas veces? Bueno, eso es lo que tenés
que poner en el repeat.

Definí una versión superadora de DibujarLineaNegra6, esta vez


usando repeat.

 ¡Dame una pista!

Acordate que para escribir un repeat tenés que pensar dos cosas:


 Qué secuencia de comandos se repite. En este caso la secuencia
consta de varios comandos, eso es lo que tenés que poner entre las
llaves ({}) del repeat.
 Cuántas veces se repite esta secuencia. Eso va entre los paréntesis (())
que van luego de la palabra repeat; y como sabemos que sabés contar
no te vamos a decir qué poner. 

procedure DibujarLineaNegra6(){
repeat(6){
Mover(Este)
}
Poner(Negro)
}
Tu solución no pasó las pruebas

Se obtuvo un tablero distinto al esperado.

Tablero Inicial
0 1 2 3 4 5 6

1 1

0 0

6
0 1 2 3 4 5

Tablero final esperado


0 1 2 3 4 5 6

1 1

0 0
1 1 1 1 1 1
6
0 1 2 3 4 5

Tablero Final Obtenido


0 1 2 3 4 5 6

1 1

0 0

6
0 1 2 3 4 5
procedure DibujarLineaNegra6( ) {
repeat(6) {
Poner(Negro)
Mover(Este) }
}
program { DibujarLineaNegra6()
}
Me da error y el mensaje dice: "Resultados: [9:1]: Ya había un programa
definido en (?):6:1. No se puede definir un programa en (?):9:1." No entiendo
que tengo que hacer, si alguien puede ayudarme por favor, gracias!

No se debe definir program, no lo pide

La repetición es una herramienta de programación que nos permite


automatizar la repetición de alguna tarea indicando el número de veces
consecutivas que deseamos hacerla.
La palabra reservada para la repetición simple es repeat, y va seguida por el
número de repeticiones entre paréntesis y los comandos a repetir entre
llaves. Por ejemplo si quisieramos colocar 5 bolitas azules en la posición
actual del cabezal podríamos hacer:
program{
Poner(Azul)
Poner(Azul)
Poner(Azul)
Poner(Azul)
Poner(Azul)
}

O podríamos hacerlo de una manera más clara y escribiendo menos código


de la siguiente forma utilizando la estructura de repetición repeat:

program{
repeat(5){
Poner(Azul)
}
}
Lo que debemos hacer en este ejercicio es precisamente utilizar repeat para
no repetir código, la clave aquí está en encontrar qué secuencia de
comandos se repite (eso es lo que tenés que poner entre las llaves {} del
repeat) y cuántas veces se repite esta secuencia (eso va entre los paréntesis
( ) que van luego de la palabra repeat)
Espero haberte ayudado
Saludos

Solución
procedure DibujarLineaNegra6( ) {
repeat(6) {
Poner(Negro)
Mover(Este) }
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial
0 1 2 3 4 5 6

1 1

0 0

6
0 1 2 3 4 5

Tablero final esperado


0 1 2 3 4 5 6

1 1

0 0
1 1 1 1 1 1
6
0 1 2 3 4 5

Ejercicio 7: ¿Dónde está el error?


Esta solución para LineaRoja4 no resuelve el problema como esperábamos,
mirá:
Tablero inicial Lo que hace Lo que esperábamos

0 1 0 1 0 1

4 4 4 4 4 4
1

3 3 3 3 3 3
1 1

2 2 2 2 2 2
1 1

1 1 1 1 1 1
1 1

0 0 0 0 0 0
1

0 1 0 1 0 1

procedure LineaRoja4() {
repeat(4) {
Mover(Norte)
Poner(Rojo)
}
}
¿Nos ayudás a corregirla? Te dejamos el código en el editor.
 ¡Dame una pista!

Si te perdiste y querés volver a la solución inicial, podés


presionar "Reiniciar" dentro del editor.

SOLUCION VALIDA
procedure LineaRoja4() {
repeat(4) {
Poner(Rojo)
Mover(Norte)
}
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial

0 1

4 4

3 3

2 2

1 1

0 0

0 1
Tablero final

0 1

4 4

3 3
1 1
2 2
1
1
1 1
1
1
0 0
1 1
1
0

¡Bien, corregiste el error! No fue tan fácil de encontrar, ¿no?  Ahora ya


sabemos que el orden dentro de un repeat también importa, y mucho.

Ejercicio 8: Diagonal con una bolita


Definí un procedimiento Diagonal4Azul que dibuje una diagonal de longitud 4
hacia el Noreste, donde cada celda tenga una bolita azul. El cabezal debe
quedar donde muestra la imagen.
0 1 2 3 4

4 4

1
3 3
1
1
2 2
1
1
1 1

1
0 1 0

0 1 2 3 4

SOLUCION VALIDA
procedure Diagonal4Azul(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial
0 1 2 3 4

4 4

3 3

2 2

1 1

0 0

0 1 2 3 4

TABLERO FINAL
0 1 2 3 4

4 4

1
3 3
1
1
2 2
1
1
1 1 1
1
0 1 0

0 1 2 3 4

Ejercicio 9: Diagonal "pesada"


Ahora vamos a hacer lo mismo, pero en versión "pesada".

¿Qué quiere decir esto? Que en vez de poner 1 bolita en cada celda, ahora
hay que poner 21. Mirá la imagen:

0 1 2 3 4

4 4

3 3
2
1

2 2 2

1 2 1

0 2 0

0 1 2 3 4

Definí un procedimiento DiagonalPesada4Azul que resuelva el problema.

 ¡Dame una pista!

A diferencia del anterior, ahora lo que tenés que hacer en cada celda es más
complejo (tenés que hacer más que un simple Poner(Azul)).

Y, como realmente queremos que aprendas a dividir tu problema en


subtareas, es importante que en tu solución no anides estructuras de
repetición.
procedure DiagonalPesada4Azul(){
repeat(4){
procedure CeldaAzul21( ) {
repeat(21)
{
Poner(Azul)
Mover(Este)
Mover(Norte) }
}
}
}
 ¡Ups! Tu solución no se puede ejecutar
Resultados:

[3:5]: Se esperaba un comando.


Se encontró: la palabra clave "procedure".

procedure DiagonalPesada4Azul(){
repeat(4){
DibujarCeldaAzul21() {
repeat(21)
{
Poner(Azul)
Mover(Este)
Mover(Norte) }
}
}
}
 ¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  Hay que dividir en subtareas. Intentá crear un procedimiento que


ponga 21 bolitas azules y luego invocalo en DiagonalPesada4Azul.

Resultados:

[3:5]: El procedimiento "DibujarCeldaAzul21" no está definido.


procedure DiagonalPesada4Azul(){
repeat(4){
procedure DibujarCeldaAzul(){
CeldaAzul ( ) {
Poner(Azul)
repeat(21)
Mover(Este)
Mover(Norte) }
}
}
}

procedure DiagonalPesada4Azul(){
repeat(4){
procedure DibujarCeldaAzul(){
CeldaAzul ( ) {
Poner(Azul)
repeat(21)
Mover(Este)
Mover(Norte) }
}
}
}

¡Ups! Tu solución no se puede ejecutar


Resultados:

[3:5]: Se esperaba un comando.


Se encontró: la palabra clave "procedure".

Una solución en la consulta pero "Tu solución


funcionó, pero hay cosas que mejorar."
procedure DiagonalPesada4Azul() {
repeat(21)
{Poner(Azul) }
repeat(3)
{Mover(Norte)
Mover(Este)
repeat(21)
{Poner(Azul)
}
}

Mover(Norte)
Mover(Este)
}
Diego Damian A. hace 14 días
lo que te dice es que en vez de repetir tanto podes hacer dos procesos uno
para la repeticion de las bolitas y otro para el movimiento llamando a las
bolitas
Diana L.  MENTORÍA  hace 13 días
¡Buenas Camila! ¿Cómo te va?
Como menciona Diego, lo que nos está diciendo es que tenemos una
repetición de lógica que podríamos resolver usando un procedimiento
aparte. Nos dice también que podríamos tener un procedimiento que se
encargue de poner las 21 bolitas azules, este mismo vamos a poder
invocarlo dentro de DiagonalPesada4Azul, ¿te animás a hacerlo?
¡Saludos!

Otra resolución que tuvo observación:

procedure DiagonalPesada4Azul (){


repeat(21){
Poner(Azul)
}
repeat(3){
Mover(Norte)
Mover(Este)
repeat(21){
Poner(Azul)
}
}
Mover(Norte)
Mover(Este)
}
Yamil J. hace 9 días
Con ésta solución llego al resultado pero me dice que hay cosas que
mejorar. No logro darme cuenta como puedo hacer más simple el último
paso de poner el cabezal al final. Saludos!!
Norman Adrian M. hace 9 días
en resultados te dice: crear un procedimiento que ponga 21 bolitas azules ...y
despues lo llamas en el program y ademas podes hacer este punto con un
solo repeat
Norman Adrian M. hace 9 días
perdon no es necesario aqui usar program...solo otro procedure.. procedure
Poner21Azul(){ repeat(21){ Poner(Azul) } } separar un poco el codigo nomas
seria...y el resto del codigo en DiagonalPesada4Azul()
No me funciona como decis

Natalia Susana C. hace 8 días


¡Hola Yamil! ¿Cómo estás? Veamos que sugiere Mumuki...
Objetivos que no se cumplieron:
 Hay que dividir en subtareas. Intentá crear un procedimiento que
ponga 21 bolitas azules y luego invocalo en DiagonalPesada4Azul.
 Parece que hay lógica repetida que podrías eliminar utilizando repeat.
¡Probablemente lo tengas que usar en más de un lugar!
Al parecer ambos hacen referencia a lo mismo.. fijate en la solución que
propones, esta porción de código:

repeat(21){
Poner(Azul)
}

¿La ves repetida en tu código?


Lo que te sugiere la plataforma, es que a la porción de codigo repetida, la
extraigas en un nuevo procedimiento, asi cuando la tenes que usar
nuevamente, no tenés que escribir toda esa funcionalidad otra ves, sino, solo
basta con invocar a este nuevo procedimiento que ya tiene definida esta
porción de código.
Espero te halla sido útil.
Otra solución con error:
procedure BolitaAzul(){repeat(21){Poner(Azul)}}
procedure DiagonalPesada4Azul()
{BolitaAzul()Mover(Este)Mover(Norte)BolitaAzul()Mover(Este)Mover(Norte)Bo
litaAzul()Mover(Este)Mover(Norte)BolitaAzul()
{IrAlBorde(Este)IrAlBorde(Norte)}}

Halty C. hace 17 días


procedure BolitaAzul(){repeat(21){Poner(Azul)}} procedure
DiagonalPesada4Azul()
{BolitaAzul()Mover(Este)Mover(Norte)BolitaAzul()Mover(Este)Mover(Norte)Bo
litaAzul()Mover(Este)Mover(Norte)BolitaAzul()
{IrAlBorde(Este)IrAlBorde(Norte)}}
Entiendo que es esto lo que tengo que hacer y me da bien el resultado, pero
al no usar el comando repeat NO está aprobado y lo entiendo. Pero no
puedo solucionarlo
Erika B. hace 17 días
Hola, Halty.
BolitaAzul()Mover(Este)Mover(Norte)BolitaAzul()Mover(Este)Mover(Norte)Bol
itaAzul()Mover(Este)Mover(Norte) ¿Acá no estás repitiendo todo el tiempo lo
mismo? ¿No te convendría usar repeat?
En vez de poner todo ese texto, podés poner
repeat (numero que necesites, contalo) {BolitaAzul () Mover (Norte) Mover
(Este)}
Maria Emilia W.  MENTORÍA  hace 16 días
Hola Halty, ¡Venís muy bien! El comando repeat se utiliza cuando tenemos
varias acciones iguales que se repiten de manera consecutiva. Por ejemplo,
en tu caso, tenes tres que se repiten de esa manera: BolitaAzul() , Mover(Este) y
Mover(Norte). Como lo hacen 3 veces, es la cantidad de veces que necesitas
que el comando repeat(veces que repite) se ejecute. Entonces con su sintaxis
correcta, quedaría de la siguiente manera:

repeat(3) {
BolitaAzul()
Mover(Este
Mover(Norte)
}

Ojo, tené en cuenta que en tu tablero contenes 4 celdas llenas con bolitas.
Recordá, además, que tanto un procedure, como un repeat o un program inician y
finalizan con llaves {} . Dentro de esas llaves, es dónde se escribe nuestro
código. Reveé el tuyo y fijate que no es necesario colocar las llaves que
contienen a IrAlBorde(Este) e IrAlBorde(Norte). Si te sirve de ayuda, te invito a que
cuando realices los ejercicios, escribas un código por línea. Esto te lo
recomiendo para poder organizarte mejor, tanto en la sintaxis y para
observar las acciones que realizan cada uno.
Otro resultado a mejorar:
procedure DiagonalPesada4Azul(){
repeat(21){
Poner(Azul)
}
Mover(Norte)
Mover(Este)
repeat(21){
Poner(Azul)
}
Mover(Norte)
Mover(Este)
repeat(21){
Poner(Azul)
}
Mover(Norte)
Mover(Este)
repeat(21){
Poner(Azul)
}
Mover(Norte)
Mover(Este)
}
Valentin A. hace 22 días
Buenas noches, me dice que esta bien pero puedo mejorar, y no entiendo
que lo que tendria que agregar o modificar
Gaston P.  MENTORÍA  hace 22 días
¡Hola Valentín!
El resultado sugiere que crees un nuevo procedimiento encargado de
colocar las 21 bolitas azules. Este nuevo procedimiento evitaría lógica
repetida, suplantando repeat() demás, y dando una mayor distribución de
subtareas a los procedimientos del ejercicio.
Como el resultado menciona, es necesario crear un procedimiento que
coloque 21 bolitas azules. Dentro de este nuevo procedimiento, sería ideal
hacer uso de un único repeat(). Una vez creado este procedimiento, podrás
notar que no sería necesario ningún otro repeat().

Daniela M.  MENTORÍA  hace 22 días


Hola Valentin ¿Como estas? ¡Estas cerca! Fijate que ya hiciste un repeat para
las 21 pelotitas, que esta perfecto pero como dice la solucion hay dos cosas
mas que podemos mejorar: 1- Dividir en subtareas. O sea crear un
procedimiento para poder evitar repetir codigo, asi lo escribimos una sola
vez cuando la llamemos y ya esta. 2- Usar otro repeat para que no tengamos
que escribir todas las veces que debemos hacer cierta/s accion/es seguida/s.
Entonces... ¿Que podemos dividir o separar? Lo que se esta repitiendo
dentro del codigo que escribimos ¿Y que seria eso? Bueno, lo que
repetimos es poner las bolitas y mover despues. Ese podria ser un
procedimiento. ¿Es el unico posible? No, para nada. Otro podria ser, solo la
parte de moverse. Otro, la parte de poner las 21 bolitas. Todo eso se repite,
por lo que crear un procedimiento para poder reducir un conjunto de lineas
en una sola es una gran mejora. Por lo que un codigo asi, que es super largo:

procedure Ejemplo (){


Poner (Azul)
Poner (Verde)
Poner (Rojo)
Mover (Sur)
Poner (Azul)
Poner (Verde)
Poner (Rojo)
Mover (Oeste)
Poner (Azul)
Poner (Verde)
Poner (Rojo)
Mover (Este)
Mover (Este)
Poner (Azul)
Poner (Verde)
Poner (Rojo)
Mover (Norte)
Mover (Norte)
}

Podemos mejorarlo a lo siguiente, con tan solo separar la parte de poner


bolitas que se repite varias veces:

procedure PonerBolitas(){
Poner (Azul)
Poner (Verde)
Poner (Rojo)
}
procedure Ejemplo (){
PonerBolitas ()
Mover (Sur)
PonerBolitas ()
Mover (Oeste)
PonerBolitas ()
Mover (Este)
Mover (Este)
PonerBolitas ()
Mover (Norte)
Mover (Norte)
}

Bueno, todo bien pero ¿Que pasa con el repeat? Bueno, lo que se repite
serian poner las bolitas y moverse. Ahora sabiendo todo eso, ¿Te animas a
intentarlo de nuevo? ¡Estas reeee cerca! Porque el ejercicio funciona, solo
hay cositas que se podrian implementar.
Otra resolución explicada de los errores y como solucionarlo:
procedure DiagonalPesada4Azul() {
repeat(21){
Poner(Azul)
}
repeat(3) {
Mover(Norte)
Mover(Este)
repeat(21){
Poner(Azul)
}
}
}
Buenas. no puedo solucionar este problema...si alguien me podria ayudar. Me dice
que debo crear un procedimiento que subdivida las tareas.
Lara F. hace 10 meses
¡Hola, Héctor! Las subtareas nos sirven para facilitar la resolución de problemas y evitar
repetir código. En este caso, hay líneas que se repiten (línea 2-3 y línea 8-9) que es la parte
que coloca 21 bolitas azules, entonces lo que podemos hacer es crear un nuevo
procedimiento que se encargué exclusivamente de hacer ese paso de colocar las bolitas. A
ese procedimiento lo podemos llamar Poner21Azules (¡o con el nombre que vos quieras!)
para luego utilizarlo en DiagonalPesada4Azul

SOLUCION CORRECTA DEL EJERCICIO


procedure Bolitas(){
  repeat(21){
    Poner(Azul)
 }
}
procedure DiagonalPesada4Azul(){
  repeat(4){
    Bolitas()
    Mover(Norte)
    Mover(Este)
  }
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Con el cabezal en el origen

Tablero Inicial

0 1 2 3 4

4 4

1
3 3

1
2 2

1
1 1

0 0

0 1 2 3 4

Tablero final
0 1 2 3 4

4 4

3 3
2
1

2 2

1 2 1

0 2 0

0 1 2 3 4

Con el cabezal desplazado


Tablero inicial

0 1 2 3 4 5

4 4

3 3

2 2

1 1

0 0

0 1 2 3 4 5

Tablero final

0 1 2 3 4 5

4 4

3 2 3

2 2 2

1 2 1
0 0

0 1 2 3 4 5

Muy bien. Aunque el repeat es poderoso y nos ayuda a escribir menos código,
sigue siendo igual de importante la división en subtareas.

¡No vale olvidarse de lo aprendido hasta ahora!

Ejercicio 10: El caso borde


Muchas veces cuando usamos un repeat nos encontramos con que el último
caso es levemente distinto a los anteriores, situación que solemos
llamar caso borde. Pero mejor, veamos un ejemplo.

El procedimiento LineaNegra4Este que te presentamos dibuja una línea negra


hacia el Este dejando el cabezal fuera de la línea, una celda hacia el Este.

procedure LineaNegra4Este() {
repeat(4) {
Poner(Negro)
Mover(Este)
}
}

Si ahora queremos hacer que deje el cabezal en la última celda de la línea,


tenemos dos opciones:

 Mover el cabezal al Oeste luego de dibujar la línea. Un truco medio


feo, porque para funcionar necesita que haya al menos 5 espacios al
Este de la posición inicial, cuando nuestra línea sólo ocupará 4.
 Tratar el último caso de manera especial. Esta opción es más
interesante y más fiel a lo que queremos hacer: la última vez no
queremos que el cabezal se mueva, simplemente nos basta con poner
la bolita negra.

0 1 2 3

1 1
1 1 1 1
0 0

0 1 2 3
Teniendo en cuenta esto último, definí una nueva versión de LineaNegra4Este que deje el
cabezal en la última celda de la línea.

¡Dame una pista!

Algunos ejercicios atrás comprobaste que se pueden poner cosas


tanto antes como después de un repeat. Podés usar esa misma idea para
tratar el último caso de manera especial, sacándolo del repeat.

Ojo: al "sacar un caso para afuera" también vas a tener que reducir el
número de veces que repetís los otros casos. 

procedure LineaNegra4Este() {
Poner(Negro)
Mover(Este)
repeat(3) {
Poner(Negro)
Mover(Este)
}
}

Tu solución no pasó las pruebas


Resultados de las pruebas:

  Con lugares de sobra


Se obtuvo un tablero casi igual al esperado, pero el cabezal no
coincide.
Tablero inicial

0 1 2 3 4

1 1

0 0

0 1 2 3 4
Tablero final esperado

0 1 2 3 4
1 1

0 0
1 1 1 1
0 1 2 3 4
Tablero final obtenido

0 1 2 3 4

1 1

0 0
1 1 1 1
0 1 2 3 4
Con el espacio justo
El programa hizo BOOM.
Tablero inicial

0 1 2 3

1 1

0 0

0 1 2 3

Tablero final esperado

0 1 2 3

1 1

0 1 1 1
0
1
0 1 2 3

Tablero final obtenido DESASTRE BOOM


BOOM
[6:5]: No se puede mover hacia la dirección Este: cae afuera del tablero.

procedure LineaNegra4Este() {
Poner(Negro)
repeat(3) {
Poner(Negro) seria asi Invirtiendo Mover(Este)
Mover(Este) Poner(Negro)ypasalaprueba
}
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
  Con lugares de sobra
Se obtuvo un tablero distinto al esperado.

Tablero inicial

0 1 2 3 4

1 1

0 0

0 1 2 3 4

Tablero final esperado

0 1 2 3 4

1 1

0 0
1 1 1 1
0 1 2 3 4
Tablero final obtenido

0 1 2 3 4

1 1

0 0
1 1 1 1
0 1 2 3 4

Con el espacio justo


Se obtuvo un tablero distinto al esperado.
Tablero INICIAL

0 1 2 3

1 1

0 0

0 1 2 3

Tablero final esperado

0 1 2 3

1 1

0 1 1 1
0
1
0 1 2 3

Tablero final OBTENIDO

0 1 2 3

1 1

0 1 1 1 0
1
0 1 2 3

Solución ejercicio perfectA


procedure LineaNegra4Este(){
  repeat(3){
    Poner(Negro)
    Mover(Este)
 }
  Poner(Negro)
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
  Con lugares de sobra
 Tablero Inicial

0 1 2 3 4

1 1

0 0

0 1 2 3 4
Tablero final esperado

0 1 2 3 4

1 1

0 0
1 1 1 1
0 1 2 3 4

 Con el espacio justo


Tablero INICIAL

0 1 2 3

1 1

0 0

0 1 2 3

Tablero final esperado

0 1 2 3

1 1

0 1 1 1
0
1
0 1 2 3
Siempre que tengas problemas como este vas a poder solucionarlos de la
misma manera: procesando el último caso por separado.

Otra variante menos común, y tal vez más difícil de construir también, es la
de procesar el primer caso aparte:

procedure LineaNegra4Este() {
Poner(Negro)
repeat(3) {
Mover(Este)
Poner(Negro)
}
}

Por convención, vamos a preferir la forma que procesa distinto al último


caso, aunque a menudo ambas sean equivalentes (es decir, produzcan el
mismo resultado)

Ejercicio 11: De lado a lado, dibujamos un


cuadrado
En el ejercicio anterior definimos el procedimiento LineaNegra4Este. Ahora
vamos a utilizarlo para dibujar un cuadrado negro igualito a los de los
tableros de ejemplo:

0 1 2 3 0 1 2 3 4 5 0 1 2 3 4

3 5 5 4
1 1 1 1 1 1 1 1
3 4

1 1 1 1
2 4 4 3
1 1 1 1 1
2
1 1 1
3

1 1 1 1

1 3
1 1 1 1 3 2 1 1 1 1
2
1

1 1 1 1

0 2
1 1 1 1 2 1 1 1 1 1
1
0

0 1 2 3 1
1 1 1 1
1 0 0
0 0
0 1 2 3 4
0 1 2 3 4 5
Definí el procedimiento CuadradoNegro4 para dibujar un cuadrado de 4x4 con bolitas
negras. Al empezar, el cabezal se encuentra en la esquina inferior izquierda del
cuadrado (no necesariamente del tablero ) y cuando termine el programa el cabezal
deberá quedar en el extremo superior derecho del cuadrado. No te olvides de
invocar LineaNegra4Este.
Tené en cuenta lo que hablamos en el ejercicio anterior sobre el caso borde. 
 ¡Dame una pista!

Podemos pensar a un cuadrado de 4x4 como cuatro líneas de longitud 4,


una arriba de la otra. Con el procedimiento que ya definiste tenés el
problema de dibujar una línea resuelto, aunque el cabezal queda en una
posición poco conveniente para dibujar la siguiente. ¿Qué deberíamos hacer
después de dibujar cada línea? ¿En qué dirección me conviene hacerlo?

Biblioteca
procedure LineaNegra4Este() {
repeat(3) {
Poner(Negro)
Mover(Este)
}
Poner(Negro)
}

procedure CuadradoNegro4(){
LineaNegra4Este() No va Esto lo puedo cambiar por esto porque se repite:

Mover(Norte) repeat (3) {

Mover3Oeste() LineaNegra4Este()
LineaNegra4Este() Mover(Norte)

Mover(Norte) Mover3Oeste() }

Mover3Oeste() LineaNegra4Este()

} }

Procedure Mover3Oeste (){

Mover(Oeste)

Mover(Oeste)

Mover(Oeste)

procedure CuadradoNegro4(){
LineaNegra4Este ()
Mover(Norte)
Mover3Oeste()
LineaNegra4Este ()
Mover(Norte)
Mover3Oeste()
}
Procedure Mover3Oeste (){
Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
}
¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que escribiste Procedure en lugar de procedure. ¡Recordá que debe


comenzar en minúsculas!
 Detalles
No entiendo, ¡necesito ayuda!

Tu solución no pasó las pruebas


Objetivos que no se cumplieron:

  CuadradoNegro4 debe usar repeat

Resultados de las pruebas:

  Con lugares de sobra: Se obtuvo un tablero distinto al esperado.

 Tablero inicial
0 1 2 3

4 4

3 3

2 2

1 1

0 0

3
0 1 2
Tablero final esperado

0 1 2 3

4 4

3 1 3
1
1 1
2 2
1 1 1 1
1 1
1 1 1 1
0 1 0
1 1 1
3
0 1 2
Tablero final obtenido

0 1 2 3

4 4

3 3

2 2

1 1
1 1 1 1
0 1 0
1 1 1
3
0 1 2

Con el espacio justo: Se obtuvo un tablero distinto al esperado.


Tablero inicial

0 1 2 3 4

3 3

2 2

1 1

0 0

0 1 2 3 4
Tablero final esperado

0 1 2 3 4
1 1 1 1
3 3
1 1 1 1
1 1 1 1
2 2
1 1 1 1
1 1 1 1
1 1
1 1 1 1
1 1 1 1
0
1 1 1 10
0 1 2 3 4
Tablero final obtenido
0 1 2 3 4

3 3

2 2

1 1 1 1
1 1
1 1 1 1
1 1 1 1
0 1 1 1 10
4
0 1 2 3

LA SOLUCION ES:

procedure CuadradoNegro4(){
repeat(3){
LineaNegra4Este()
repeat(3){
Mover(Oeste)
}
Mover(Norte)
}
LineaNegra4Este()
}

procedure Mover3Oeste (){


Mover(Oeste)
Mover(Oeste)
Mover(Oeste)
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Con lugares de sobra


 Tablero inicial
0 1 2 3

4 4

3 3

2 2

1 1

0 0

0 1 2 3

 Tablero final

0 1 2 3

4 4

1 1 1 1
3 3
1 1 1 1
1 1 1 1
2 1 2
1 1
1 1 1 1
1 1
1 1
1 1 1
0 1 10
1 1
0 1 2 3

Con el espacio justo


Tablero inicial
0 1 2 3 4

3 3

2 2

1 1

0 0
0 1 2 3 4

Tablero final

0 1 2 3 4
1 1 1 1
3 1 3
1 1
1 1 1 1
2 2
1 1
1 1 1 1
1 1 1

1 1 1 1
0
1 1 10
4
0 1 2 3

En esta guía aprendiste algo muy importante: cómo hacer que la


computadora repita tareas, usando el comando repeat.

Con esta nueva herramienta ya podés empezar a construir programas mucho


más interesantes: recorrer un tablero de dimensiones conocidas, poner o
sacar muchas bolitas, parametrizar el dibujo de un cuadrado, etc.

¡Terminaste Repetición Simple!

En esta guía aprendiste algo muy importante: cómo hacer que la


computadora repita tareas, usando el comando repeat.

Con esta nueva herramienta ya podés empezar a construir programas mucho


más interesantes: recorrer un tablero de dimensiones conocidas, poner o
sacar muchas bolitas, parametrizar el dibujo de un cuadrado, etc.

¡Animate a pensar otros ejemplos!

Parámetros
Gracias a los procedimientos empezamos a dividir en subproblemas,
logrando hacer programas más complejos de una manera más fácil y
evitando repetir código. 
Ahora vamos a ver como podemos hacerlos más genéricos utilizando
parámetros. 

Ejercicios

  1. Pensando en subtareas


  2. Dibujando un cuadrado con subtareas
  3. Color esperanza
  4. Los que faltan
  5. Procedimientos con agujeritos
  6. Llenando los espacios vacíos
  7. DibujarLinea3
  8. DibujarCuadradoDeLado3
  9. Pasando varios parámetros
  10. La ley, el orden y el BOOM
  11. Un argumento para dos parámetros
  12. La tercera es la vencida

Ejercicio 1: Pensando en subtareas


¡Queremos dibujar un nuevo cuadrado! 

0 1 2
1 1 1
2 2
1
1 1
1 1 1
1
1 1 1
1

1 1 1
0 0
1 1 1
2
0 1

Dividiendo cada parte del problema en procedimientos más pequeños,


podemos plantear la siguiente estrategia: construir el cuadrado como tres
líneas de tres bolitas una encima de la otra. ¿A qué nos referimos con una
línea de tres bolitas? A esto:

0 1 2
1 1 1 2
2

1
1 1 1 1
1

0
0
1 1 1
1
1 1 1 1
1
2
0 1

¡Arranquemos por ahí!

Definí el procedimiento DibujarLineaNegra3 que, como su nombre lo


indica, dibuje una línea poniendo 3 bolitas negras consecutivas hacia el Este y
dejando el cabezal donde comenzó. Invocalo en un program.
En la Biblioteca vas a encontrar el procedimiento VolverAtras. ¡Eso significa
que podés invocarlo sin tener que definirlo! 

BIBLIOTECA

procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

procedure Bolitas(){
repeat(3){
Poner(Negro)
}

procedure DibujarLineaNegra3( ) {
repeat(3) {
Bolitas()
Mover(Este) }
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}
program { DibujarLineaNegra3()
}
¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que te falta una } antes de un procedure. ¿Puede que sea en la


línea 5 o cerca de ella?

 Detalles
Resultados:
[5:1]: Se esperaba un comando.
Se encontró: la palabra clave "procedure".

procedure Bolitas(){
repeat(3){
Poner(Negro)
}
}
procedure DibujarLineaNegra3( ) {
repeat(3) {
Bolitas()
Mover(Este) }
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}
program { DibujarLineaNegra3()
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  DibujarLineaNegra3 debe utilizar VolverAtras

Resultados:

[18:11]: El procedimiento "VolverAtras" está definido dos veces: en (?):11:3 y en (?):18:1.


procedure Bolitas(){
repeat(3){
Poner(Negro)
}
}
procedure DibujarLineaNegra3( ) {
repeat(3) {
Bolitas()
Mover(Este) }
}
VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}
program { DibujarLineaNegra3()
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[11:1]: Se esperaba una definición (de programa, función, procedimiento, o tipo).


Se encontró: un identificador con mayúsculas.

Una solución con error en las consultas

procedure PonerMover () {
Poner (Negro)
Mover (Este)
Poner (Negro)
Mover (Este)
Poner (Negro)
}
procedure DibujarLineaNegra3 () {
PonerMover ()
{
VolverAtras ()
}
}
program {
DibujarLineaNegra3 ()
}

Mirna Lorena V. hace 16 días


DibujarLineaNegra3 debe usar repeat. No entiendo porque me pone asi
MENTORÍA  hace 16 días
¡Hola Mirna! ¿Cómo te va?
Antes de ver el tema del repeat, recordá que las llaves las usamos para abrir y
cerrar procedimientos, programas o estructuras como el repeat. Con esto
dicho, las llaves de las líneas 10 y 12 son innecesarias.
En cuanto al repeat, esta estructura nos permitía repetir las veces que
queramos lo que esté dentro de las llaves. Por ejemplo si hacíamos:
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)

Es lo mismo que hacer:

repeat(5){
Poner(Rojo)
}

Se repetirá 5 veces la instrucción Poner(Rojo), pero usamos menos código al


escribirlo.
¿Tenés alguna lógica que se repita cierta cantidad de veces que pueda ir en
un repeat? Prestemos atención al procedimiento PonerMover
Otra solución que esta bien pero que se le deben hacer mejoras
procedure DibujarLineaNegra3(){
repeat(1) {Poner(Negro)
Mover(Este)
Poner(Negro)
Mover(Este)
Poner(Negro)
VolverAtras()
}
}
program{
DibujarLineaNegra3()
}
MENTORÍA  hace 7 días
¡Hola Carina! Antes de entrar en lo que es el código en sí, acordate que el
comando repeat se usa justamente para repetir cosas y evitar escribir código
de más, por lo que no tiene sentido usar repeat(1) ya que no está habiendo
ninguna repetición, sino que simplemente se están ejecutando los comandos
una sola vez (tendría que mismo resultado quitándole el repeat ya que no hay
repetición). En cuanto al código en sí, fijate que los comandos Poner(Negro) y
Mover(Este) se repiten dos veces cada uno, por lo que se podrían agrupar
dentro de un repeat(2) y por fuera de esta repetición (es decir, por fuera de la
llave que cierra el repeat) habría que usar una vez más el comando Poner(Negro)
e invocar el procedimiento VolverAtras. Probá modificar el código con esto
en mente y cualquier cosa si seguís con dudas lo seguimos viendo.

SOLUCION MIA MAL


procedure DibujarLineaNegra3(){
repeat(3){
Poner(Negro)
Mover(Este)
VolverAtras()
}
}
program { DibujarLineaNegra3()
}
Tu solución no pasó las pruebas

[13:2]: No se puede mover hacia la dirección Oeste: cae afuera del tablero.

EJERCICIO RESUELTO BIEN


procedure DibujarLineaNegra3(){
repeat(2){
Poner(Negro)
Mover(Este)
}
Poner(Negro)
VolverAtras()
}
program { DibujarLineaNegra3()
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Tablero de 3 por 3

0 1 2
1 1 1 2
2

1 1
1 1 1
1
1
1
0
0
1 1 1
1
1 1
2
0 1

0 1 2
1 1 1 2 1
2

1
1 1 1
1 1

1 1 1
0 0
1 1 1
2
0 1
 Tablero de 4 por 4
Tablero inicial

0 1 2 3

3 3

2
2 1
1 1 1 1 1
1 1

0 0

3
0 1 2

1
Tablero FINAL

0 1 2 3

3 3

2 2

1 1

0 1 0
1 1
3
0 1 2

¡Perfecto!  Ya tenemos nuestra línea, ya vamos a poder hacer un cuadrado


negro.

Ejercicio 2: Dibujando un cuadrado con


subtareas
¡Ya podemos dibujar nuestro cuadrado! El cual debería verse así:
El cabezal comienza en el origen, es decir, en el casillero de abajo a la
izquierda:
0 1 2
1 1 1 2
2

1 1 1 1 1
1
1
1
1 1 1 0
0

2
0 1

¡Ya podemos dibujar nuestro cuadrado! El cual debería verse así:

0 1 2
1 1 1
2 2
1 1
1
1 1 1
1 1
1 1 1
1 1 1
0 0
1 1 1
2
0 1

Definí el procedimiento DibujarCuadradoNegroDeLado3 que
invocando DibujarLineaNegra3 dibuje un cuadrado negro sobre el tablero. ibl

 ¡Dame una pista!

Podemos pensar a un cuadrado de 3x3 como 3 líneas de longitud 3 una


arriba de la otra, ¿no?

Ah, y recordá también que DibujarLineaNegra3 ya usa VolverAtras cuando


termina. 

BIBLIOTECA
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

procedure DibujarLineaNegra3() {
/*
...
*/
}
/*
La definición de este procedimiento está oculta pero satisface lo requerido
en el ejercicio anterior.
*/

Resolución mal
procedure DibujarCuadradoNegroDeLado3(){
repeat(3){
DibujarLineaNegra3()
}
procedure DibujarLineaNegra3(){
repeat(2){
Poner(Negro)
Mover(Este)
}
Poner(Negro)
VolverAtras()
}
}
program {
DibujarCuadradoNegroDeLado3()
}
 ¡Ups! Tu solución no se puede ejecutar
Resultados:

[5:3]: Se esperaba un comando.


Se encontró: la palabra clave "procedure".

Una solución con error


procedure DibujarCuadradoNegroDeLado3(){
DibujarLineaNegra3()
repeat(1){
}
Mover(Norte)
repeat(1){
DibujarLineaNegra3()
}
Mover(Norte)
repeat(1){
DibujarLineaNegra3()
}
}
program{
DibujarCuadradoNegroDeLado3()
}
Rocio C. hace 9 días
hola!! buenas tardes!, necesito ayuda con este problema, esta es la cuestion
es el unico metodo que me acepto mas o menos, pero si le saco un repeat
me sigue diciendo que queda uno incesario cualquiera que le saque, y si le
saco los tres repeat me dice que tengo que usar un repeat (el mismo
procedimiento pasa con el numero dentro del repeat (me sale 2 o 3 bolitas
en lugar de una sola)), cualquier otra cosa que modifique me sale que fallo.
ya no se que hacer, les agradeceria la ayuda!
Diana L.  MENTORÍA  hace 9 días
¡Buenas tardes Rocio! ¿Cómo te va?
Si recordamos de ejercicios anteriores, el repeat nos permite poder ejecutar
varias veces ciertas instrucciones en un orden determinado. Por ejemplo en
lugar de hacer:
Poner(Rojo)
Poner(Azul)
Poner(Rojo)
Poner(Azul)

Que nos coloca una bolita roja y una azul dos veces, podemos meter esto
dentro de un repeat al que le decimos que lo ejecute dos veces:

repeat(2){
Poner(Rojo)
Poner(Azul)
}
Fijate que tomamos la repetición de código y lo hicimos más pequeño.
¿Y qué pasa si usamos un repeat(1)? Como vemos en el ejemplo, al repeat le
podemos decir qué cantidad de veces queremos que se repita algo, si le
decimos repeat(1), solamente lo ejecutará una vez:

repeat(1){
Poner(Rojo)
Poner(Azul)
}

Es el equivalente de hacer:

Poner(Rojo)
Poner(Azul)

¿Para que lo agregamos si es exactamente lo mismo que solamente poner


las instrucciones? Justamente, es innecesario hacer repeat(1) porque no
queremos que se repita algo, si no que queremos que se ejecute una sola
vez, que es lo mismo que poner directamente las instrucciones.
Como mencionaste, si le sacamos los repeat nos dice que deberíamos
usarlos 🤔. Esto es porque tenemos una repetición de lógica en nuestro
código que podría solucionarse con un repeat. Veamos el código sin los
repeat(1):

procedure DibujarCuadradoNegroDeLado3(){
DibujarLineaNegra3()
Mover(Norte)
DibujarLineaNegra3()
Mover(Norte)

DibujarLineaNegra3()

}
program{
DibujarCuadradoNegroDeLado3()
}

Fijate que varias veces dibujamos la línea y nos movemos al Norte, ¿no
podrá eso ir dentro de un repeat? ¿Cuántas veces se repite?
procedure DibujarCuadradoNegroDeLado3(){
repeat(2){
DibujarLineaNegra3()
Mover(Norte)
}
{
DibujarLineaNegra3()
}
program{
DibujarCuadradoNegroDeLado3()
}

¡Ups! Tu solución no se puede ejecutar


Problemas que encontramos:

 Parece que te falta una } que cierre el procedure antes de program.


  Detalles
 Resultados:

 [9:3]: Se esperaba un comando.


 Se encontró: la palabra clave "program".

SOLUCION VALIDA
procedure DibujarCuadradoNegroDeLado3(){
repeat(2){
DibujarLineaNegra3()
Mover(Norte)
}
{
DibujarLineaNegra3()
}
}
program{
DibujarCuadradoNegroDeLado3()
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
  Tablero de 3 por 3
 0 1 2

2 1 1 1
2

1 1 1 1
1

0 1 1 1
0

2
0 1

¡Ya podemos dibujar nuestro cuadrado! El cual debería verse así:

0 1 2
1 1 1
2 2
1 1
1
1 1 1
1 1
1 1 1
1 1 1
0 0
1 1 1
2
0 1

 Tablero de 4 por 4
Tablero inicial
0 1 2 3

3 3

2 2

1 1

0 0
0 1 2 3

0 1 2 3

3 3

2 1 2
1 1
1 1

0 1 0
1 1
0 1 2 3

¡Muy bien! Ya tenemos un cuadrado negro, pero también queremos


cuadrados de otros colores . Solucionemos esto haciendo nuevos
procedimientos. 

Esto no va en la resolución del ejercicio pero nos muestra lo siguiente de


como se definio la LineaNegra3 del ejercicio anterior
procedure DibujarLineaNegra3(){
repeat(2){
Poner(Negro)
Mover(Este)
}
Poner(Negro)
VolverAtras()
}
Si nos pidieran definirlo completo seria:
procedure DibujarLineaNegra3(){
repeat(2){
Poner(Negro)
Mover(Este)
}
Poner(Negro)
VolverAtras()
}
procedure DibujarCuadradoNegroDeLado3(){
repeat(2){
DibujarLineaNegra3()
Mover(Norte)
}
{
DibujarLineaNegra3()
}
}
program{
DibujarCuadradoNegroDeLado3()
}

Ejercicio 3: Color esperanza


Ya sabemos como dibujar una línea negra con 3 bolitas . Usemos esa lógica
para dibujar una línea verde.

Definí el procedimiento DibujarLineaVerde3 e invocalo en el program.


 ¡Dame una pista!

DibujarLineaVerde3 es igual a DibujarLineaNegra3 solo que dibuja una linea verde. 

Biblioteca

procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

SOLUCION

procedure DibujarLineaVerde3(){
repeat(2){
Poner(Verde)
Mover(Este)
}
Poner(Verde)
VolverAtras()
}
program{
DibujarLineaVerde3()
}

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

  Tablero de 3 por 3

0 1 2
1 1 1
2 2

1
1 1 1 1
1 1 1
0 1 1
0 1 1 1
1
2 1
0 1 1 1
1

1
0 1 2
1 1
1 1 1 2
2 1
1
1 1 1
1 1

1 1 1
0 0
1 1 1
2
0 1

Tablero de 4 por 4

0 1 2 3

3 3

2
2
1 1 1
1 1
0 0
1
3
0 1 2

¡Excelente! Pero todavía nos faltan dos colores más . Ya te imaginarás lo que
hay que hacer. 

Ejercicio 4: Los que faltan


Solo nos faltan dos colores: Rojo  y Azul .

Definí los procedimientos DibujarLineaRoja3 y DibujarLineaAzul3.


Biblioteca

procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

procedure DibujarLineaRoja3(){
repeat(2){
Poner(Rojo)
Mover(Este)
}
Poner(Rojo)
VolverAtras()
}
program{
DibujarLineaRoja3()
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  DibujarLineaAzul3 debe utilizar VolverAtras
  DibujarLineaAzul3 debe usar repeat
  la solución debe declarar DibujarLineaAzul3

Resultados:

[13:1]: Ya había un programa definido en (?):9:3.

Ejercicio mal el program no se pidio


procedure DibujarLineaRoja3(){
repeat(2){
Poner(Rojo)
Mover(Este)
}
Poner(Rojo)
VolverAtras()
}
procedure DibujarLineaAzul3(){
repeat(2){
Poner(Azul)
Mover(Este)
}
Poner(Azul)
VolverAtras()
}
program{
DibujarLineaRoja3()
DibujarLineaAzul3()
}
 ¡Ups! Tu solución no se puede ejecutar
Resultados:

[22:1]: Ya había un programa definido en (?):17:3.


No se puede definir un programa en (?):22:1.
LA SOLUCION BIEN ES
procedure DibujarLineaRoja3(){
repeat(2){
Poner(Rojo)
Mover(Este)
}
Poner(Rojo)
VolverAtras()
}
procedure DibujarLineaAzul3(){
repeat(2){
Poner(Azul)
Mover(Este)
}
Poner(Azul)
VolverAtras()
}
¡Muy bien! Tu solución pasó todas las pruebas

Tablero de 4 por 4

0 1 2 3

3 3

2
2
1 1 1
1 1

0 1 0
1 1
3
0 1 2
¡Muy bien!  Pero se volvió medio repetitiva la tarea de dibujar 4
procedimientos casi iguales ¿no?  Sólo cambiaba el color, y si a esto le
sumamos que además necesitamos un nuevo procedimiento por cada
cuadrado, ¡la cosa se pone cada vez más aburrida! . ¿Se podrá solucionar de
alguna manera? 

Ejercicio 5: Procedimientos con agujeritos


¡Empecemos con algo fácil!  Supongamos que tenemos un procedimiento
llamado Poner3Verdes, que pone 3 bolitas verdes en un casillero, y lo
queremos generalizar para que funcione con cualquier color que queramos
(pero uno solo por vez). Lo que necesitamos es agregarle al procedimiento
una especie de agujero...

procedure Poner3(color) {
repeat(3) {
Poner(color)
}
}

...que luego pueda ser completado con el color que queramos:

program {
Poner3(Negro)
Poner3(Rojo)
}
Escribí los códigos anteriores en el editor y fijate qué pasa.

procedure Poner3(color) {
repeat(3) {
Poner(color)
}
}
program {
Poner3(Negro)
Poner3(Rojo)
}

 ¡Muy bien! Tu solución pasó todas las pruebas


Tablero inicial

0 1

2 2

1 1

0 0

0 1

Tablero final

0 1

2 3 2
3
3

1 1

0 0

1
0

¿Viste qué interesante lo que hicimos? 

Con un mismo procedimiento pudimos hacer 2 cosas casi iguales; por un


lado pusimos 3 bolitas negras y por el otro 3 bolitas rojas. La diferencia
estuvo en cómo usamos Poner3: la primera vez completamos
el agujero con Negro y la segunda con Rojo.

Ejercicio 6: Llenando los espacios vacíos


Entendamos qué acabamos de hacer. 

Lo primero que hicimos fue definir un procedimiento, pero con una pequeña
diferencia: toma un parámetro, llamado color.

procedure Poner3(color) {
Poner(color)
Poner(color)
Poner(color)
}

¿Y qué es un parámetro? Son esos nombres que van entre paréntesis para
ser reemplazados por valores concretos cuando invocamos al procedimiento.
Por ejemplo, si lo invocamos así..

program {
Poner3(Negro)
}

...lo que se ejecuta es:

Poner(Negro)
Poner(Negro)
Poner(Negro)

Y si lo invocamos así...

program {
Poner3(Rojo)
}

lo que se ejecuta es:

Poner(Rojo)
Poner(Rojo)
Poner(Rojo)

Fijate como cada vez que aparece color se reemplaza por el valor que
le pasamos a Poner . Veamos si se entiende:

Creá un programa que ponga tres bolitas verdes. No te olvides de invocar el


procedimiento Poner3.

BIBLIOTECA

procedure Poner3(color) {
Poner(color)
Poner(color)
Poner(color)
}

Solucion Mal

procedure Poner3(Verde) {
Poner(Verde)
Poner(Verde)
Poner(Verde)
}
program {Poner3(Verde)}
 ¡Ups! Tu solución no se puede ejecutar
Resultados:

[1:18]: Se esperaba un identificador con minúsculas.


Se encontró: un identificador con mayúsculas.

Definido en la consulta con error y se


explica cual es la solución
procedure Poner3(color) {
Poner(color)
Poner(color)
Poner(color)
}
program {
Poner3(Verde)
}
Victoria Yamila L. hace 10 meses
no puedo creer de nuevo con el Poner3(color) tengo problemas... ahora me
dice q el procedimiento Poner3(color) esta definido en 1 y en 9... pero ni
llegue a escribir en 9, q significa?
Carlos Jorge T. hace 10 meses
Hola Victoria. Si te fijás en la biblioteca, el procedimiento "Poner3(color)" ya
está definido. Sólo tenés que usarlo. Borrá toda la definición que hiciste y
sólo dejá la parte desde "program". Saludos.
SOLUCION PERFECTA
program {
Poner3(Verde)
}
¡Muy bien! Tu solución pasó todas las pruebas
0 1

2 2

1 1

0 0

1
0

0 1

2 3 2

3
1 1

0 0

1
0

Ejercicio 7: DibujarLinea3
¡Ahora te toca a vos!

Ya hicimos cuatro procedimientos para dibujar líneas de cada color, pero si


usamos parámetros podría ser sólo uno.

Definí el procedimiento DibujarLinea3 que reciba un color y dibuje una línea


de ese color. Despreocupate por los programs para invocarlo con cada uno
de los colores, van por nuestra parte. 

 ¡Dame una pista!

¡Ojo!  DibujarLinea3 tiene que servir para cualquier color como hicimos


con Poner3. Este es el parametro

procedure Poner3(color) {
Poner(color)
Poner(color)
Poner(color)
}

En la Biblioteca podés ver DibujarLineaNegra3 para usarlo como referencia.

Biblioteca
procedure DibujarLineaNegra3() {
repeat(2) {
Poner(Negro)
Mover(Este)
}
Poner(Negro)
VolverAtras()
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

SOLUCION CON ERROR


procedure DibujarLinea3() {
repeat(2) {
Poner(Color)
Mover(Este)
}
Poner(Color)
VolverAtras()
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  DibujarLinea3 debe tener un parámetro

Resultados:

[27:11]: El procedimiento "VolverAtras" está definido dos veces: en (?):10:1 y en (?):27:1.

Solucion en la consulta con error


procedure DibujarLinea3(){
repeat(2){
Poner(color)
Mover(Este)
}
Poner(color)

VolverAtras()
}
Araceli Abigail V. hace 10 meses
Holaa!! Estoy un poco desorientada, pregunto, cual seria el parametro que
me pide... Gracias :)
Sergio Sebastian S. hace 10 meses
Hola Araceli.. lo que te pide es que DibujarLinea3 acepte 1 parametro que
basicamente es que acepte algo para luego usarlo.. te pongo un ejemplo
procedure PintarColor(color){ Poner(color) } En este caso, acepto 1 parametro color
y lo uso abajo en Poner... Se entiende?

procedure DibujarLinea3(Color) {
repeat(2) {
Poner(Color) Este es el error pq lo pongo con mayuscula
Mover(Este) Esto es el identificador
}
Poner(Color)
VolverAtras()
}

(Aclaración:Esta es la resolución perfecta del ejercicio)


procedure DibujarLinea3(color){
repeat(2){
Poner(color)
Mover(Este)
}
Poner(color)
VolverAtras()
¡Muy bien! Tu solución pasó todas las pruebas
Tablero Inicial

0 1 2 3

3 3
2 2

1 1

0 0

3
0 1 2

Tablero final
0 1 2 3
1 1 1
3 3

2 2

1 1

0 1 0
1 1
3
0 1 2

Tablero Inicial

0 1 2 3

3 3

2 2

1 1

0 0

3
0 1 2

Tablero final

0 1 2 3

3 3

2 2

1 1
0
1 1 1 0

3
0 1 2

Tablero Inicial

0 1 2 3

3 3

2 2

1 1

0 0

3
0 1 2

Tablero final

0 1 2 3

3 3

2 2

1 1

0 1 0
1 1
3
0 1 2

Tablero Inicial

0 1 2 3

3 3

2 2

1 1

0 0
3
0 1 2

Tablero final

0 1 2 3

3 3

2 2

1 1

0 0
1 1 1
3
0 1 2

En vez de escribir color podríamos haber escrito c, col o incluso pepe, porque a


la computadora no le importa el nombre que le demos a las cosas... pero a
nosotros sí (y mucho ), así que por eso elegimos usar nombres que
expresen bien lo que queremos decir.

Fijate también que elegimos un nuevo nombre para nuestro nuevo


procedimiento porque ahora sirve para cualquier color. Esto tampoco es
estrictamente necesario para la computadora, pero es super importante para
los humanos que van a leer y escribir el código. Imaginate que si le
pusieramos DibujarLineaNegra3 (o DibujarLineaAzul3) al usarlo para dibujar una
línea roja quedaría DibujarLineaNegra3(Rojo). Si bien va a funcionar, no se
entendería bien qué es lo que hace: ¿una línea negra? ¿una línea roja? ¿una
línea negra y roja?. 

¡Es importantísimo poner buenos nombres para programar bien! 

Ejercicio 8: DibujarCuadradoDeLado3
¡Hora del último pasito!  Ya definimos un procedimiento para poder dibujar
cuadrados negros (DibujarCuadradoNegroDeLado3), pero todo este asunto de los
parámetros surgió cuando quisimos hacer cuadrados de distintos colores. 
Invocando DibujarLinea3, definí el
procedimiento DibujarCuadradoDeLado3 que recibe un color y dibuja un
cuadrado de 3x3 de ese color.

 ¡Dame una pista!


Recordá que DibujarLinea3 recibe un parámetro.
Biblioteca
procedure DibujarLinea3(color) {
repeat(2) {
Poner(color)
Mover(Este)
}
Poner(color)
VolverAtras()
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

MI PRIMERA RESOLUCION Y QUE DIO ERROR


procedure DibujarLinea3(Verde) {
repeat(2) {
Poner(Verde)
Mover(Este)
}
Poner(Verde)
VolverAtras()
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}
procedure DibujarCuadradoDeLado3(){
repeat(2){
DibujarLinea3()
Mover(Norte)
}
{
DibujarLinea3()
}
}

¡Ups! Tu solución no se puede ejecutar


Resultados:

[1:25]: Se esperaba un identificador con minúsculas.


Se encontró: un identificador con mayúsculas.

Ejercicio sacado de la consulta que tiene


error
procedure DibujarCuadradoDeLado3(Negro){
repeat (2){
DibujarLinea3(Negro)
Mover(Norte)
DibujarLinea3(Negro)
Mover(Norte)}
DibujarLinea3(Negro)

}
Mercedes N. hace 5 meses
[1:34]: Se esperaba un identificador con minúsculas. Se encontró: un
identificador con mayúsculas. A qué se refiere?
Mercedes D. hace 5 meses
Hola Mercedes! El error indicado en el ejercicio hace referencia a que el
parámetro del procedimiento debe estar escrito solo con minusculas. En el
caso del ejercicio, está indicado el parámetro como "Negro". Según el
enunciado, debe recibir un parámetro llamado "color" para que el
procedimiento pueda ser usado con cualquier color. Por otro lado, en el
ejercicio se está usando repeat para indicar que ciertos pasos del
procedimiento se deben repetir dos veces, pero dentro del corchete cada
paso ya está escrito dos veces. Por lo tanto, esa acción se llevará a cabo 4
veces. Por último, para poder visualizar mejor la escritura de la solución
podés utilizar la herramienta "dar formato" que se encuentra a la derecha de
la consola donde se escribe la solución.

Ejercicio sacado de la consulta que tiene


error
procedure DibujarCuadradoDeLado3(color){
repeat(2){
DibujarLinea3(Negro)
}
VolverAtras()
}
Leandro P. hace 20 días
Hola, creo que está mal tu uso de VolverAtras, trata de hacerlo sin eso, a ver
qué pasa.
Guillermo Ignacio B.  MENTORÍA  hace 19 días
¡Hola Sary! Nuevamente, al realizar el código y apretar en enviar se evalúa el
ejercicio, por lo que si te sale en verde es porque está bien, pero de otra
manera significa que hay cosas para corregir. En este caso hay algunas cosas
para modificar.
 En principio, como dice Leandro, no es necesario usar VolverAtras ya
que este se usa cuando invocás DibujarLinea3 (fijate en la
Biblioteca).
 Por otro lado la idea del ejercicio (y de la sección Parámetros en sí) es
que no se utilice un color en particular, sino que se haga uso del
parámetro color, Sin embargo en este caso el código solo pondría
bolitas negras.
 Por último la consigna dice que hay que formar un cuadrado, por lo
que cada vez que se invoca a DibujarLinea3 hay que mover el cabezal
para formar otra línea.
Probá modificar el código con esto en mente y cualquier cosa si seguís con
dudas lo seguimos viendo.
Ejercicio sacado de la consulta que tiene
error
procedure DibujarCuadradoDeLado3(color) {

DibujarLinea3(color)
Mover(Norte)
DibujarLinea3(color)
Mover(Norte)
DibujarLinea3(color)

}
Yesica R. hace 10 meses
¡Hola! ¿Qué tal? No entiendo en qué momento utilizar repeat
" Tu solución funcionó, pero hay cosas que mejorar Objetivos que no se
cumplieron: DibujarCuadradoDeLado3 debe usar repeat"
Cuando pongo repeat en DibujarCuadradoDeLado3 me repite las bolas
adentro.
Hasta ahora la única solución que encontré fue ésta sin repeat que funciona
pero que me dice que debe mejorar, y no entiendo como proceder
Mayra Nerina M. hace 10 meses
¡Hola Yesica! ¿Como estas? Recordá que el repeat nos ayuda a escribir menos
código, para saber si algo deberia ir dentro de uno, lo que podés hacer es
observar si hay parte del codigo que se está repitiendo. En este caso
DibujarLinea3(color) Mover(Norte). ¡Estás muy cerca de lograrlo!
RESULTADO CORRECTO DEL EJERCICIO
Biblioteca
procedure DibujarLinea3(color) {
repeat(2) {
Poner(color)
Mover(Este)
}
Poner(color)
VolverAtras()
}
procedure VolverAtras() {
Mover(Oeste)
Mover(Oeste)
}

solucion
procedure DibujarCuadradoDeLado3(color){
repeat(2){
DibujarLinea3(color)
Mover(Norte)
}
{
DibujarLinea3(color)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

Tablero INICIAL

0 1 2 3

3 3

2 2

1 1

0 0

3
0 1 2

Tablero final (CON TODOS LOS COLORES: NEGRO, AZUL, VERDE, ROJO)

0 1 2 3

3 3

2 2
1 1 1
1 1
1 1 1
0 0
1 1 1
3
0 1 2

Genial, ¡logramos crear un procedimiento que nos sirve para cualquier color! 

Un procedimiento puede no tener parámetros (como pasa


en VolverAtras o DibujarLineaNegra3) o un parámetro
(como Mover, Poner o DibujarLinea3), pero ¿puede tener más de uno?

Ejercicio 9: Pasando varios parámetros


¿Y si queremos que DibujarLinea3 sirva también para dibujar líneas en
cualquier dirección?  Sin dudas tenemos que decirle al procedimiento,
además del color, en qué direccion debe dibujar la línea; y para eso vamos a
necesitar un nuevo parámetro . Por suerte, ¡los procedimientos también
pueden tener más de un parámetro! 

¿Y cómo se hace esto? Muy fácil, al igual que como hacemos al escribir,
vamos a separar cada parámetro usando comas de esta manera:

procedure DibujarLinea3(color, direccion) {


Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}

Creá un program que invoque la nueva versión de DibujarLinea3 (no tenés


que definirla, sólo invocarla) y dibuje un cuadrado multicolor como este:
0 1 2 3
1 1 1 1
3 1 1 1 3
1
1
2 2
1 1
1
1
1 1 1
1 1

0
1 1 1
1
1
1 1 1
0

0 1 2 3
No te preocupes por la posición final del cabezal.
 ¡Dame una pista!

Prestá atención a la cantidad de parámetros que recibe el procedimiento y


en qué orden. Y no te olvides de separarlos con comas. 

BIBLIOTECA
procedure DibujarLinea3(color, direccion) {
Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}

RESULTADO DE SOLUCION INCORRECTA

program {
DibujarLinea3(color,direccion)
DibujarLinea3(color,direccion)
DibujarLinea3(color,direccion)
DibujarLinea3(color,direccion)

}
Tu solución no pasó las pruebas

El programa hizo BOOM.

BOOM
[2:17]: La variable "color" no está definida.

Solución de consulta no resuelta

Elida Beatriz L. hace 10 meses


me sale este error
[2:17]: La variable "color" no está definida.
cuando solo se supone que hay que invocar un prodedimiento que está en
Biblioteca mis dos posibles programas son

program { DibujarLinea3(color, direccion) }


o
program {
repeat(4)
{ DibujarLinea3(color, direccion)
}
}
Daniela M.  MENTORÍA  hace 10 meses
¡Hola Elida! Esta muy bien como lo razonas pero en el pograma lo que
hacemos es invocar al procedimiento. El color y direccion que le pasamos
aca en el programa cuando le invocamos deben ser valores validos para
poder resolverlo. Es decir que, cuando llama a DibujarLinea3(color,
direccion), al ejecutar el Poner(color), no va a poder hacerlo ya que nosotros
no le pasamos ningun valor para poder lograr hacer esa linea. En cambio si
le pasamos, cuando la llamamos en el programa, algo como
DibujarLinea3(Rojo, Norte) por ejemplo, va a lograr entender que debe
Poner(Rojo) o Mover(Norte).
SOLUCION DE CONSULTA NO RESUELTA

program{

DibujarLinea3(Verde,Este)

DibujarLinea3(Rojo,Norte)

Mover(Oeste)

Mover(Oeste)

Mover(Sur)

DibujarLinea3(Azul, Norte)

Mover(Este)

DibujarLinea3(Negro,Este)

María Julieta O. hace 7 días


Hola! Así como definí el programa la primera bolita roja comienza donde
está la ultima verde. Pero si entre la linea verde y roja escribo "Mover(Este)"
me dice que cae fuera del tablero. No sé como corregir.
David Ignacio D.  MENTORÍA  hace 7 días
¡Hola María! ¿Cómo estás? No debería caer fuera del tablero si te referís a
comenzar con lo siguiente:

program {
DibujarLinea3(Verde, Este)
Mover(Este)
DibujarLinea3(Rojo, Norte)
[...] // Siguen las líneas

Tal y como está definido DibujarLinea3, el cabezal queda posicionado al final de


la línea, en este caso sin estar en el borde Este. Luego de esto, deberías seguir
con la línea negra y finalmente con la azul, lográndolo sólo con un
movimiento entre el dibujado de las líneas.

program {
DibujarLinea3(Verde, Este)
Mover(Este)
DibujarLinea3(Rojo, Norte)
Mover(Norte)
DibujarLinea3(Negro,Oeste)
Mover(Oeste)
DibujarLinea3(Azul, Sur)
Mover(Azul)

}
Tu solución no pasó las pruebas

1 1
El programa hizo BOOM.

BOOM
[9:3]: El parámetro de "Mover" debería ser una dirección pero es un color.
program {
DibujarLinea3(Verde, Este)
Mover(Este)
DibujarLinea3(Rojo, Norte)
Mover(Norte)
DibujarLinea3(Negro,Oeste)
Mover(Oeste)
DibujarLinea3(Azul, Sur)
Mover(Sur)

}
¡Muy bien! Tu solución pasó todas las pruebas
0 1 2 3
1
3 3

2
2
1
1
1

1
1
1
1 1
1

0
0 1
1 1 1 1

0 1 2 3
Tablero final

0 1 2 3
1 1 1 1
3 1 1 1 3
1
1
2 2
1 1
1
1
1 1 1 1 1

0
1 1 1
1
1
1 1 1
0

0 1 2 3
Como habrás notado, al usar los procedimientos debemos darle un valor a
cada uno de sus parámetros respetando el orden en que fueron definidos.

A estos valores concretos que usamos cuando invocamos a un


procedimiento los llamamos argumentos. 
Ejercicio 10: La ley, el orden y el BOOM
Recién te decíamos que el orden en que pasabamos los argumentos era
importante pero nunca te dijimos por qué . ¡Vamos a verlo!

Creá un programa cualquiera que invoque DibujarLinea3, pero esta vez


intentá invocarlo con los argumentos invertidos. 

 ¡Dame una pista!

Con parámetros invertidos nos referimos a que primero pases la dirección y


después el color.

Biblioteca

procedure DibujarLinea3(color, direccion) {


Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}

SOLUCION
program {
DibujarLinea3(Este, Verde)
Mover(Este)
DibujarLinea3(Norte, Rojo)
Mover(Norte)
DibujarLinea3(Oeste,Negro)
Mover(Oeste)
DibujarLinea3(Sur, Azul)
Mover(Sur)

}
¡Muy bien! Tu solución pasó todas las pruebas

¡BOOM!

BOOM
[12:3]: El parámetro de "Poner" debería ser un color pero es una dirección.

Ok, hizo BOOM , pero ¿qué quiere decir eso de El parámetro de Poner debería ser
un color? 

Al pasar los argumentos al revés, donde se esperaba un color llegó una


dirección; entonces cuando intentamos Poner una dirección provocamos la
autodestrucción del cabezal . Poner(Norte) o Poner(Este) no se pueden ejecutar
porque no tienen ningún sentido. 

Ejercicio 11: Un argumento para dos


parámetros
Ya vimos que pasa cuando pasamos los argumentos desordenados pero
vamos a hacer un experimento más . ¿Qué crees que va a pasar si a un
procedimiento le pasamos menos argumentos de los que necesita?

Creá un programa que invoque a DibujarLinea3 pero pasándole sólo un


argumento.

Biblioteca
procedure DibujarLinea3(color, direccion) {
Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}
Solucion
program {
DibujarLinea3(Verde)
DibujarLinea3(Rojo)
DibujarLinea3(Negro)
DibujarLinea3(Azul)

}
 ¡Muy bien! Tu solución pasó todas las pruebas

¡BOOM!
BOOM

[2:2]: El procedimiento "DibujarLinea3" espera recibir 2 parámetros pero se


lo invoca con un argumento.

¡BOOM de nuevo ! Como te imaginarás, si le pasamos más argumentos de


los que espera pasará lo mismo. 

Entonces es importante recordar que al invocar un procedimiento no


debemos:

 pasarle menos o más argumentos de los que necesita;


 pasarle los argumentos en un orden diferente al que espera.

Ejercicio 12: La tercera es la vencida


Para terminar esta lección vamos a definir un procedimiento
llamado Triada ¡que recibe tres parámetros! 

Triada recibe tres colores por parámetro y pone tres bolitas, una al lado de la
otra hacia el Este, en el mismo orden en que se reciben. El cabezal empieza
en el origen y debe terminar sobre la última bolita de la tríada.
Por ejemplo: Triada(Rojo, Azul, Verde) nos da como tablero resultante:

0 1 2
1

0 1 1 1 0
1 1

2
0 1

mientras que Triada(Azul, Verde, Rojo):

0 1 2

1
0
1 1 1 0
1 1

2
0 1

Definí el procedimiento Triada.

 ¡Dame una pista!

Los nombres de los parámetros elegilos vos, pero mucho cuidado: no


pueden repetirse, tenés que pensar tres nombres diferentes.

Y si no te sale, te lo explicamos en este video. 

procedure DibujarTriada(color, direccion) {


Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  Triada debe tener tres parámetros


  la solución debe declarar Triada

Resultados:

[10:4]: El procedimiento "Triada" no está definido.


procedure DibujarTriada(color,color,color)
{
Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  Triada debe tener tres parámetros


  la solución debe declarar Triada

Resultados:

[1:31]: Conflicto de nombres: "color" se usa dos veces: como parámetro en (?):1:25, y como parámetro
en (?):1:31.

SOLUCION CON ERROR EN LA


CONSULTA
procedure Triada(color1,color2,color3){
Poner(Negro)
Mover(Este)
Poner(Azul)
Mover(Este)
Poner(Rojo)
}
Juan Manuel C. hace 22 días
Hola Pablo. Los parámetros que indicaste cuando definiste "Triada": (color1,
color2, color3) tienen que estar incluidos en las operaciones "Poner" para
que funcione bien (por ejemplo: "Poner(color1)"). Vos no sabés de antemano
qué colores pueden pedirte, por eso no podés poner que el procedimiento
ponga un "Negro" cuando puede que te pidan un "Verde". El parámetro
hace el trabajo de "Poner" el color que le digan al programa, aunque no
sepamos cuál vaya a ser. De lo contrario puede que ingreses como
parámetros "Verde, Verde, Verde" (por ejemplo) pero, según tu
procedimiento que escribiste, siempre va a arrojar "Negro, Azul, Rojo" sin
importar que en realidad hayas puesto otros colores. Por eso no funciona.

SOLUCION CORRECTA
procedure Triada(color1,color2,color3){
Poner(color1)
Mover(Este)
Poner(color2)
Mover(Este)
Poner(color3)
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

INICIAL

0 1 2

1
0 0
1 1

2
0 1

FINALES

0 1 2
1

0 1 1 1 0
1 1

2
0 1

mientras que Triada(Azul, Verde, Rojo):

0 1 2

1
0
1 1 1 0
1 1

2
0 1

¡Terminaste Parámetros!
¡Felicitaciones! 
En esta lección aprendimos como los parámetros facilitan nuestra tarea
permitiéndonos crear procedimientos más genéricos. Cuidado al invocar
estos procedimientos, ¡acordate que la cantidad de argumentos y su orden
importa! Los nombres también pero para las personas, no para las
computadoras. 

Práctica Repetición simple


Ahora que ya sabés cómo repetir tareas, vamos a combinar eso con
procedimientos y parámetros para solucionar problemas más complejos. 

Además, vamos a ir introduciendo algunos temas nuevos en el camino... ¡No


te los pierdas!

Objetivos

 Vamos a aprender qué son las expresiones más sencillas (¿sabías


que Azul es una expresión?)
 Vamos a empezar a reutilizar el código que ya escribimos. Recordá lo
que dijo un sabio: "Cada vez que alguien repite código, se muere un
gatito" 
 Profundizaremos el uso de parámetros.
 Vamos a encontrar patrones que se repiten y aprenderemos a
utilizarlos.
 Comenzaremos a usar bolitas para representar información. Es decir,
vamos a darle un pequeño dominio a nuestros problemas, usando las
bolitas para representar otra cosa: personas, autos, flores, ¡lo que se te
ocurra!

Ejercicios

  1. Entrando en calor... ¡Volviendo!


  2. Una diagonal más ancha
  3. Pongamos... ¡Todo lo que queramos!
  4. Día de la Memoria
  5. Escribir cualquier fecha
  6. Movamos... ¡Todo lo que queramos!
  7. Los números del reloj
  8. Una línea heavy
  9. Guarda con la guarda
  10. Una guarda en L

Ejercicio 1: Entrando en calor... ¡Volviendo!


En la guía anterior, vimos que se podía usar repeat para hacer algo muchas
veces. Hicimos un ejemplo que se llamaba Diagonal4Azul, que era más o menos
así:

procedure Diagonal4Azul(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}

¿Te animás a definir el procedimiento Diagonal4AzulVolviendo? Este


procedimiento debería hacer lo mismo que Diagonal4Azul, pero tiene que
dejar el cabezal en la posición inicial. Recordá que podés invocar todo lo que
está en la Biblioteca sin necesidad de volver a definirlo. 

Biblioteca
procedure Diagonal4Azul(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}

0 1 2 3 4

4 4

1
3 3
1
1
2 2

1
1 1 1

1
0 1 0

0 1 2 3 4

procedure Diagonal4Azul(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
procedure Diagonal4AzulVolviendo(){
repeat(4){
Mover(Oeste)
Mover(Sur)
Poner(Azul)
}
}
}

 ¡Ups! Tu solución no se puede ejecutar


Resultados:

[7:1]: Se esperaba un comando.


Se encontró: la palabra clave "procedure".

procedure Diagonal4Azul(){ (debería ir asi) procedure Diagonal4AzulVolviendo() {


repeat(4){ Diagonal4Azul()
Poner(Azul) repeat(4){
Mover(Este) Mover(Oeste)
Mover(Norte) Mover(Sur)
Diagonal4AzulVolviendo(){ }
repeat(4){ }
Mover(Oeste)
Mover(Sur)
Poner(Azul)
}
}
}

¡Ups! Tu solución no se puede ejecutar


Objetivos que no se cumplieron:

  Diagonal4AzulVolviendo debe usar repeat
  Diagonal4AzulVolviendo debe utilizar Diagonal4Azul
  la solución debe declarar Diagonal4AzulVolviendo

Resultados:

[19:11]: El procedimiento "Diagonal4Azul" está definido dos veces: en (?):1:1 y en (?):19:1.

Solucion de la consulta pero tiene error

procedure Diagonal4AzulVolviendo(){
repeat(1){
Diagonal4Azul()}
IrAlBorde(Oeste)
IrAlBorde(Sur)
}
Eric Hernán H. hace 10 meses
Cuando ingreso este procedimiento la devolución de la actividad indica que
funciona pero no está aprobada porque tiene un 'repeat' de más. Sin
embargo, cuando se lo saco (el que esta en la línea 2) la devolución de la
actividad me indica que no está aprobada porque no tiene ningún 'repeat'. A
qué puede deberse este problema?
Le estás diciendo "repeat (1)", y eso es innecesario, Borrá eso y quedaría
bien.
A tener en cuenta, el repeat usalo de (2) para arriba.
Mayra Nerina M. hace 10 meses
¡Hola Eric! ¿Como estas? Como dijo Guillermo arriba, el repeat tiene sentido
cuando es de 2 para arriba. Lo que sucede es que usaste IrAlBorde (Que no
está para nada mal, incluso es mas rapido) pero el ejercicio busca que hagas
el recorrido de la vuelta moviendote por los casilleros con el repeat . Si no
quedó claro, o surge otra consulta, no dudes en preguntarnos. ¡Saludos!

Otra solución dada en la consulta con


error
procedure
Diagonal4AzulVolviendo(){
Diagonal4Azul()
repeat (3){
Mover(Oeste)
Mover(Sur)
}
}
Liliana P. hace 10 meses
Buen dia yo uso repeat (3) porque entiendo q el cabezal queda en 3;3 y
debo mover al oeste 3 veces para quedar en 3;0 y de ahi moverme 3 veces al
sur para llegar a 0;0, no entiendo por qué  me lo mueve 2 veces, podran
explicarme? gracias
Guillermo Ignacio B.  MENTORÍA  hace 10 meses
¡Hola Liliana! En primer lugar fijate que la palabra procedure y el nombre del
procedimiento están en líneas distintas. Esto no genera un error pero
conviene que estén en la misma línea. Por otro lado fijate que en el
procedimiento Diagonal4Azul, que está definido en la Biblioteca, se repiten 4
veces los comandos Mover(Este) y Mover(Norte), por lo que el cabezal queda en
4;4, entonces para regresarlo al casillero inicial hay que mover el cabezal 4
veces al Sur y al Oeste.

SOLUCION CORRECTA
procedure Diagonal4AzulVolviendo(){
Diagonal4Azul()
repeat (4){
Mover(Oeste)
Mover(Sur)
}
}

USAMOS LO QUE TENIAMOS EN LA BIBLIOTECA Y QUE REDEFINIMOS PARA ESTE EJERCICIO


procedure Diagonal4Azul(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}

¡Muy bien! Tu solución pasó todas las pruebas


0 1 2 3 4
4 4

3 1
3

2 1
2

1 1
1

0 1
0

0 1 2 3 4

Tablero final
0 1 2 3 4
4 4
1
3 3
1
1
2 2
1
1
1 1
1
1
0 0
1
0 1 2 3 4

¡Bien!
Tenés que acostumbrarte a pensar... ¿No podría usar algún procedimiento
que ya definí antes?

Una gran ventaja de los procedimientos es que, una vez que están escritos,
podés guardártelos para volver a usarlos. Cuando ejercitás en
Mumuki, nosotros ya los guardamos por vos y te dejamos
la Biblioteca lista para usar, pero en la vida real ese trabajo vas a tener que
hacerlo vos. 

Ejercicio 2: Una diagonal más ancha


Sigamos probando tus habilidades para reutilizar...
Ahora, tenés que hacer este dibujo:

El procedimiento debe llamarse BandaDiagonal4. ¡Ojo! prestá atención a


la posición final del cabezal.
 ¡Dame una pista!

De nuevo, pensá: ¿qué procedimiento que definiste antes puede ayudarte a


resolver parte de esta tarea?

0 1 2 3 4

6 6

1
5 1 5

1 1
4 1 1 4

1 1 1
3 1 1 1 3

1 1 1
2 1 1 1 2

1 1
1 1 1 1

1
0 1 0

0 1 2 3 4

Biblioteca
procedure Diagonal4AzulVolviendo(){
Diagonal4AzulAvanzando()
repeat(4){
Mover(Sur)
Mover(Oeste)
}
}

procedure Diagonal4AzulAvanzando(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}

YO DI ESTA SOLUCION
procedure BandaDiagonal4(){
repeat(4) {
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}
procedure BandaDiagonalVolviendo(){
BandaDiagonal4()
repeat(4){
Mover(Sur)
Mover(Oeste)
}
}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:
  BandaDiagonal4 debe utilizar Diagonal4AzulVolviendo

Se obtuvo un tablero distinto al esperado.

Tablero final obtenido


0 1 2 3 4

6 6

5 5

4 4

1
3 1 3

1
1
1 1
2 2

1 1
1 1
1
1
0 1 0

0 1 2 3 4

Solucion errónea en la consulta


procedure BandaDiagonal4() {
repeat(2) {
Diagonal4AzulAvanzando()
Diagonal4AzulVolviendo()
Mover(Norte)
}
Mover(Sur)
Mover(Sur)
}

Hola Martin! Fijate siempre en la Biblioteca las funciones, te suelen dar


informacion.. EN ESTE CASO!
procedure Diagonal4AzulVolviendo(){
Diagonal4AzulAvanzando()
repeat(4){
Mover(Sur)
Mover(Oeste)
}
}
fijate que Diagonal4AzulVolviendo() ya utiliza Diagonal4AzulAvanzando asi que vos no
deberias usarla, porque si no, se ejecuta 2 veces (cayendose del tablero.)

OTRA SOLUCION MAL EN LA CONSULTA


procedure BandaDiagonal4(){
repeat(2){
Diagonal4AzulVolviendo()
Mover(Norte)
Diagonal4AzulVolviendo()

}
Mover(Sur)
Mover(Sur)
}

Diana L.  MENTORÍA  hace 10 meses


¡Hola Alberto!
Si bien las bolitas están en los lugares correctos, si te fijás en la banda del
medio, hay dos bolitas en cada celda en lugar de una, por eso el error. Como
dentro del repeat está dos veces Diagonal4AzulVolviendo(), en lugar de realizar 3
diagonales realiza 4. Intentá quitar uno por fuera del repeat.

BIBLIOTECA
procedure BandaDiagonal4(){ procedure Diagonal4AzulVolviendo(){
repeat(2){ Diagonal4AzulAvanzando()
Diagonal4AzulVolviendo() repeat(4){
Mover(Norte) Mover(Sur)
} Mover(Oeste)
{ }
Diagonal4AzulVolviendo() }

}
Mover(Sur)
Mover(Sur)
}
 ¡Muy bien! Tu solución pasó todas las pruebas

Tablero Inicial
0 1 2 3 4

6 6

5 5

4 4

3 3

1
2 2

1 1
1 1

1
0 0

0 1 2 3 4

Tablero Final
0 1 2 3 4

6 6

1
5 1 5

1 1
4 1 1 4
1 1 1
3 1 1 1 3

1 1 1
2 1 1 1 2

1 1
1 1 1 1

1
0 1 0

0 1 2 3 4

Ejercicio 3: Pongamos... ¡Todo lo que


queramos!
Ahora que tenemos una idea de reutilización, y practicamos repetición,
vamos a definir un procedimiento que nos va a servir de acá en adelante.

Necesitamos un procedimiento que nos ayude a poner muchas bolitas. Sí,


podríamos simplemente usar un repeat para lograrlo, pero como es una tarea
re-común que vamos a hacer un montón de veces, vamos a preferir definir
un procedure llamado PonerN. Nuestro procedimiento debe poner la cantidad
de bolitas indicada de un color dado.

Por ejemplo, PonerN(3, Azul) haría esto:


0 1

1 1

3
0 3 0

2 0
Definí el procedimiento PonerN(cantidad, color).
1

procedure PonerN(3,Azul){
Poner(Azul)
Poner(Azul)
Poner(Azul)
}
¡Ups! Tu solución no se puede ejecutar
Resultados:
[1:18]: Se esperaba un identificador con minúsculas.
Se encontró: un número.

SOLUCION EN LA CONSULTA CON


ERROR
procedure PonerN(cantidad, color) {
repeat(10) {
Poner(color)
}
}
Maria Jimena Z. hace 10 meses
Hola! le estoy dando vueltas al repeat y no entiendo porque no pasa el test..
Lei algunas consultas, similares a lo que consulto y no logro descifrarlo cual
es el error. Muchas gracias!

Carlos Jorge T. hace 10 meses


Hola María Jimena... Dentro de tu función no estás usando el parámetro
cantidad. Usaste un número fijo en su lugar. Fijate dónde debe ir ese
parámetro.

procedure PonerN(cantidad, color) {


repeat(cantidad) {
Poner(color)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

0 1

1 1

3
0 3 0

2
0 1
0 1

1 1

3
0 4 0

2
0 1

Aunque quizás no veas todavía la utilidad de este procedure que creamos, te


contamos dos aspectos que es importante tener en cuenta al programar:

 reutilización de código: como poner muchas bolitas es una tarea


común, está bueno tener un procedimiento que lo resuelva: lo
escribimos una vez y lo usamos para siempre;

 declaratividad: cuando tengamos que resolver un problema más


complejo, tener este procedimiento nos va a ayudar a pensar a más
alto nivel, ya que no vamos a tener que preocuparnos
por cómo poner muchas bolitas sino en qué queremos construir con
ellas.

Ejercicio 4: Día de la Memoria


Muchas veces vamos a usar el tablero de Gobstones como memoria, o sea,
para recordar algo importante que vamos a necesitar más adelante.

¿Qué podríamos representar con bolitas? Por ejemplo una fecha. Una fecha
que debemos recordar es el 24 de marzo de 1976, hoy constituido Día de la
Memoria por la Verdad y la Justicia en Argentina.

El objetivo, entonces, es definir un procedimiento DiaDeLaMemoria():

 En la celda actual, poné 24 bolitas Azules, que representan el día.


 En la celda inmediatamente al Este, poné 3 bolitas Verdes, que representan el
mes.
 En la celda a continuación, poné 1976 bolitas Negras, representando el año.

0 1 2
24
*
0 0
3

2
0 1

 ¡Dame una pista!

Ya que definimos PonerN(cantidad, color), ahora podemos invocarlo, ¿no?.

BILIOTECA

procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}

procedure DiaDeLaMemoria(cantidad,color){
repeat(cantidad){
Poner(color)
Mover(Este)
}
{
repeat(cantidad){
Poner(color)
Mover(Este)
}
{
repeat(cantidad){
Poner(color)
}
}
¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 Parece que te falta una } que cierre el último procedure.

 Detalles
Resultados:
[18:1]: Se esperaba un comando.
Se encontró: la palabra clave "program".

Otra solución mia mal


procedure DiaDeLaMemoria(cantidad,color){
repeat(24){
Poner(Azul)
Mover(Este)
}

repeat(3){
Poner(Verde)
Mover(Este)
}
repeat(1976){
Poner(Negro)
}
}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:
  DiaDeLaMemoria debe utilizar PonerN
  DiaDeLaMemoria no debe usar repeat
  La solución parece tener un error de tipeo: debe usar PonerN, pero
usa Poner. ¿Quizás quisiste decir PonerN?
El programa hizo BOOM.
BOOM
[12:4]: El procedimiento "DiaDeLaMemoria" espera recibir 2 parámetros pero se lo invoca con ningún
argumento.

SOLUCION NO VALIDA EN LA CONSULTA


procedure DiaDeLaMemoria(){
PonerN(cantidad, color)
Mover(Este)
PonerN(cantidad, color)
Mover(Este)
PonerN(cantidad, color)
}
Matias R. hace 10 meses
Me indica que la variable cantidad no esta declarada. No entiendo el porqué
de esto ya que la variable cantidad ya esta siendo declarada cuando invoco
al procedimiento PonerN()

Agustín S. hace 10 meses


Tenes que darle un número a esa cantidad y un color. Como dice en la
consigna: En la celda actual, poné 24 bolitas Azules, que representan el día.
En la celda inmediatamente al Este, poné 3 bolitas Verdes, que representan
el mes. En la celda a continuación, poné 1976 bolitas Negras, representando
el año.

Sergio Sebastian S. hace 10 meses


Hola Matias.. el procedimiento PonerN( ) lleva 2 argumentos.. la cantidad y el
color.. por cantidad tenes que ponerlo vos manualmente Los numeros
deberian ser 24/3/1976

Otra solución con pequeños errores


procedure DiaDeLaMemoria(){PonerN(24, Azul) Mover(Este) PonerN(3,
Verde) Mover(Este) PonerN(1974, Negro) }

Agustin A. hace 22 días


Hola, no entiendo porque el resultado es igual a que me pide el ejercicio y
me dice que mi solucion no paso la prueba.
Catalina F.  MENTORÍA  hace 22 días
¡Hola Agustin!
Casi terminamos, lo que pasa es que la cantidad de bolitas a colocar en la
última celda es 1976 Un consejito: utilicemos el botón Dar formato ubicado a
la derehca de nuestra solución para poder visibilizar mejor el código. Una
estructura muy clara de un procedure puede ser:

procedure DiaDeLaMemoria(){
//Nuestro código va acá
}

Solucion correcta del ejercicio


procedure DiaDeLaMemoria(){
PonerN(24,Azul)
Mover(Este)
PonerN(3,Verde)
Mover(Este)
PonerN(1976,Negro)
}
¡Muy bien! Tu solución pasó todas las pruebas
inicial

0 1 2

24 *
0 0
3

2
0 1

final
0 1 2
24
*
0 24 3 0
3 2

0 2
1
2

¿Sabías que Azul es una expresión literal? ¡También 1976! También


son expresiones literales: Verde, Negro, 3 y 24.

Cuando usamos un procedimiento que tiene parámetros como


PonerN, PonerN(56, Rojo) tenemos que enviarle valores como argumento. ¡Y
las expresiones sirven para eso!

Ejercicio 5: Escribir cualquier fecha


Ahora que ya escribimos una fecha particular, hagamos un procedimiento
que sirva para escribir cualquier fecha.

Definí el procedimiento Fecha(dia, mes, anio), que recibe los tres


valores correspondientes, y escribe la fecha que representan, de esta manera:
 En la celda actual, tantas bolitas azules para representar el día.
 En la celda inmediatamente al Este, tantas bolitas Verdes para representar el
mes.
 En la celda a continuación, tantas bolitas Negras para representar el año.
Por ejemplo, Fecha(12, 8, 1990) produciría algo así:

0 1 2
24
*
0 12 8 0
3 2

0 2
1
2

 ¡Dame una pista!


¡Podés resolverlo muy parecido a como lo resolviste en el ejercicio anterior!
Recorda que el día, mes y año representan la cantidad de bolitas azules,
verdes y negras que hay que poner respectivamente.

Biblioteca
procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}

procedure Fecha(dia,mes,anio){
repeat(12){ Aca el error es que se debe poner: Poner(dia,Azul)
Poner(Azul)
}
repeat(8){ Aca igual
Poner(Verde)
}
repeat(1990){ Aca igual
Poner(Negro)
}
}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:

  Fecha debe utilizar PonerN
  Fecha no debe usar repeat

Resultados de las pruebas:


 Se obtuvo un tablero distinto al esperado.

 0 1 2

24
12 *

0 0
8 3
2

2 0 1
2

Otra solución mal


procedure Fecha(){
PonerN(12,Azul)
Mover(Este)
PonerN(8,Verde)
Mover(Este)
PonerN(1990,Negro)
}
Tu solución no pasó las pruebas
Resultados de las pruebas:

 El programa hizo BOOM.

 BOOM
 [9:4]: El procedimiento "Fecha" espera recibir ningún parámetro pero se lo invoca con 3
argumentos.
Otra solución mal
procedure PonerN(){
PonerN(12,Azul)
Mover(Este)
PonerN(8,Verde)
Mover(Este)
PonerN(1990,Negro)
}
 ¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  Fecha debe utilizar PonerN
  la solución debe declarar Fecha

Resultados:

[13:11]: El procedimiento "PonerN" está definido dos veces: en (?):1:1 y en (?):13:1.

SOLUCION DE LA CONSULTA
procedure Fecha (dia, mes, anio) {
PonerN (dia, Azul)
Mover (Este)
PonerN (mes, Verde)
Mover (Este) El error es este porque se debe poner en vez de 26, anio
PonerN (26,Negro)
}
Yair Horacio D. hace 9 días
Pude resolver el ejercicio, volví a hacerlo mal para poder sacarme una duda. Cuándo se usan los
argumentos? Para qué sirven? No entiendo cuando usarlos... :/

Guillermo Ignacio B.  MENTORÍA  hace 8 días


¡Hola Yair! Antes que nada los argumentos y los parámetros son cosas
distintas, relacionadas, pero distintas. Los parámetros se utilizan al definir un
procedimiento (o una función) dónde se le va a asignar un valor cuando se
ejecute. Este valor es el argumento. Una de las ideas de usar parámetros es
darle más versatilidad al código, es decir, poder usarlo de forma más flexible.
En este caso, por ejemplo, tenemos 3 parámetros, dia, mes y anio, que
representan una cantidad de bolitas, por lo cual, cuando se ejecute (dentro
del program o si es invocado dentro de otro procedimiento), le vamos a poder
dar el valor que nosotros queramos (o necesitemos), por ejemplo:
program {
Fecha (13,2,1950)
Fecha (16,8,2005)
}

En este caso, los argumentos serían 13, 2 y 1950 para la primera invocación y
16, 8 y 2005 para la segunda. Si no utilizamos parámetros en este caso
tendríamos que hacer dos procedimientos (que además se deberían llamar
diferentes porque no se pueden definir dos procedimientos con el mismo
nombre) para obtener el mismo resultado, lo cual sería muy engorroso. Y si
quisiéramos otra fecha tendríamos que definir otro procedimiento y así
sucesivamente.

SOLUCION CORRECTA DEL EJERCICIO


procedure Fecha (dia, mes, anio) {
PonerN (dia, Azul)
Mover (Este)
PonerN (mes, Verde)
Mover (Este)
PonerN (anio,Negro)
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

0 1 2
24 *
0 12 8 0
3
2

2 0 1
2

Otros valores
0 1 2
24 *
0 4 6 0
3
2
0 2
1
2

Dos cuestiones teóricas para pensar de este ejercicio:


1. Puede parecerte que estás repitiendo código con el ejercicio anterior.
¡Es cierto! Para arreglarlo, deberías volver al ejercicio anterior y allí usar
el procedimiento Fecha. 
2. Acá vemos que hay otro tipo de expresiones: ¡Los parámetros!
Al usar un procedimiento, puedo enviarle tanto otros parámetros
como literales: PonerN(dia, Azul). Recordá en este caso que los nombres
de los parámetros sólo nos sirven a los humanos, para la máquina sólo
importa el orden.

Ejercicio 6: Movamos... ¡Todo lo que


queramos!
Definí un procedimiento MoverN(cantidad, direccion) que haga que el cabezal se desplace
la cantidad especificada de veces en la dirección indicada.
Por ejemplo, MoverN(3, Oeste) provocaría:

Inicial Final
0 1 2 3 0 1 2 3

2 2 2 2

1 1 1 1

0 0 0 0

0 1 2 3 0 1 2 3

 ¡Dame una pista!

¡Es muy parecido al PonerN que hicimos hace poco!

procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}

ESTA SOLUCION MIA ESTA MAL


procedure MoverN(cantidad, direccion){
repeat(3){
MoverN(3,Oeste)
}

}
¡Ups! Tu solución no se puede ejecutar

RESOLUCION MAL EN LA CONSULTA


procedure MoverN(cantidad,dirección){
repeat (2){
Mover(Este) }
}
Roque Sergio P. hace 9 días
No logro resolverlo. Aquí paré, pero intenté de mil maneras. Lo logro en el
tablero superior pero no en el inferior. Seguramente estoy mareado, pero no
logro entender las explicaciones.

Ana C. hace 9 días


MoverN funciona con 2 parametros (cantidad, direccion) seria repetir mover
la cantidad de veces necesarias en la direccion indicada
pero no la que te da como ejemplo, si no que sirva para cualquier caso
toma el ejemplo de PonerN procedure PonerN(cantidad,color)
{ repeat(cantidad){ Poner(color) } } en lugar de PonerN, tenemos que MoverN

RESOLUCION MAL EN LA CONSULTA


procedure MoverN(cantidad,direccion)( ){

repeat(cantidad){

MoverN(3,Oeste)
}

Diana L.  MENTORÍA  hace 10 meses


¡Hola Analía!
Como regla, no podemos invocar un procedimiento dentro del mismo, es
decir que no podemos usar MoverN dentro de MoverN.
Casi casi está la solución de todas formas. Queremos movernos cantidad de
veces hacia direccion. El repeat(cantidad) ya te da la repetición de una acción por
la cantidad, ¿cuál sería esa acción? Sabemos que tenemos que movernos, y
tenemos un procedimiento que nos regala el movimiento: Mover. El problema
ahora es que Mover necesita que le demos una direccion hacia donde
moverse ¿tenemos la direccion en algún lugar? ¡Claro! En los parámetros:
direccion.
Intentá seguir esa lógica

Resolucion mal
procedure MoverN(cantidad,direccion){
repeat(3){
MoverN(3,Oeste)
}
}

Resolucion bien
procedure MoverN(cantidad, direccion){
repeat(cantidad){
Mover(direccion)
}
}

Solucion Correcta
procedure MoverN(cantidad, direccion){
repeat(cantidad){
Mover(direccion)
}
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 Tablero inicial
0 1 2

0 0

0 1 2
 Tablero final
0 1 2

0 0

0 1 2
Tablero inicial
0

1 1

0 0

0
Tablero final
0

1 1

0 0

¡Perfecto!

Recordamos entonces que entre los paréntesis del repeat no sólo pueden ir


números (como 7 o 42), sino también otros tipos de expresiones que
denoten valores numéricos (como cantidad en este caso).

Ejercicio 7: Los números del reloj


¡Ya sabés Kung Fu!

Ahora, tenés que mostrarnos que podés dibujar un reloj. Lo que haremos por
ahora es solamente poner los números que aparecen en un típico reloj de
agujas:
 El 12 arriba,
 El 3 a la derecha,
 El 9 a la izquierda, y
 el 6 abajo.

Definí un procedimiento DibujarReloj(radio) que ponga los números del reloj


como se indica arriba: alrededor del casillero actual. El tamaño del reloj se
indica con el radio que recibís como parámetro: mientras más grande es el
radio, más alejados están los números del centro.
Dado el siguiente program:

program {
DibujarReloj(2)
}

El reloj resultante es así:

0 1 2 3 4
12
4 4
12

3 9 3

2
9
2 3 3 2

1 2 1
6
0 0

0 1
6

2
2 3 4

¡Dame una pista!

¡Dividí en subtareas!

No vale hacer un procedimiento que sea un choclo, con muchos comandos


uno abajo del otro, tiene que ser legible y cortito.

Pensá como combinar PonerN y MoverN, los cuales podés encontrar en la


siempre útil Biblioteca.
Biblioteca.

procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}
procedure MoverN(cantidad,direccion){
repeat(cantidad){
Mover(direccion)
}
}

SOLUCION
procedure Agregarhora(hora,direccionIdadireccionVuelta,radio){
(usar esto de la biblioteca)

MoverN(radio, direccionIda)

PonerN(hora,Rojo)

MoverN(radio, direccionVuelta)
}
procedure DibujarReloj(radio){ este puede ser 2, 4 según distancia
Agregarhora(12, Norte, Sur, radio)
Agregarhora(3, Este, Oeste, radio)
Agregarhora(9, Oeste, Este, radio)
Agergarhora(6, Sur, Norte, radio)
}

¡Ups! Tu solución no se puede ejecutar

[11,3]El procedimiento “Agergarhora” no esta definido es Agregarhora


Y ASI QUEDARIA BIEN EL EJERCICIO
Otro error
procedure Agregarhora(hora,direccionIda,direccionVuelta,radio){
MoverN(radio, direccionIda)
PonerN(hora,Rojo)
MoverN(radio,direccionvuelta)
}
procedure DibujarReloj(radio){
Agregarhora(12,Norte,Sur,radio)
Agregarhora(3,Este,Oeste,radio) vuelta debe ir en mayúscula Vuelta
Agregarhora(9,Oeste,Este,radio)
Agregarhora(6,Sur,Norte,radio)
}
Tu solución no pasó las pruebas
Resultados de las pruebas:

  El programa hizo BOOM.


 BOOM
 [4:16]: La variable "direccionvuelta" no está definida.

SOLUCION CORRECTA
procedure Agregarhora(hora,direccionIda,direccionVuelta,radio){
MoverN(radio, direccionIda)
PonerN(hora, Rojo)
MoverN(radio, direccionVuelta)
}
procedure DibujarReloj(radio){
Agregarhora(12, Norte, Sur, radio)
Agregarhora(3, Este, Oeste, radio)
Agregarhora(9, Oeste, Este, radio)
Agregarhora(6, Sur, Norte, radio)
}
Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
Inicial
0 1 2 3 4

4 4

3 3

2 2
9 3

1 1

0 0
6

0 1 2 3 4

Tablero final
0 1 2 3 4
12
4 4
12

3 3

9 3
2 2
9 3

1 1

6
0 0
6

0 1 2 3 4

Tablero inicial
0 1 2

2 2

1 1

0 0

0 1 2

Tablero final
0 1 2
2 12 2
12

9 3
1 1
9 3

6
0 0
6

0 1 2
¿Te fijaste? Estamos usando bolitas para representar la hora de un reloj. Al
programar, usamos las abstracciones que tenemos para modelar cosas del
mundo real.
Y como siempre, es muy importante dividir el problema en subtareas. Y si
puedo no repetir código, ¡Aún mejor!

Antes de pasar al siguiente ejercicio preguntate: ¿repetí código?

Ejercicio 8: Una línea heavy


El procedimiento LineaEstePesada(peso, color, longitud) debe dibujar hacia
el Este una línea del color dado, poniendo en cada celda tantas bolitas como
indique el peso. La linea debe ser tan larga como la longitud.

A modo de ejemplo, LineaEstePesada(3, Verde, 5) debería dibujar una línea verde,


ocupando cinco celdas hacia el Este y poniendo tres bolitas en cada una de
ellas:

0 1 2 3 4

1 1

0 3 3 0
3 3 3 3 3 3 3
3

2
0 2
1 2
2 2
3 4 2
Definí el procedimiento LineaEstePesada(peso, color, longitud). Tené en
cuenta que el cabezal debe regresar a la posición inicial. Para eso vas a tener
que invocar MoverN.
Biblioteca

procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}
procedure MoverN(cantidad,direccion){
repeat(cantidad){
Mover(direccion)
}
}

Solucion con Error que hice yo

1. procedure LineaEstePesada(peso, color, longitud){


2. repeat(peso){
3. Poner(color)
4. PonerN(longitud)
5. }
6. }
7.
8. procedure MoverN(longitud,direccion){
9. repeat(longitud){
10.MoverN(direccion)
11.}
12.}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  LineaEstePesada debe utilizar MoverN

Resultados:

[25:11]: El procedimiento "MoverN" está definido dos veces: en (?):8:1 y en (?):25:1.


Ejercicio resuelto en la consulta con error
1. procedure LineaEstePesada(peso, color, longitud){
2. repeat(longitud) {
3. PonerN(peso, color)
4. Mover(Este)
5. }
6. }
7. MoverN(longitud, direccion) {
8. repeat(longitud) {
9. Mover(Oeste)
10.}
11.}
12.}
Julieta Agustina F. hace 15 días
Hola! No puedo volver el cabezal hacia atrás porque me dice que me salgo
del tablero, por otro lado probé así pero me dice que hay un indicador con
mayúscula y no puedo identificar cual es, creo que hay más de un error :(
Iván Adrián A. hace 15 días
Hola! La línea 6 cerró el procedimiento.
Julieta Agustina F. hace 15 días
Gracias! ya la borré pero por algun motivo aunque use la longitud para
volver el cabezal me dice que me salgo del tablero
Iván Adrián A. hace 15 días
A "Mover" de la línea 4 le faltaría que cantidad de celdas mueve, vendría
mejor un MoverN. Al final solo con la linea 7 alcanza ya que solo debés
volver en la dirección contraria.
Iván Adrián A. hace 15 días
MoverN del repeat va de a uno al Este. El siguiente MoverN va afuera del
repeat y solo se asigna dirección y no longitud.
Camila C.  MENTORÍA  hace 15 días
Hola Julieta. ¿Cómo estás? Estás por buen camino. El detalle está en los
movimientos que hacemos para retroceder a la celda inicial, para esto
podemos usar procedimiento MoverN que ya tenemos definido, la longitud
será el parámetro ingresado y la dirección en este caso sería Oeste, porque
al ser una línea dibujada hacia el Este para retroceder iríamos a la dirección
contraria. De esta manera, usando el MoverN no sería necesario el repeat y el
Mover(Oeste) de la línea 8 y 9, ya que esto lo indicaremos con el MoverN.
También, fijate las llaves, habría una de más suelta en tu código.

OTRA SOLUCION CON ERROR


1. procedure LineaEstePesada(peso, color, longitud) {
2. repeat(longitud) {
3. PonerN(peso,color)
4. MoverN(1,Este)
5. }
6. MoverN(7,Oeste)
7. }

Juan Ignacio E.  MENTORÍA  hace 3 días


¡Hola Sergio!
Estás muy cerca de la solución, repasemos qué nos está pidiendo el ejercicio:
Debemos definir un procedimiento llamado LineaEstePesada(peso, color, longitud)
que debe dibujar hacia el Este una línea del color dado, poniendo en cada
celda tantas bolitas como indique el peso y que la línea debe ser tan larga
como longitud. Además nos dice el cabezal debe regresar a la posición inicial.
Ahora si observamos los Resultados Tu solución no pasó las pruebas Resultados de las
pruebas: El programa hizo BOOM [20:5]: No se puede mover hacia la dirección Oeste: cae
afuera del tablero. Vemos que el estamos cayendo afuera del tablero en el caso
de prueba en que la longitud es 4 pero el procedimiento funciona para cuando
longitud es 7, y esto se debe a que en el código propuesto le estamos
pidiendo al cabezal que vuelva hacia el Oeste 7 posiciones
independientemente de cuánto (longitud) se movió hacia Este, debería
moverse hacia el Oeste lo mismo que se movió al Este, corrigiendo eso,
debería funcionar para todos los casos
Además no hace falta usar MoverN cuando sólo nos movemos 1posición, para
eso ya existe la función Mover

Solución no valida
1. procedure LineaEstePesada(peso, color, longitud) {
2. repeat(longitud) {
3. PonerN(peso,color)
4. Mover(Este)
5. }
6. MoverN(4,Oeste)
7. }
Tu solución no pasó las pruebas
Resultados de las pruebas: esta esta bien

0 1 2 3 4

1 1

0 0
3 3 3 3 3

0 1 2 3 4

0 1 2 3 4

1 1

0 3 3 0
3 3 3 3 3 3 3

2
0 2
1 2
2 2
3 4

Se obtuvo un tablero casi igual al esperado, pero el cabezal no coincide.


Tablero inicial esta esta mal

0 1 2 3 4 5 6 7

0 0

7
0 1 2 3 4 5 6

Tablero final

0 1 2 3 4 5 6 7

0 3 3 3 3 3 3 3 0

2 2 2 0
2 1 2 3 2
4
2
5
2
6
7

Solucion con error


1. procedure LineaEstePesada(peso, color, longitud){
2. repeat(longitud){
3. PonerN(peso, color)
4. MoverN(Este) (seria poniendo esto (1,Este)
5. }
6. MoverN(longitud, Oeste)
7. }
Tu solución no pasó las pruebas
Resultados de las pruebas:

 El programa hizo BOOM.

 BOOM

 [4:3]: El procedimiento "MoverN" espera recibir 2 parámetros pero se lo invoca


con un argumento.

SOLUCION CORRECTA
1. procedure LineaEstePesada(peso, color, longitud){
2. repeat(longitud){
3. PonerN(peso, color)
4. MoverN(1,Este)
5. }
6. MoverN(longitud, Oeste)
7. }

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

0 1 2 3 4

1 1

0 0
3 3 3 3 3
0 1 2 3 4

0 1 2 3 4

1 1

0 3 3 0
3 3 3 3 3 3 3

2
0 2
1 2
2 2
3 4

0 1 2 3 4 5 6 7

0 0

7
0 1 2 3 4 5 6

Tablero final

0 1 2 3 4 5 6 7

0 3 3 3 3 3 3 3 0

02 2
1
2
2
2
3 2
4
2
5
2
6
7

¿Viste que se pueden reusar MoverN y PonerN en varios lugares?

¡Son muy útiles!

Ejercicio 9: Guarda con la guarda


Bueno, estamos en tiempo para algún ejercicio integrador...

Definí un procedimiento GuardaDe5(), que haga una "guarda" de 5 azulejos (como las que
decoran las paredes). Cada azulejo está conformado por 1 bolita verde, 5 negras y 9 rojas.
0 1 2 3 4 5
1 1

5 5 5 5 5

1 5 1 1 1 1
0 5 5 0
1 1 1 1 1 1 5
9
9 1
9
5 9 9 9

9 9 9 9 9
1 9 1 1 1 1

1 9
1 1 1 1
0 1 2 3 4 5

¡Dame una pista!


No te olvides de dividir en subtareas y además de considerar el caso borde.
¡A no repetir código! Cada azulejo puede resolverse con un procedimiento...
BIBLIOTECA

procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}

Solucion no valida
procedure GuardaDe5(cantidad, color){
repeat(cantidad){
Poner(color)
Mover(Este)
}
}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:

  GuardaDe5 debe utilizar PonerN
  La solución parece tener un error de tipeo: debe usar PonerN, pero
usa Poner. ¿Quizás quisiste decir PonerN?

El programa hizo BOOM.


BOOM
[8:4]: El procedimiento "GuardaDe5" espera recibir 2 parámetros pero se lo invoca con ningún
argumento.

RESOLUCION NO VALIDA DE LA
CONSULTA
1. procedure AzulejoTric(){
2. PonerN(5,Negro)
3. PonerN(9,Rojo)
4. PonerN(1,Verde)
5. Mover(Este)
6. }
7. procedure GuardaDe5(){
8. repeat(5){
9. AzulejoTric()
10.}
11.IrAlBorde(Este)
12.}

Laritza L. hace 4 meses

Ya lo he intenado de varias maneras, si en el repeat pongo 5 me hace boom


y si pongo 4 me falta una celda, ya no se como hacerle. Ayuda

Ariel Alejandro M. hace 4 meses

Hola ¿Qué tal Laritza? Lo que has hecho está muy bien, te felicito. Solo que
te estarías olvidando de considerar el "caso borde". Por ejemplo, cuando
repetís por quita vez "AzulejoTric()", te pone la cantidad que le indicaste de
bolas negras, rojas y verdes, y despues le "decís" que vaya hacia el Este. Esto
ultimo no sería un problema para tableros que contengan más de 5
columnas (cantidad de casilleros horizonales). El problema es que cuando
tenés un tablero con justo 5 columnas, el cabezal intentará irse hacia el Este
(en el ultimo "repeat"), y al no poder realizar esa operación (porque no hay
más casilleros hacia el Este), el programa hará BOOM! Para solucionar esto,
debes procesar el último caso por separado. Esto se llama "El caso borde".
Para recordar que es esto, podés ir al ejercicio Nº10 de la Lección Nº4
llamada: "El caso borde". Espero haberte sido de ayuda ¡Saludos!

Catalina F.  MENTORÍA  hace 4 meses

¡Hola Laritza!

  Como bien dice Ariel, nos ayudaría mucho considerar manejar el último
caso de poner bolitas y mover por fuera de nuestro repeat. Esto quiere decir
que en el repeat estamos moviendo hacia el Este cinco veces, cuando
solamente deberiamos de mover cuatro. ¿Cómo lo solucionamos? Tenemos
varias formas distintas:

  1. Un primer acercamiento es dejar AzulejoTric como está y solamente hacer


un repeat por cuatro. Esto quiere decir que tendremos que encargarnos de
que luego del repeat se coloquen las instrucciones

PonerN(5,Negro)
PonerN(9,Rojo)
PonerN(1,Verde)

de nuevo. La única manera que tendremos de lograrlo es colocar estas tres


líneas de código en GuardaDe5 luego de nuestro repeat(4).
Una segunda posibilidad es modificar nuestro procedimiento AzulejoTric
para que solamente coloque azulejos, pero no mueva hacia el Este, y
hacer que GuardaDe5 en el repeatse encargue de invocar a AzulejoTric y
Mover(Este). En este caso debaríamos de invocar a AzulejoTric una vez antes
del repeat y, como en el caso anterior, necesitamos repetir solo cuatro
veces las instrucciones de Mover(Este) y AzulejoTric para que nos quede el
tablero esperado.
Dos recomendaciones:
En Gobstons es una buena idea tener a mano papel y lápiz para reproducir lo
que hará nuestra solución y entender mejor el recorrido de las instrucciones
que estamos escribiendo
Antes de empezar toquemos el botón Dar formato a la derecha de nuestra
solución para acomodar las líneas 3 y 4 :)

SOLUCION NO VALIDA EN LA CONSULTA


1. procedure AzulejoTricolor(){
2. PonerN(5,Negro)
3. PonerN(9,Rojo)
4. PonerN(1,Verde)
5. Mover(Este)
6. }
7. procedure GuardaDe5(){
8. repeat(4){
9. PonerN(5,Negro)
10.PonerN(9,Rojo)
11.PonerN(1,Verde)
12.}
13.IrAlBorde(Este)
14.}
Tu solución no pasó las pruebas

Se obtuvo un tablero distinto al esperado.


Todas las bolitas se ponen en la primera celda y se suman por color

SOLUCION VALIDA. EJERCICIO RESUELTO


1. procedure AzulejoTric(){
2. PonerN(5,Negro)
3. PonerN(9,Rojo)
4. PonerN(1,Verde)
5. }
6. procedure GuardaDe5(){
7. repeat(4){
8. AzulejoTric()
9. Mover(Este)
10.}
11.AzulejoTric()
12.}
¡Muy bien! Tu solución pasó todas las pruebas
0 1 2 3 4 5

1 1

5 5 5 5 5

0 0
9 1 9 1 9 1 9 1 9 1

0 1 2 3 4 5

0 1 2 3 4 5

1 1

5 5 5 5 5

1 5 1 1 1 1 1
0 5 5 5 0
1 1 1 1 1 1 5 1
9
9 1
9
5 9 9 9
9
9 9 9 9 9 9
1 9 1 1 1 1

1 9
1 1 1 1 9
0 1 2 3 4 5

¡Bien! Recordaste cómo considerar el caso borde.


Además, en este ejercicio hay que dividir en subtareas para evitar la repetición de código.
Esto es muy importante a la hora de programar. ¡Asegurate que tu solución no repita
código!

Ejercicio 10: Una guarda en L


Definí un procedimiento GuardaEnL() que haga una guarda en L como
muestra la figura, pero dejando el cabezal en la posición inicial.
0 1 2

9
5
5
2 2
9 9
9 1 1

1
5

1 9 5 1
9 1
9 1 9 5 5
1 9 9
5 5 5

0 9 5 9 9 0
9
9 1 1 9 9 1
9 1 9
9
1 1

1 1 1
0 1 2

La ventaja ahora, es que te regalamos el procedimiento PonerAzulejo.


¡Pero ojo que necesitás dividir en más subtareas!
 ¡Dame una pista!
Para dividir en subtareas vas a tener que pensar si podés partir el problema
principal de dibujar una L en problemas más chicos, y cada una de ellas será
un procedimiento nuevo que deberás usar desde GuardaEnL.

Biblioteca
procedure PonerAzulejo(){
Poner(Verde)
PonerN(5,Negro)
PonerN(9,Rojo)
}
procedure PonerN(cantidad,color){
repeat(cantidad){
Poner(color)
}
}
procedure MoverN(cantidad,direccion){
repeat(cantidad){
Mover(direccion)
}
}

Solucion con error


procedure AzulejoTric(){
PonerN(5,Negro)
PonerN(9,Rojo)
PonerN(1,Verde)
}
procedure GuardaDe3(){
repeat(2){
AzulejoTric()
Mover(Este)
}
AzulejoTric()
}
procedure GuardaenL(){
IrAlBorde(Oeste)
Mover(Norte)
repeat(2){
AzulejoTric()
}
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  GuardaEnL debe usar repeat
  GuardaEnL debe utilizar PonerAzulejo
  GuardaEnL debe utilizar MoverN
  la solución debe declarar GuardaEnL
  Hay que dividir en subtareas. Tené en cuenta qué partes de tu código
se repiten y trasladalas a un nuevo procedimiento.
  La solución parece tener un error de tipeo: debe declarar GuardaEnL,
pero declara GuardaenL. ¿Quizás quisiste decir GuardaEnL?
  La solución parece tener un error de tipeo: debe usar MoverN, pero
usa Mover. ¿Quizás quisiste decir MoverN?
Resultados:

[22:4]: El procedimiento "GuardaEnL" no está definido.

Otra solución mia no valida


procedure Azulejo(){
PonerN(5,Negro)
PonerN(9,Rojo)
PonerN(1,Verde)
}
procedure GuardaenL(){
repeat(2){
Poner(Azulejo)
Mover(Este)
}
Poner(Azulejo)
}
procedure GuardaenL(){
IrAlBorde(Oeste)
MoverN(Norte)
repeat(2){
Poner(Azulejo)
}
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  GuardaEnL debe usar repeat
  GuardaEnL debe utilizar PonerAzulejo
  GuardaEnL debe utilizar MoverN
  la solución debe declarar GuardaEnL
  Hay que dividir en subtareas. Tené en cuenta qué partes de tu código
se repiten y trasladalas a un nuevo procedimiento.
  La solución parece tener un error de tipeo: debe declarar GuardaEnL,
pero declara GuardaenL. ¿Quizás quisiste decir GuardaEnL?

Resultados:

[13:11]: El procedimiento "GuardaenL" está definido dos veces: en (?):6:1 y en (?):13:1.

Otra solución mia con error


procedure Azulejo(){
PonerN(5,Negro)
PonerN(9,Rojo)
PonerN(1,Verde)
}
procedure GuardaenL(){
repeat(2){
Poner(Azulejo)
Mover(Este)
}
Poner(Azulejo)
IrAlBorde(Oeste)
MoverN(Norte)
Poner(Azulejo)
MoverN(Norte)
Poner(Azulejo)
MoverN(Sur)
MoverN(Sur)
}
 ¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  GuardaEnL debe usar repeat
  GuardaEnL debe utilizar PonerAzulejo
  GuardaEnL debe utilizar MoverN
  la solución debe declarar GuardaEnL
  Hay que dividir en subtareas. Tené en cuenta qué partes de tu código
se repiten y trasladalas a un nuevo procedimiento.
  La solución parece tener un error de tipeo: debe declarar GuardaEnL,
pero declara GuardaenL. ¿Quizás quisiste decir GuardaEnL?

Resultados:

[8:11]: El constructor "Azulejo" no está definido. El nombre "Azulejo" es el nombre de un


procedimiento.

Solucion de la consulta no valida para


mejorar
1. procedure GuardaEnL(){
2. PonerAzulejo()
3. repeat(2){
4. MoverN(1,Norte)
5. PonerAzulejo()
6. }
7. IrAlBorde(Sur)
8. repeat(2){
9. MoverN(1,Este)
10. PonerAzulejo()
11. }
12. IrAlBorde(Oeste)
13. }
Ezequiel A. hace 10 meses
Lo que hice yo es poner alguno de los repeat en un procedimiento aparte y
luego llame a ese procedimiento dentro del GuardaEnL(). Por ejemplo el
primer repeat ponelo en un procedure aparte, y luego llamalo (en lugar de
ese repeat)
Daniela M.  MENTORÍA  hace 10 meses
¡Hola Hernán! ¿Como estas? Tu solucion estuvo muy bien pero si te fijas las
lineas 4 y 5 son muy similares a las 9 y 10, lo unico que cambia seria la
direccion en la que te moves. Por lo tanto, podes crear un procedimiento
que realice justo eso y ahi ya estarias dividiendo en subtareas. ¿Se te ocure
como hacerlo?

Otra solución de la consulta a mejorar


1. procedure LineaColorNorte(){
2. PonerAzulejo()
3. Mover(Norte)
4. PonerAzulejo()
5. Mover(Norte)
6. PonerAzulejo()
7. }
8. procedure LineaColorEste(){
9. Mover(Este)
10.PonerAzulejo()
11.Mover(Este)
12.PonerAzulejo()
13.}
14.procedure GuardaEnL(){
15.LineaColorNorte()
16.IrAlBorde(Sur)
17.LineaColorEste()
18.IrAlBorde(Oeste)
19.}
Hola Lourdes! Fijate que en los 2 primeros procedimientos estás
repitiendo códigos que los podés simplificar usando repeat. Y cuando
quieras mover más de una celda en la misma dirección deberías usar
MoverN, eso es lo que te está marcando como error en el ejercicio.

Solucion nueva mia con error


1. procedure LineaColorNorte(){
2. PonerAzulejo()
3. repeat(2){
4. MoverN(Norte)}
5. PonerAzulejo()
6. }
7. procedure LineaColorEste(){
8. repeat(2){
9. MoverN(Este)}
10. PonerAzulejo()
11. }
12. procedure GuardaEnL(){
13. LineaColorNorte()
14. IrAlBorde(Sur)
15. LineaColorEste()
16. IrAlBorde(Oeste)
17. }
Tu solución no pasó las pruebas
El programa hizo BOOM.
BOOM
[4:3]: El procedimiento "MoverN" espera recibir 2 parámetros pero se lo invoca con un argumento.

Solucion correcta del ejercicio


1. procedure MoverAzulejo(num, dir){
2. repeat(num){
3. Mover(dir)
4. PonerAzulejo()
5. }
6. }
7. procedure GuardaEnL(){
8. PonerAzulejo()
9. MoverAzulejo(2, Este)
10.MoverN(2, Oeste)
11.MoverAzulejo(2, Norte)
12.MoverN(2, Sur)
13.}
 ¡Muy bien! Tu solución pasó todas las pruebas
0 1 2

9
5
5
2 2
9 9
9 1 1

1
5

1 9 5 1
9 1
9 1 9 5 5
1 9 9
5 5 5

0 9 5 9 9 0
9
9 1 1 9 9 1
9 1 9
9
1 1

1 1 1
0 1 2

Terminaste Práctica Repetición simple!


¡Muy bien!

En esta guía:

 Reusaste procedimientos definidos anteriormente.


 Usaste repetición.
 Consideraste los casos borde.
 Hiciste un repaso grande de parámetros.
 ¡Evitaste repetir código! 
 Empezaste a usar las bolitas para representar varios dominios:
Fechas, Relojes y Guardas.
 Aprendiste que los literales y los parámetros son expresiones que se
pueden pasar por argumento a los procedimientos.

Expresiones
¿Sepuedenhacerprogramasque sumen cosas? 
¿Y dibujar figuras en distintas direcciones sin tener que especificar cada una
deellas?  
¿Y mirar lo que hay en el tablero? 

Todo eso y (no) mucho más en esta nueva entrega de "aprendiendo a


programar con bolitas de colores". ¡Arrancamos!

Ejercicios

  1. Muchas formas de decir lo mismo


  2. La suma de las partes
  3. ¿Qué se hace antes?
  4. La carrera del salmón
  5. Dos pasos adelante, un paso atrás
  6. Poner al lado
  7. La línea que vuelve
  8. Dibujando una L
  9. Previo a lo siguiente
  10. Siga la flecha
  11. Copiando bolitas
  12. Sacando bolitas

Ejercicio 1: Muchas formas de decir lo


mismo
Cuando nos comunicamos con alguien más, usamos palabras o frases para
describir una idea. Por ejemplo, todas las siguientes expresiones hablan de
lo mismo, aunque lo hacen de distintas formas:

 el número 5; 
 la cantidad de dedos de una mano; 
 la suma entre 3 y 2;   
 el número de continentes que existen en el planeta, según la ONU. 

Todas las frases anteriores hablan del valor cinco, aunque no lo digan de


forma explícita.

Con esta idea e invocando PonerN, creá un programa que ponga cinco bolitas
negras, PERO sin escribir el número 5.

 ¡Dame una pista!

¿Y cómo se escribe una suma o una resta en Gobstones?


Igual que en la vida real.

SOLUCION INCORRECTA HECHA POR MI


program {
Poner(3+2)
Poner(Negro)
}
Tu solución no pasó las pruebas

Ver detalles

Objetivos que no se cumplieron:


  la solución debe utilizar PonerN
  program no debe utilizar Poner
  La solución parece tener un error de tipeo: debe usar PonerN, pero
usa Poner. ¿Quizás quisiste decir PonerN?

Parece que algo no anduvo bien 

No hace falta invocar a Poner en este ejercicio ya que se puede solucionar


con PonerN.
Pero a no desesperar, intentemos otra vez 
El programa hizo BOOM.
BOOM
[2:3]: El parámetro de "Poner" debería ser un color pero es un número.

Otra solución incorrecta mia


program {
PonerN(3+2)
Poner(Negro)
}

Tu solución no pasó las pruebas

Ver detalles

Objetivos que no se cumplieron:

  program no debe utilizar Poner

Eh, ¿qué pasó acá ?


No hace falta invocar a Poner en este ejercicio ya que se puede solucionar
con PonerN.

¡Intentemos de nuevo!
El programa hizo BOOM.

SOLUCION CORRECTA
Solucion Biblioteca
program { procedure PonerN(cantidad, color) {
PonerN(3+2,Negro) repeat(cantidad){
Poner(color)
} }
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Tablero inicial
0 1

1 1

0 0

0 1
Tablero final
0 1

1 1

5
0 0
5
1
0

Algunas variantes válidas:

program {
PonerN(4 + 1, Negro)
}

program {
PonerN(12 - 7, Negro)
}

Y así se nos pueden ocurrir infinitas formas de "decir 5" y sólo una de ellas lo
hace de manera literal (o sea, escribiendo 5).

Ejercicio 2: La suma de las partes


Juguemos un poco más con esto de hacer cuentas.

Definí un procedimiento PonerSuma(x, y) que reciba dos parámetros y ponga la cantidad


de bolitas rojas que surge de sumar x e y.
Ejemplo: PonerSuma(4, 2) debería poner 6 bolitas rojas en la celda actual (porque 6 es el
resultado de sumar 4 y 2).

0 1

1 1

0 6 0
6

0 1

Solucion mia mal


procedure PonerSuma(cantidad,color){
Suma(x+y)
Poner(color)
}
 ¡Ups! Tu solución no se puede ejecutar

Ver detalles

Objetivos que no se cumplieron:

  PonerSuma debe utilizar PonerN
  PonerSuma no debe utilizar Poner

Parece que algo no funcionó .


No hace falta invocar a Poner en este ejercicio ya que se puede solucionar
con PonerN.

¡Corrijamos el problema!
Resultados:

[2:8]: El procedimiento "Suma" no está definido.

procedure PonerN(cantidad,color){
PonerSuma(cantidad)
Poner(color)
}
¡Ups! Tu solución no se puede ejecutar

Ver detalles

Objetivos que no se cumplieron:

  PonerSuma debe utilizar PonerN
  PonerSuma debe tener dos parámetros
  PonerSuma debe usar +
  la solución debe declarar PonerSuma

Eh, ¿qué pasó acá ?

Es necesario sumar los valores de x e y para poner la cantidad de bolitas


necesarias invocando a PonerN.

¡Intentemos de nuevo!
Resultados:

[14:11]: El procedimiento "PonerN" está definido dos veces: en (?):1:1 y en (?):14:1.

Solucion con error en la consulta


procedure PonerSuma(x,y){
PonerN(4,1,Rojo)
}
Damián Fernando P. hace 11 días
porque me dice que poner suma lleva el signo + si cuando lo invoco
tambien me da error

Walter G. hace 11 días


Hola Damián porque sabemos que para sumar algo usamos el signo + para
los números Segundo porque vos no debés poner los números, para eso son
los parámetros, esos son los que tenés que usar y por lo tanto sumar x+y
Espero sea útil

Camila C.  MENTORÍA  hace 11 días


¡Hola Damián! ¿Cómo estás? En este ejercicio queremos que PonerSuma()
ponga la cantidad de bolitas resultado de la suma de los dos parámetros que
se recibe, es decir que no vamos a poner un número especifico. Recordá que
los parámetros no tienen un valor determinado en el momento que
definimos el procedimiento, pueden tomar potencialmente cualquier valor.
Por esto es que en el PonerN(cantidad, color) vamos a usar los parámetros x e y
para la cantidad. Para sumar vamos a utilizar el signo +. De esta forma es que
deberíamos, al igual que como sumamos números, sumar los parámetros: x +
y. Ánimo estás por buen camino.

SOLUCION CORRECTA
procedure PonerSuma(x,y){
PonerN(x+y,Rojo)

}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

0 1

1 1
0 0
6

0 1

0 1

1 1

0 0
6 6
0 1

0 1

1 1

0 9 0
6
9
0 1

Como ya descubriste, podemos escribir expresiones aritméticas (o sea,


cuentas matemáticas) en los mismos lugares donde hasta ahora veníamos
escribiendo números.

Ejercicio 3: ¿Qué se hace antes?


De un conocido diario (no podemos revelar su nombre por temas de
confidencialidad) nos pidieron definir un procedimiento para contar,
aproximadamente, cuánta gente asistió a una determinada manifestación.
Contamos con la información de cuántos micros, autos y bicicletas asistieron
y desde allí podemos hacer un cálculo siguiendo estas reglas:
 en cada micro viajan 40 personas;
 en cada auto viajan 4 personas;
 en cada bicicleta viaja 1 persona.
Definí el procedimiento ContarGente(micros, autos, bicicletas) que a partir de
la cantida de micros, autos y bicicletas que recibe como parámetro, haga las
cuentas necesarias y refleje el resultado con bolitas de color verde.
Te dejamos un par de ejemplos que te pueden ayudar:
 ContarGente(1, 1, 1) generaría este tablero:
0 1

1 1

0 0
45 45

5
0 1

 ContarGente(1, 2, 3) generaría este tablero:


0 1

1 1

0 0
51 51

5
0 1

 ¡Dame una pista!

Ah, un detalle: la multiplicación en Gobstones se hace con el símbolo * (por


ejemplo, 3 * 2).

Biblioteca
procedure PonerN(cantidad, color) {
repeat(cantidad) {
Poner(color)
}
}

Solucion no valida mia


procedure ContarGente (micros, autos, bicicletas){
PonerN(micros, Verde)
PonerN(autos, Verde)
PonerN(bicicletas, Verde)
}
 Tu solución no pasó las pruebas

Ver detalles

Objetivos que no se cumplieron:

  ContarGente debe usar expresiones matemáticas


  No es necesario usar más de un PonerN.

Parece que algo no anduvo bien 

Es necesario ver qué operaciones matemáticas son necesarias para calcular la


gente y poner la cantidad de bolitas correspondiente.

Pero a no desesperar, intentemos otra vez 


Resultados de las pruebas:

  Se obtuvo un tablero distinto al esperado.

Solucion dada en la consulta que se puede mejorar

1. procedure ContarGente(micro, auto, bicicleta) {


2. PonerN (micro * 40, Verde)
3. PonerN (auto * 4, Verde)
4. PonerN (bicicleta * 1, Verde)
5.
6. }
Cecilia P. hace 5 meses
Dice que la solución funcionó, pero que se puede mejorar. En los objetivos
me aclara que no es necesario repetir el procedimiento de PonerN, pero no
logro entender cómo poner los datos de los tres vehículos si solo puedo
poner este procedimiento una única vez. Si alguien pudiera orientarme un
poco lo agradecería mucho.
Mercedes D. hace 5 meses
Hola Cecilia! El objetivo de este ejercicio es obtener una celda con el número
de bolitas total según las personas que viajan en cada medio de transporte.
Asi como usas el simbolo " * " para multiplicar a la cantidad de personas por
la cantidad de vehiculos, podés usar el simbolo " + " para sumar la cantidad
total, sin la necesidad de repetir el procedimiento PonerN.
1. procedure ContarGente(micro, auto, bicicleta) {
2. PonerN (micro * 40, Verde + auto * 4, Verde + bicicleta * 1, Verde)
3. }
Tu solución no pasó las pruebas
Resultados de las pruebas:
  El programa hizo BOOM.
 [2:2]: El procedimiento "PonerN" espera recibir 2 parámetros pero se lo invoca con 4
argumentos.

SOLUCION CORRECTA
procedure ContarGente(micros, autos, bicicletas){

PonerN(40*micros+4*autos+bicicletas, Verde)

 ¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

Tablero inicial

0 1

1 1

0
0

0 1 45

5
Tablero final

0 1

1 1

0 45 *
0

5
0 1
En Gobstones, como en la matemática, existe la idea de precedencia de
operadores. En criollo, esto quiere decir que hay ciertas operaciones que se
hacen antes que otras, sin la necesidad de usar paréntesis para ello. En
particular, el orden es: primero las multiplicaciones y divisiones, luego las
sumas y las restas (de nuevo, como en matemática).

Por lo tanto, la expresión (10 * 4) + (8 * 7) es equivalente a 10 * 4 + 8 * 7.

Ejercicio 4: La carrera del salmón


Bueno, basta de números (por un ratito). Ahora vamos a aprender a hacer
"cuentas" con las direcciones.

Para hacer esto, simularemos el movimiento de un salmón: en contra de la


corriente. Nuestro objetivo será definir un
procedimiento MoverComoSalmon(direccion) que reciba una dirección y se
mueva exactamente una vez en la dirección opuesta. Veamos en una tabla
cómo debería comportarse este procedimiento:

 MoverComoSalmon(Norte)  se mueve hacia el Sur.


 MoverComoSalmon(Este)  se mueve hacia el Oeste.
 MoverComoSalmon(Sur)  se mueve hacia el Norte.
 MoverComoSalmon(Oeste)  se mueve hacia el Este.

Como la dirección va a ser un parámetro de nuestro procedimiento,


necesitamos una forma de decir "la dirección opuesta a X" para poder luego
usar esto como argumento de Mover. Gobstones nos provee un mecanismo
para hacer esto, la primitiva opuesto(dir). En criollo: opuesto (¡sí, en minúsculas!)
nos dice la dirección contraria a la dir que nosotros le pasemos.

Sabiendo esto, podríamos definir fácilmente el procedimiento que


queríamos:

procedure MoverComoSalmon(direccion) {
Mover(opuesto(direccion))
}
Escribí la solución en el editor y dale Enviar. Vas a ver cómo se mueve el cabezal...

1. procedure MoverComoSalmon(direccion){
2. Mover(opuesto(direccion))
3. }

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

 Tablero inicial

0 1

1 1

0 0

0 1

 Tablero final

0 1

1 1

0 0
0 1

 Tablero inicial

0 1

1 1

0 0

0 1

 Tablero final

0 1

1 1

0 0

1
0

Las expresiones no sólo pueden denotar números, también nos sirven para


realizar transformaciones sobre direcciones. Más sobre esto en los próximos
ejercicios.

Ejercicio 5: Dos pasos adelante, un paso


atrás
Tenemos un amigo llamado Carlos, que es bastante desconfiado. En su vida,
eso se manifiesta en muchos aspectos, pero el más notorio es su forma de
caminar: sólo camina hacia el Este y siempre que da dos pasos hacia
adelante automáticamente da un paso hacia atrás.

Por ejemplo, si le pidiéramos que diera 2 pasos, terminaría dando 1; si le


pidiéramos 4, daría 2; y así sucesivamente. En definitiva, lo que termina
pasando es que nuestro amigo da la mitad de los pasos que le pedimos.

Importante: en Gobstones usamos el operador div para dividir; por


ejemplo "4 dividido 2" se escribe 4 div 2.
Definí el procedimiento CaminarDesconfiado(pasos) que simule el caminar de Carlos: debe
recibir la cantidad de pasos que debería dar y recorrer la mitad. Siempre se mueve
al Este.
 ¡Dame una pista!

Acordate que podés invocar MoverN(cantidad, direccion).

Biblioteca
procedure MoverN(cantidad, direccion) {
repeat(cantidad) {
Mover(direccion)
}
}

Solucion Correcta

procedure CaminarDesconfiado(pasos){
MoverN(pasos div 2, Este)
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 Tablero inicial

0 1 2 3 4 5

0 0

0 1 2 3 4 5

 Tablero final

0 1 2 3 4 5

0 0

0 1 2 3 4 5

 Tablero inicial
0 1 2 3 4 5

0 0

0 1 2 3 4 5

 Tablero final

0 1 2 3 4 5

0 0

0 1 2 3 4 5

Sobre el ejemplo de 4 pasos, no hay dudas: Carlos dio 2 pasos. Ahora,


cuando le pedimos que diera 7, ¿por qué dio 3?

En Gobstones, la división es entera: se ignoran los decimales. De esta


forma, 7 div 2 termina dando 3 en vez de 3.5.

Ejercicio 6: Poner al lado


Para ver si entendiste lo anterior, te toca ahora resolver por tu cuenta.
Queremos definir un procedimiento que nos sirva para poner una bolita al
lado de donde se encuentre el cabezal, dejándolo en la posición original. Por
ejemplo, al invocar PonerAl(Norte, Verde) debería poner una bolita verde una
posición hacia el Norte, sin mover el cabezal (bueno, ya sabemos que en
realidad sí se mueve, pero el punto es que en el resultado final esto no se
tiene que ver).
0 1

1 1

0 0
45
0 1

0 1

1 1
1

0
45
5 0

0 1

Definí el procedimiento PonerAl(direccion, color).


¡Dame una pista!
Para volver a dejar el cabezal donde empezó, necesitás lograr que se mueva
en la dirección opuesta a la inicial.
¿Será algo parecido a lo que hicimos en el ejercicio anterior? 

procedure PonerAl(direccion, color){


MoverN(Norte)
Poner(Verde)
Mover(opuesto(Norte))
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[2:3]: El procedimiento "MoverN" no está definido.

SOLUCION DADA EN LA CONSULTA CON ERROR


1. procedure PonerAl (direccion,color){
2. Mover (direccion)
3. Poner (Rojo)
4. Mover (opuesto(direccion))
5. }

Cecilia L. hace 28 días


Hola! el primer tablero me da ok, pero el de abajo no, y ya no se como
hacerlo. Intente de varias formas.
Nahuel A. hace 28 días
Buenas noches, dentro de los parentis poner (Rojo) estas dando un valor,
cuando en el procedure PonerAl (direccion, color) en color no tenes mismo
valor. Acordate que estas haciendo un procedimiento (procedure) y el
problema que te plantean ellos, usan el program PonerAl (direccion, color)
Asignando los valores.

Gaston P.  MENTORÍA  hace 28 días


¡Hola Cecilia! Vas bien encaminada, aunque procedimiento debe funcionar
para cualquier color y direccion que sean pasados por parámetro. Para esto, es
necesario hacer que se coloque una bolita de color color y moverse en una
dirección direccion.

SOLUCION CORRECTA lo que hice yo con error


procedure PonerAl (direccion,color){ procedure PonerAl(dirección,color){
Mover (direccion) MoverN (Norte)
Poner (color) Poner (Verde)
Mover (opuesto(direccion)) Mover (opuesto(Norte))
} }

 ¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

Inicial

0 1

1 1

0 0
45

0 1

final
0 1

1 1
1

5
0 0
45

0 1

Otro final cambiando direccion 1


0 1

1 1
5
0 1 1 0
45

50 5
1

Tanto opuesto(dir) como otras herramientas que veremos más adelante forman


parte de lo que conocemos como funciones y, como las expresiones
aritméticas que ya vimos, se pueden usar en cualquier lugar donde hasta
ahora poníamos valores o argumentos.

O sea, donde hasta ahora podrías usar dir ahora también podrías


poner opuesto(dir), ya que ambas expresiones denotan direcciones.
Obviamente te queda a vos decidir en cada caso si tiene sentido
usar opuesto o no.

Ejercicio 7: La línea que vuelve


Ahora que sabés usar la función opuesto, podemos finalmente resolver el
problema de definir un procedimiento que dibuje una línea en cualquier
dirección y deje el cabezal en la posición inicial.

La versión que sabíamos hacer hasta ahora era esta:

procedure Linea(direccion, color, longitud) {


repeat(longitud) {
Poner(color)
Mover(direccion)
}
}

Valiéndote de tus nuevos conocimientos sobre expresiones, modificá el


procedimiento Linea para que el cabezal quede en el lugar donde empezó.
 ¡Dame una pista!

MoverN y opuesto parecieran ser buenos aliados para el problema que tenés que


resolver.

Solucion mia mal

1. procedure Linea(direccion, color, longitud) {


2. repeat(longitud) {
3. Poner(color)
4. Mover(direccion) aca falto cerrar con una llave
5. MoverN(opuesto(direccion))falto abrir con una llave y agregar longitud ,
opuesto(dirección)
6. }
7. }
Tu solución no pasó las pruebas
Resultados de las pruebas:

 El programa hizo BOOM.

 BOOM
 [6:4]: El procedimiento "MoverN" espera recibir 2 parámetros pero se lo invoca con un
argumento.

Tablero final esperado

0 1 2 3

3 3

2 1 2
1

1 1 1
1

0 0
1 1
0 1 2 3

Solucion dada por la consulta para


arreglar con observacion
procedure Linea(direccion, color, longitud) {
repeat(longitud) {
Poner(color)
Mover(direccion)
}
repeat(longitud) {
Mover(opuesto(direccion))
}
}
Jorge Pedro H. hace 10 meses
Hola, pude llegar al resultado pero no de la manera que lo plantean
utilizando el procedimiento MoverN, quería saber si podrían ayudarme a
buscar la lógica para integrarlo. Gracias.

Ivan K. hace 10 meses


Hola, creo que se podria solucionar utilizando MoverN en lugar del segundo
repeat, la cantidad seria "longitud", y la direccion seria el opuesto a la
dirección

SOLUCION CORRECTA

1. procedure Linea(direccion, color, longitud) {


2. repeat(longitud) {
3. Poner(color)
4. Mover(direccion)
5. }
6. {MoverN(longitud,opuesto(direccion) )
7. }
8. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
Tablero final esperado

0 1 2 3

3 3

2 1 2
1

1 1 1
1

0 0
1 1

0 1 2 3

Otro Tablero final esperado

1 2 3
0

1 1 1
1 1 1

0 0

0 1 2 3

Ejercicio 8: Dibujando una L


Nuestro objetivo en este ejercicio será definir un procedimiento capaz de
dibujar una letra L de color Azul, pero con la posibilidad de elegir hacia
dónde está orientada. A continuación, algunos ejemplos de cómo debería
comportarse:

Ele(Norte)

0 1 2 3

3 3

2 1 1
2

1 1 1
1

0 2 1
1 1 0

0 1 2 3
Ele(Este)
1
0 1 2 3

3 3

2 1 1
2

1 1 1
1

0 0
1

0 1 2 3

Indudablemente, una L consta de dos líneas y dibujar una línea es la tarea


que ya resolviste en el ejercicio anterior. Así que por ese lado, tenemos la
mitad del problema resuelto.

La primera línea es fácil, porque coincide con la dirección que recibimos


como argumento... ¿pero la segunda? Bueno, ahí viene lo interesante:
además de opuesto, Gobstones nos provee dos funciones más para operar
sobre las direcciones, siguiente y previo. siguiente(direccion) retorna la dirección
siguiente a la especificada, mientras que previo(direccion) retorna la anterior,
siempre pensándolo en el sentido de las agujas del reloj:

Descubrí cuál de las funciones nuevas tenés que invocar y definí el


procedimiento Ele(direccion). No te preocupes por la posición inicial del
cabezal, nosotros nos encargaremos de ubicarlo en el lugar
correspondiente para que la L se pueda dibujar.
 ¡Dame una pista!
El procedimiento Linea recibe tres argumentos: la dirección, el color y la
longitud. En este caso, lo único que varía es la dirección: el color es siempre
Azul y la longitud es siempre 3.
Biblioteca

procedure Linea(direccion, color, longitud) {


repeat(longitud) {
Poner(color)
Mover(direccion)
}
MoverN(longitud, opuesto(direccion))
}
procedure MoverN(cantidad, direccion) {
repeat(cantidad) {
Mover(direccion)
}
}

RESOLUCION MIA MAL


1. procedure Linea(direccion, color, longitud) {
2. repeat(longitud) {
3. Poner(color)
4. Mover(direccion)
5. }
6. {MoverN(longitud,opuesto(direccion) )
7. }
8. procedure Ele(direccion, longitud){
9. repeat (longitud) {
10.siguiente(direccion)
11.}
12.}
13.}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[1:1]: Se esperaba una definición (de programa, función, procedimiento, o tipo).


Se encontró: un número.

Solucion con error en la consulta


1. procedure Ele(direccion){
2. Linea(direccion, Azul, 3)
3. MoverN(3, direccion )
4. siguiente(direccion)
5. }
¡Hola Oriana!
Vamos a verlo por partes, para dibujar una L vamos a necesitar hacer dos
líneas, primero entonces veamos qué es lo que hace el procedimiento Linea
(lo podemos ver en la solapa </>Biblioteca):

procedure Linea(direccion, color, longitud) {


repeat(longitud) {
Poner(color)
Mover(direccion)
}
MoverN(longitud, opuesto(direccion))
}

Fijate que lo que hace es dibujar una línea hacia la direccion que le digamos,
del color y longitud que le digamos, y cuando termina de hacerlo vuelve a
la posicion inicial.
Si imaginamos un tablero, en donde nuestro cabezal comienza en la posición
(0,0). Si hacemos Linea(Norte, Rojo, 2), va a dibujar la linea roja dos celdas hacia
arriba y volverá a la posición (0,0), dejandonos en donde comenzamos.
Si tenemos esto en cuenta podemos dividir nuestro problema de dibujar una
L en dos partes, como dijimos: dos líneas.

 La primera línea, como bien hiciste, vamos a necesitar hacerla hacia la


dirección que nos pasen por parámetro:

Linea(direccion, Azul, 3)

Cuando termine de hacer esta línea, ya vuelve hacia la posición inicial.


 Ahora para la segunda línea, si dibujamos una L, vamos a querer que
las dos líneas comiencen en la misma celda, tienen que compartir una
"punta". Entonces, vamos a necesitar dibujar la segunda línea desde
la celda inicial ¿necesitamos movernos? ¡Por suerte no! Ya la primera
línea que dibujamos nos dejo en esta posición, entonces solamente
tenemos que dibujar otra línea, y podemos hacerlo volviendo a usar el
procedimiento Linea, sabemos que el color va a serAzul y la longitud va
a ser 3 ¿y la dirección? Como pusiste en la línea 4, la dirección que
vamos a necesitar para la segunda línea es la siguiente a la dirección
que nos viene por parámetro. Pero como siguiente es una función, nos
va a retornar una dirección, no va a realizar acciones en el tablero. Y
nos viene perfecto, porque dentro de Linea(direccion, color,
longitud) justamente necesitamos una dirección. Podemos entonces
reemplazar el parámetro direccion de Linea por siguiente(direccion).

1. procedure Ele(direccion){
2. Linea(Norte, Azul, 3)
3. Linea(siguiente(Norte), Azul, 3)
4. }

Hernán Gonzalo V. hace 10 meses

La (Norte, Este), me sale bien y comprendo el porqué del error "[15:5]: No


se puede mover hacia la dirección Norte: cae afuera del tablero." porque
en el 2do tablero el ir hacia el Norte lo hace caer fuera del tablero... pero
no sé como solucionarlo.

Maria Florencia T. hace 10 meses

Hola Hernán! Fijate que ya le estás poniendo una dirección definida a las
lineas! Deja esos valores como parámetros para que varíe dependiendo
de la direccion que le des a Ele(direccion). Por ejemplo, al darle a Ele
dirección Este (Ele(Este)), los valores de abajo no podrán cambiar porque
ya pusiste los valores Norte y Norte, entonces la Linea se hará hacia el
Norte.
Mauro G. hace 10 meses
Hola Hernan, como dijo Maria. En este ejercicio no deberías forzar al
procedure a ir a una dirección definida como Norte, etc, sino utilizar el
argumento "direccion" que es lo que le vas a pasar a la función. A partir
de ahí deberías utilizar solo siguiente o previo dado el caso que
corresponda.
RESOLUCION MIA MAL
1. procedure Linea(direccion, color, longitud) {
2. repeat(longitud) {
3. Poner(color)
4. Mover(direccion)
5. }
6. {MoverN(longitud,opuesto(direccion) )
7. }
8. procedure Ele(direccion, longitud){
9. repeat (longitud) {
10.siguiente(direccion)
11.}
12.}
13.}

SOLUCION CORRECTA
1. procedure Ele(direccion){
2. Linea(direccion, Azul, 3)
3. Linea(siguiente(direccion), Azul, 3)
4. }
¡Muy bien! Tu solución pasó todas las pruebas

Ejercicio 9: Previo a lo siguiente


Ya te presentamos las funciones opuesto, previo y siguiente que nos permiten
desplazarnos en forma relativa a alguna dirección . Antes de seguir
utilizándolas, vamos a conocerlas un poco mejor.
Si partimos de este tablero inicial:
Y luego ejecutamos Mover(siguiente(Norte)) el tablero obtenido será así:

Porque siguiente(Norte) es Este. Si luego
ejecutamos Mover(previo(Oeste)) lograremos el siguiente tablero:

Porque previo(Oeste) es Sur. ¡Veamos si se entendió!

Si tenemos este tablero inicial:


¿Qué tablero se consigue luego de invocar el siguiente procedimiento?

procedure PonerMisterioso() {
Mover(siguiente(Este))
Poner(Negro)
Mover(opuesto(Oeste))
Poner(Negro)
Mover(previo(Oeste))
Poner(Negro)
}
ESTA ES

 ¡Muy bien! Tu solución pasó todas las pruebas

Ejercicio 10: Siga la flecha


Ya vimos distintas funciones que a partir de una dirección nos permiten
obtener otra distintas.

Como siempre en programación, lo interesante es combinar nuestras


herramientas para lograr nuevos objetivos . Por ejemplo podemos dibujar
flechas en una dirección determinada de la siguiente forma:
Flecha(Norte)

0 1 2

2 1 2
9 1 1

1 1 1 1
9
1 1 1

5 5 5

0 0
9 1 9 1 9 1

0 1 2

Flecha(Oeste)

0 1 2

2 1 2
9 1 1

1 1 1
9
1 1

5 5 5

0 0
9 1 9
1 1 9 1
1
0 1 2

Definí el procedimiento Flecha(direccion) que dibuje una flecha roja en la dirección


correspondiente. El cabezal empieza y debe quedar siempre en el centro, como se ve
en los tableros de ejemplo.

 ¡Dame una pista!

Tené en cuenta que cada vez que nos movamos en una dirección para poner
una bolita vamos a tener que volver a la dirección anterior. Por suerte
tenemos una función para eso, ¿cuál?
EJRCICIO RESUELTO MAL POR MI
1. procedure Flecha(direccion){
2. Mover(siguiente(direccion))
3. Poner(Rojo)
4. Mover(opuesto(direccion))
5. Mover(siguiente(direccion))
6. Poner(Rojo)
7. Mover(opuesto(direccion))
8. Mover(siguiente(direccion))
9. Poner(Rojo)
10.Mover(opuesto(direccion))
11.}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:

  Flecha debe utilizar previo

El programa hizo BOOM.


[5:3]: No se puede mover hacia la dirección Norte: cae afuera del tablero.

BOOM
[5:3]: No se puede mover hacia la dirección Este: cae afuera del tablero.

Otra Solución mia mal


1. procedure Flecha(direccion){
2. Mover(siguiente(direccion))
3. Poner(Rojo)
4. Mover(opuesto(direccion))
5. Mover(previo(direccion))
6. Poner(Rojo)
7. Mover(opuesto(direccion))
8. Mover(siguiente(direccion))
9. Poner(Rojo)
10.Mover(opuesto(direccion))
11.}
Tu solución no pasó las pruebas
Resultados de las pruebas:

 El programa hizo BOOM.

 [7:3]: No se puede mover hacia la dirección Este: cae afuera del tablero.
 [7:3]: No se puede mover hacia la dirección Sur: cae afuera del tablero.

Otra solución mia mal


1. procedure Flecha(direccion){
2. Mover(siguiente(direccion))
3. Poner(Rojo)
4. Mover(opuesto(direccion))
5. Mover(previo(direccion))
6. Poner(Rojo)
7. Mover(previo(direccion))
8. Mover(siguiente(direccion))
9. Poner(Rojo)
10.Mover(previo(direccion))
11.}
Tu solución no pasó las pruebas
Resultados de las pruebas:

 Se obtuvo un tablero distinto al esperado.

EJERCICIO RESUELTO EN LA CONSULTA

procedure Flecha(direccion) {
Mover(previo(direccion))
Poner(Rojo)
repeat(2) {
Mover(siguiente(direccion))
}
Poner(Rojo)
Mover(previo(direccion))
Mover(direccion)
Poner(Rojo)
Mover(opuesto(direccion))
}
Marcelo O. hace 10 meses
Buenas noches! Pude resolverlo completando y corrigiendo el codigo
leyendo las preguntas y las respuestas. Pero la realidad es que no me queda
muy claro este ejercicio, creo que es por las funciones "previo" y "siguiente",
al parecer no termino de entender su comportamiento.
Mauro G. hace 10 meses
Hola Marcelo,
El procedure Flecha recibe a direccion como argumento. Lo que te permite
previo y siguiente es conseguir una nueva dirección dependiendo de esta, en
lugar de tener que escribir forzadamente a donde querés que vaya la casilla.
Por lo tanto es un código más general y te permite para muchos más casos.
Imaginate una brújula donde Norte está arriba, Este a la derecha, Sur está
abajo y Oeste a la izquierda. Teniendo en cuenta la rotación de las agujas
del reloj la siguiente dirección a Norte es Este, y la siguiente a Este es Sur,y la
siguiente a Sur es Oeste, y la siguiente a Oeste es Norte. previo muestra lo
mismo, pero hacia el lado contrario. El previo a Norte es Oeste, y así
sucesivamente.
Por ejemplo si el procedure Flecha(direccion) recibe la dirección Norte y le aplicás
un siguiente(direccion) estás 'convirtiendo' a ese Norte en un Este. Pero si vos
no utilizarías esto, tendrías que saber previamente que valor tiene direccion y
ahí ya un programa o un procedure en este caso pierde todo sentido ya que
te serviría para solo un caso o un par de casos.

También si vos utilizaces, por ej siguiente(siguiente(direccion)) y direccion es


Norte, pasarías a estar en Sur, ya que le aplicaste siguiente al siguiente de
Norte que era Este.

Carlos Jorge T. hace 10 meses

Hola Marcelo... Para entender bien el problema, tenés que volver a ver y
entender mejor la roseta que muestra el problema anterior a este (8.
Dibujando una L) Allí, en el gráfico te explica que "previo" te devuelve la
primer dirección que está ubicada girando en sentido contrario al
movimiento de las agujas de un reloj, "siguiente" te devuelve la primera
dirección que está ubicada girando en sentido al movimiento normal de las
agujas de un reloj. Entonces, "previo" a Norte está Oeste (porque si
partimos desde Norte y giramos una aguja imaginaria de reloj en sentido
contrario al normal, la primer dirección que encontramos es Oeste). Y
"siguiente" a Norte es Este (porque si partimos desde Norte y giramos una
aguja imaginaria de reloj en sentido normal, la primer dirección que
encontramos es Este). Lo mismo aplica para cualquiera de las direcciones
que se elija. "previo" significa "buscar la primer dirección girando hacia la
izquierda", y "siguiente" significa "buscar la primer dirección girando hacia la
derecha". Saludos.

Mauro G. hace 10 meses

Perdón aclaro lo que dije de 'convirtiendo', por eso lo puse en comillas.


dirección va a seguir teniendo el mismo valor, no es que si hacés
siguiente(direccion) dirección toma el valor de la siguiente dirección, por eso mi
último ejemplo en el mensaje anterior. Supongamos que direccion es Norte
Hacer esto: siguiente(direccion) siguiente(direccion)
Va a darte como resultado ya que la dirección no se modifica: Este Este
Que no es lo mismo que hacer esto: siguiente(siguiente(direccion))
Que va a darte como resultado: Sur

RESULTADO CORRECTO RESOLUCION MIA CON ERROR


1. procedure Flecha(direccion) { procedure Flecha(direccion){
2. Mover(previo(direccion)) Mover(siguiente(direccion))
3. Poner(Rojo) Poner(Rojo)
4. repeat(2) { Mover(opuesto(direccion))
5. Mover(siguiente(direccion)) Mover(previo(direccion))
6. }
7. Poner(Rojo) Poner(Rojo)
8. Mover(previo(direccion)) Mover(previo(dirección))
9. Mover(direccion) Mover(siguiente(direccion))
10. Poner(Rojo) Poner(Rojo)
11. Mover(opuesto(direccion)) Mover(previo(dirección))
12. } }

Respuesta: también correcta

procedure Flecha(direccion){
Mover(previo(direccion))
Poner(Rojo)
Mover(siguiente(direccion))
Mover(siguiente(direccion))
Poner(Rojo)
Mover(previo(direccion))

Mover(siguiente(direccion))
Mover(previo(direccion))
Mover(direccion)
Poner(Rojo)
Mover(opuesto(direccion))
}
te explica que "previo" te devuelve la primer dirección que está ubicada
girando en sentido contrario al movimiento de las agujas de un reloj
Lo mismo aplica para cualquiera de las direcciones que se elija. "previo"
significa "buscar la primer dirección girando hacia la izquierda", y "siguiente"
significa "buscar la primer dirección girando hacia la derecha".
¡Muy bien! Tu solución pasó todas las pruebas

Ejercicio 11: Copiando bolitas


Supongamos ahora que queremos "copiar" las bolitas verdes, haciendo que haya la misma
cantidad de rojas y pensemos cómo podría ser ese procedimiento.
Una tarea que seguro tenemos que hacer es poner muchas bolitas, y para eso ya sabemos
que existe el procedimiento PonerN que construimos varios ejercicios atrás. El color de las
bolitas que tenemos que poner también lo sabemos: Rojo, pero... ¿cómo sabemos cuántas
poner?
Miremos algunos ejemplos:
 Si hay 4 bolitas verdes, hay que poner 4 bolitas rojas.
 Si hay 2 bolitas verdes, hay que poner 2 bolitas rojas.
 Si no hay bolitas verdes, no hay que poner ninguna roja.
Lo que nos está faltando es una forma de contar cuántas bolitas verdes hay, y para eso
necesitamos otra función que nos da Gobstones: nroBolitas(color). Lo que hace es
simple: nos retorna la cantidad de bolitas de un color determinado en la posición actual.
Invocando nroBolitas, definí el procedimiento CopiarVerdesEnRojas.
Dame una pista!
Si necesitaramos saber las cantidad de bolitas negras deberíamos
invocar nroBolitas(Negro) en nuestro procedimiento. Pero necesitamos saber la cantidad
de verdes...

procedure PonerN(cantidad, color) {


repeat(cantidad) {
Poner(color)
}
}

Solucion mia mal

1. procedure CopiarVerdesEnRojas
2. }
3. procedure PonerN(cantidad, color) {
4. repeat(cantidad) {
5. Poner(color)
6. }
7. }
 ¡Ups! Tu solución no se puede ejecutar
Problemas que encontramos:

 La cantidad de { y } no coincide. ¿Puede que sobre una } en la


línea 3 o cerca de ella?

 Detalles

[3:1]: Se encontró un "}" pero no había una llave abierta "{".


Ejercicio Resuelto en la consulta con error

1. procedure CopiarVerdesEnRojas(){
2. nroBolitas(Verde)
3. PonerN(nroBolitas(Verde),Rojo)
4. }
Buenas tardes; creo que mi procedimiento es correcto y me marca error
2:13 no veo el porque. Gracias
Mayra M. hace 10 meses

¡Hola Matias! Tu solución esta casi perfecta, salvo por un detalle y es que
no es necesario poner nroBolitas(Verde) ya que esa expresión por si sola
solo nos devuelve un número. Si está muy bien como lo utilizaste en el
PonerN.
Solucion Correcta
1. procedure CopiarVerdesEnRojas(){
2. PonerN(nroBolitas(Verde),Rojo)
3. }
¡Muy bien! Tu solución pasó todas las pruebas

Si no hay verdes, no hace nada


Tablero inicial

0 1

1 1

0 0

0 1

Tablero final
0 1

1 1

0 0

1
0

Si hay 2 verdes, pone 2 rojas


0 1

1 1

0 0
2
1
0

final
0 1

1 1

0 0
22
1
0

Si hay 7 verdes, pone 7 rojas


0 1

1 1

0 0
2
1
0

final
0 1

1 1

0 0
77
1
0

En este ejercicio, además de aprender una expresión nueva, hiciste algo que nunca habías
hecho hasta ahora: un programa cuyo efecto depende del estado del tablero inicial.

¿Qué quiere decir esto? Que el código de CopiarVerdesEnRojas() se comporta

diferente dependiendo de cómo estaba el tablero antes de ejecutarlo

Ejercicio 12: Sacando bolitas


Siguiendo con esto de contar las bolitas, te toca ahora definir un procedimiento que sirva
para sacar todas las bolitas de un color.
Pensemos las subtareas necesarias:
1. Poder sacar muchas bolitas: ya está resuelto con SacarN.
2. Contar cuántas bolitas hay que sacar: se puede hacer con nroBolitas.
3. Sacar todas las bolitas de un color: hay que combinar las 2 anteriores.
Definí SacarTodas(color), que recibe un color y saca todas las bolitas que hay de ese
color (no debe hacer nada con el resto de los colores).
 ¡Dame una pista!

 SacarTodas(Rojo) produciría esto:

Inicial

0 1 Final
1 1
0 1

4 3 1 1
0 0 Biblioteca
3
22
0 44 3 0
0 1 procedure SacarN(cantidad, color) {
repeat(cantidad) 0 1 {
Sacar(color)
}
}

Mi solucion mal

1. procedure SacarTodas(cantidad,color){
2. SacarN(nroBolitas(cantidad, color)
3. }

SOLUCION CORRECTA

1. procedure SacarTodas(color){
2. SacarN(nroBolitas(color),color)
3. }

¡Terminaste Expresiones!
Repasemos todo lo que aprendiste en esta guía:
Además de los literales que ya venías usando, existen también otro tipo
de expresiones que realizan algún tipo de operación y pueden depender de
dos cosas: de sus parámetros y del estado del tablero.

En el camino, conociste unas cuantas expresiones nuevas:

 Aritméticas: +, -, *, div.
 De direcciones: opuesto, siguiente, previo.
 Númericas: nroBolitas.

Y de yapa, también te adentraste un poquito en el arte de los programas


que hacen cosas distintas según el tablero que haya.

Alternativa Condicional
Hasta ahora, todos los programas y procedimientos que hicimos fueron
sobre tableros conocidos, sabíamos exactamente de qué tamaño era el
tablero, dónde estaba el cabezal y cuántas bolitas había en cada celda.

Nos introduciremos ahora en el mundo de lo desconocido, donde la


programación cobra aún mucho más sentido. Con la herramienta que
veremos podremos resolver problemas nuevos y evitar errores que hasta
ahora no podíamos: sacar una bolita Roja sólo si hay alguna, movernos al
Norte si eso no provoca que nos caigamos del tablero o agregar una bolita
Azul sólo si ya hay una Verde.

¿Y cómo haremos esto? Utilizando la capacidad de la computadora


para decidir: la alternativa condicional o sentencia if.

Ejercicios

  1. Sacar con miedo


  2. Sacar con miedo, segundo intento
  3. Eliminando la bolita roja
  4. Un ejemplo medio rebuscado
  5. ¿Y sólo sirve para ver si hay bolitas?
  6. Un poquito de matemática
  7. Cómo decirle que no...
  8. Dos caminos distintos
  9. Un tablero de luces

Ejercicio 1: Sacar con miedo


Vamos a definir un procedimiento que saque una bolita azul "con miedo": no
tiene que producirse un BOOM, aún cuando no haya ninguna bolita en la
celda actual.
Con lo que sabés hasta ahora, probablemente tu primera idea sea hacer algo
como esto:

procedure SacarAzulConMiedo() {
Sacar(Azul)
}
¡Probalo! Copiá el código anterior en el editor y apretá Enviar.

SOLUCION VALIDA
1. procedure SacarAzulConMiedo() {
2. Sacar(Azul)
3. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

0 1

1 1

0
1
0 1

FINAL
0 1

1 1

0 1
 Cuando no hay ninguna bolita azul, hace BOOM
BOOM
[2:3]: No se puede sacar una bolita de color Azul: no hay bolitas de ese color.

¿Te diste cuenta qué pasó?

Funcionó para el primer tablero porque tenía una bolita azul, pero
hizo BOOM para el segundo porque estaba vacío, claro.

Ejercicio 2: Sacar con miedo, segundo


intento
Ahora probá esta segunda versión que agrega una alternativa condicional.
No te preocupes por la sintaxis, ya te lo vamos a explicar. 

procedure SacarAzulConMiedo() {
if (hayBolitas(Azul)) {
Sacar(Azul)
}
}

Copiá el código anterior en el editor y apretá Enviar.

Solucion correcta
procedure SacarAzulConMiedo() {
if (hayBolitas(Azul)) {
Sacar(Azul)
}
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
  Cuando hay una bolita azul, la saca
 0 1

1 1

0
1
0 1

final
0 1

1 1

0 1

 Cuando no hay ninguna bolita azul, no hace nada


0 1

1 1

0 1
0 1

1 1

0 1

¡Bien!

Hiciste tu primer procedimiento que decide antes de ejecutar. Seguí con


nosotros para entender de qué se trata esto...

Ejercicio 3: Eliminando la bolita roja


Analicemos el procedimiento del ejercicio anterior:

procedure SacarAzulConMiedo() {
if (hayBolitas(Azul)) {
Sacar(Azul)
}
}

Como notarás, introdujimos una nueva estructura de control: el if, que en


castellano significa si; entendiendo al si como condicional ("si tuviera
hambre me comería una empanada") y no como afirmación ("sí, yo rompí el
teléfono").

Entonces, lo que le estamos diciendo a la computadora es "si hay bolitas


azules, sacá una bolita azul", que dicho así suena un poco tonto ¡y lo es!. Ya
te dijimos que la computadora sólo sabe cumplir órdenes.
¡Ahora te toca a vos! Modificá el procedimiento que te dimos para que saque una
bolita roja, sólo si hay alguna.
 ¡Dame una pista!

SacarAzulConMiedo ya no es un buen nombre para el procedimiento, esperamos que


puedas cambiarlo también.

Solucion
procedure SacarRojoConMiedo() {
if (hayBolitas(Rojo)) {
Sacar(Rojo)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
  Cuando hay una bolita roja, la saca

Cuando hay más de una bolita roja, saca una

 0 1

1 1

0
4

0 1

 0 1

1 1

0
3

0 1
Cuando no hay ninguna bolita roja, no hace nada

Ejercicio 4: Un ejemplo medio rebuscado


Vamos a ponerle nombre a las partes del if.

En primer lugar, tenemos la condición. Por ahora siempre


fue hayBolitas(color) pero podría ser cualquier otra cosa, ya veremos más
ejemplos. Lo importante acá es que eso es lo que decide si la acción se va a
ejecutar o no.

¿Y qué es la acción? Básicamente, cualquier cosa que queramos hacer sobre


el tablero. Al igual que en el repeat, podemos hacer cuantas cosas se nos
ocurran, no necesariamente tiene que ser una sola.

Resumiendo: La acción que está dentro de la estructura del if podrá


realizarse solo cuando la condición sea verdadera.

Para ejercitar esto ultimo, te vamos a pedir que definas un


procedimiento CompletarCelda() que, si ya hay alguna bolita negra, complete la celda
poniendo una roja, una azul y una verde.
 ¡Dame una pista!

Como referencia, acá tenés la solución del problema anterior:

procedure SacarRojaConMiedo() {
if (hayBolitas(Rojo)) {
Sacar(Rojo)
}
}

Solucion
procedure CompletarCelda() {
if (hayBolitas(Negro)) {
Poner(Rojo)
Poner(Azul)
Poner(Verde)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 Cuando hay alguna bolita negra, completa la celda con las otras bolitas
de colores rojo, azul y verde
Cuando no hay ninguna bolita negra, no hace nada

Ejercicio 5: ¿Y sólo sirve para ver si hay


bolitas?
Claro que no, ¡por suerte! 

La condición puede ser cualquier expresión booleana. En criollo: cualquier


cosa que represente una "pregunta" que se pueda responder con sí o no. En
Gobstones el sí se representa con el valor True (Verdadero en castellano) y
el no con el valor False (Falso en castellano).

En los ejercicios anteriores te mostramos una de las expresiones que trae


Gobstones, hayBolitas(color), que recibe un color y retorna True o False.

Otra que trae True o False (y que vas a tener que usar ahora)


es puedeMover(direccion) que nos sirve para saber si el cabezal puede moverse
en una cierta dirección.

Por ejemplo, si tenemos este tablero:

0 1

2 2

1 1
0 0

0 1

 puedeMover(Norte) será True.
 puedeMover(Sur) será True.
 puedeMover(Este) será True.
 Pero puedeMover(Oeste) será False

Creá un programa que se mueva al Este sólo si es posible. Recordá


utilizar puedeMover(direccion)

 ¡Dame una pista!

Ya sabés como usar Mover, sólo te resta pensar cómo armar


la condición para poner en el if. Y no te olvidés, solo nos interesa movernos
al Este. 

procedure puedeMover(direccion){
if(puedeMover(Este))
Mover(Este)
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

[1:11]: Se esperaba un identificador con mayúsculas.


Se encontró: un identificador con minúsculas.

Mi equivocación anterior es porque pide


el ejercicio un programa y yo hice un
procedimiento
Solucion correcta
program {if (puedeMover(Este)){
Mover(Este)}
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Si hay celdas al Este, se mueve

0 1

2 2

1 1

0 0

0 1

0 1
2 2

1 1

0 0
0 1

Si no hay celdas al Este, no hace nada

0 1

2 2

1 1

0 0

0 1

0 1

2 2

1 1

0 0

0 1
¿Y si hubieramos querido movernos hacia el Norte en caso de
que no hubiera celdas al Este?
program {if (puedeMover(Este)){
Mover(Este)}
Mover(Norte)
}

Ejercicio 6: Un poquito de matemática


Otra cosa que se puede hacer adentro de un if es comparar números, como
seguramente alguna vez hiciste en matemática.

Por suerte, esto se escribe en Gobstones igual que en la matemática


tradicional, con un < para el menor y un > para el mayor.
Ejemplo: nroBolitas(Verde) > 5 nos indica si hay más de 5 bolitas verdes.

Sabiendo esto, intentá crear un programa que ponga 1 bolita negra sólo si hay menos
de 5 bolitas negras.

Solucion mia no valida


1. program{if (nroBolitas(Negro)< 5){
2. Poner (negro)
3. }
4. }
Tu solución no pasó las pruebas
Resultados de las pruebas:

  Si hay menos de 5 bolitas negras, agrega una

El programa hizo BOOM.

BOOM
[3:11]: La variable "negro" no está definida.

 Si hay más de 5 bolitas negras, no hace nada

SOLUCION CORRECTA MIA


1. program{if (nroBolitas(Negro)< 5){
2. Poner (Negro)
3. }
4. }

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

  Si hay menos de 5 bolitas negras, agrega una

Si hay más de 5 bolitas negras, no hace nada

Ejercicio 7: Cómo decirle que no...


En todos los problemas que hicimos hasta ahora, siempre preguntamos si
una cierta condición se cumplía: ¿hay alguna bolita roja? ¿me puedo mover
al Este? ¿hay más de 3 bolitas azules?

Algo que también se puede hacer es negar una condición, algo que en


castellano puede sonar medio raro pero que en programación se hace un
montón. Los ejemplos anteriores quedarían: ¿no hay alguna bolita roja?
¿no me puedo mover al Este? ¿no hay más de 3 bolitas azules?

¿Y cómo se hace en Gobstones? Fácil, se agrega la palabra clave not antes de


la expresión que ya teníamos.

Original Negada

hayBolitas(Rojo) not hayBolitas(Rojo)

puedeMover(Este) not puedeMover(Este)

nroBolitas(Azul) > 3 not nroBolitas(Azul) > 3

Definí un procedimiento AsegurarUnaBolitaVerde() que se asegure que en la celda actual


hay al menos una bolita verde. Esto es: si ya hay bolitas verdes no hay que hacer nada,
pero si no hay tendría que poner una.
SOLUCION MIA MAL
1. procedure AsegurarUnaBolitaVerde(){
2. not (hayBolitas(Verde)){
3. Poner(Verde)
4. }
5. }
¡Ups! Tu solución no se puede ejecutar
Resultados:

[2:3]: Se esperaba un comando.


Se encontró: la palabra clave "not".

SOLUCION CORRECTA
procedure AsegurarUnaBolitaVerde(){
if (not hayBolitas(Verde)){
Poner(Verde)
}
}

EXPRESION
COMANDO PALABRA CLAVE
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Si hay bolitas verdes, no hace nada


 Si no hay bolitas verdes, agrega una
A lo que acabás de hacer, en lógica se lo llama negación y al anteponer
el not decimos que se está negando una expresión. Cualquier expresión
booleana (o sea, que devuelve True o False) se puede negar.
Ejercicio 8: Dos caminos distintos
En lo cotidiano, se presentan muchas situaciones donde debemos elegir
entre dos acciones diferentes, dependiendo de si se cumple una cierta
condición o no.

 Si la remera está limpia me la pongo, si no la lavo.


 Si tengo aceite para freir las milanesas lo uso, si no le pongo un poco
de manteca.
 Si me puedo mover al Este lo hago, si no me muevo al Norte.

Para estos casos, en Gobstones tenemos una nueva palabra clave que nos
ayuda a cumplir nuestra tarea: el else. En castellano significa si no y hace
justamente lo que necesitamos: ejecuta una serie de acciones si no se
cumple la condición que pusimos en el if.

Supongamos que queremos definir un procedimiento que se mueva al Oeste


y, en caso de que no pueda, lo haga hacia el Norte. Haciendo uso del else,
podemos definirlo de la siguiente manera:

procedure MoverComoSea() {
if (puedeMover(Oeste)) {
Mover(Oeste)
} else {
Mover(Norte)
}
}
Escribí ese código en el editor y fijate cómo resuelve el problema.

Solución valida

procedure MoverComoSea() {
if (puedeMover(Oeste)) {
Mover(Oeste)
} else {
Mover(Norte)
}
}
 ¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  Si hay celdas al Oeste, se mueve

 Si no hay celdas al Oeste, se mueve al Norte

¡Espectacular!

Ya conocés la herramienta que usan todas las aplicaciones que conociste en


tu vida para decidir qué hacer, el viejo y querido if / if...else.

Ejercicio 9: Un tablero de luces


Como ejemplo final, imaginemos que nuestro tablero está lleno de luces que
están prendidas o apagadas. Vamos a decir que las celdas con una bolita
verde están prendidas y las celdas con una bolita negra están apagadas.

Definí un procedimiento PrenderOApagarLuz() que se encargue de prender las luces que


estén apagadas o apagar las luces encendidas, según corresponda. Tené en cuenta que
en cada celda solo puede haber bolitas de color verde o negro.
 ¡Dame una pista!

Apagar una celda implica dos cosas: sacar una bolita verde y agregar una
negra; lo mismo para prender pero en sentido inverso.

Para saber si está prendida o no, basta con fijarse si hay bolitas del color que
querramos.

 Por ejemplo, acá la luz está prendida y al invocar PrenderOApagarLuz() se


apaga:

Inicial Final
0 1 0 1

1 1 1 1
1
1 1
1

1
0 0 0 0
1 1

0 1 0 1

 En cambio, acá está apagada y con tu procedimiento se prende:

Inicial Final
0 1 0 1
1
1 1 1
1
1 1 1 1
1 1
1

1
0 0 0 0
1
1 1 1 1 1
1

0 1 0 1

Solucion mia con error


procedure PrenderOApagarLuz(){
if (PrenderOApagarLuz){
Sacar (Verde)
}
else {Poner (Negro)}
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  PrenderOApagarLuz debe utilizar hayBolitas

Resultados:

[2:7]: El constructor "PrenderOApagarLuz" no está definido. El nombre "PrenderOApagarLuz" es el


nombre de un procedim

Otra solución mia con error


procedure PrenderOApagarLuz(hayBolitas){
if (hayBolitas(Verde)){
Sacar (Verde)
}
else {Poner (Negro)}
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
  Si la celda está apagada, la prende: El programa hizo BOOM.
 BOOM
[12:4]: El procedimiento "PrenderOApagarLuz" espera recibir un parámetro pero se lo invoca
con ningún argumento.

  Si la celda está prendida, la apaga: El programa hizo BOOM.


 BOOM
 [12:4]: El procedimiento "PrenderOApagarLuz" espera recibir un parámetro pero se lo invoca
con ningún argumento.

Solucion dada en la consulta es valida pero con pequeño error a corregir


procedure PrenderOApagarLuz() {
if (hayBolitas(Negro)) {
Poner(Verde)
Sacar(Negro)
}
else {if (hayBolitas(Verde)) {
Poner(Negro)
Sacar(Verde)
}
}
}
Hola Hola!! me dice "Tu solución funcionó, pero hay cosas que mejorar"
que deberia mejorar! ¿Por que el segundo if no deberia ir? porque si no pongo el
segundo if el ejercicio no se ejecuta!! Desde ya mil gracias por sus ayudas!!!
David Ignacio D.  MENTORÍA  hace 4 meses
¡Hola Karol! ¿Cómo estás? La idea del ejercicio actual es usar un sólo if, de modo
que si no se cumple la dada condición, se ejecute la rama del else sin analizar ya
nada más. El por qué de esta cuestión radica en que sólo tenemos que trabajar con
dos estados. Por un lado, ¿qué hacemos si la luz está apagada? La prendemos. Y
ahora, ¿nos interesa, si esto no se cumple, preguntar si la luz está prendida? ¡Claro
que no! Porque esta condición depende de la anterior (Si la luz no está prendida,
entonces está apagada, y viceversa). Por lo que sólo estaría de más en tu solución,
la segunda condición. Debería poder ejecutarte sin problemas. Recordá que la
estructura de la alternativa condicional es la siguiente:
[...]
if(condicion) {
//código si se cumple condicion
}
else {
//código si no se cumple condición
}
[...]

Otra solución de la consulta que funciona pero hay que corregir el error

procedure PrenderOApagarLuz() {
if (hayBolitas(Verde)) {
Poner(Negro)
Sacar(Verde)
} else {
if (hayBolitas(Negro)) {
Poner(Verde)
Sacar(Negro)
}
}
}
Vicente I. hace 16 días
Hola! Estoy un poco desorientado aqui. Me dice que la solucion que hice funcionó
pero que se podria mejorar el codigo sacando un if... Estuve intentando de
diferentes formas pero no doy con la solucion correcta.. Si algunx me podria
orientar, se lo agradecería
Norman Adrian M. hace 16 días
y se supone que hay verde o negra....con el primer if preguntas si hay verdes..si es
asi la sacas y pones negra..hasta ahi todo bien...pero sino hay verdes usa el else, no
otro if...porque si no esta la verde, Esta la negra...y resta sacar negra y poner ver

Otra solución de la consulta que tiene un pequeño error a corregir


procedure PrenderOApagarLuz(){
if (hayBolitas(Negro))
{ Sacar(Negro)
Poner(Verde)}
Else
(Sacar(Verde)
Poner(Negro)
}
Hola, me está pidiendo una expresión y no llego a comprender
Martin G.  MENTORÍA  hace 25 días
¡Hola Leonardo!
El detalle está al momento de hacer el else. Al else lo escribimos sin ninguna
mayúscula y lo que ocurre en este va entre llaves {}. Por ejemplo:

if(condicion)
{
//hacemos algo
}
else
{
//hacemos otra cosa
}

Resolucion mia
procedure PrenderOApagarLuz(hayBolitas){
if (hayBolitas(Verde)){
Sacar (Verde)
}
{else (hayBolitas(Negro)){
Poner (Negro)}
}
Resolucion de la consulta bien PERO CON UN ERROR (El Else debe ir con minúscula)

procedure PrenderOApagarLuz(){
if (hayBolitas(Negro))
{ Sacar(Negro)
Poner(Verde)}
Else {
(Sacar(Verde)
Poner(Negro)
}
}

SOLUCION CORRECTA
procedure PrenderOApagarLuz(){
if (hayBolitas(Negro))
{ Sacar(Negro)
Poner(Verde)}
else{
Sacar(Verde)
Poner(Negro)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
  Si la celda está apagada, la prende
0 1 2
1 1 1
2 2

1 1 1
1 1

1 1 1
0 0

2
0 1

0 1 2
1 1 1
2 2

1 1 1
1 1

1 1 1
0 0

2
0 1

Si la celda está prendida, la apaga

¡Terminaste Alternativa Condicional!


Ahora conocés una de las herramientas más poderosas que tiene la computación:
la alternativa condicional. Aunque parezca algo sencillo, esto es lo que permite que los
programas puedan reaccionar diferente ante distintos estímulos, dando lugar así a que las
computadoras puedan tomar decisiones.
Algunos ejemplos de esto:
 en las redes sociales, probablemente exista un if que determine si podés ver el
perfil de alguien o no;
 cuando te tomás un colectivo y pagás con la SUBE (o tarjetas similares), la máquina
decide si podés viajar o no dependiendo de si te alcanza el saldo.
Te dejamos como ejercicio pensar (y por qué no intentar escribirlas) qué partes de los
sistemas con los que interactuás todos los días parecerían estar resueltas con un if.

Funciones
Cuando introdujimos la noción de procedimientos, dijimos que:

 son una forma de darle nombre a un grupo de comandos, logrando así que
nuestros programas fueran más entendibles;
 nos posiblitan la división en subtareas: para resolver un problema grande, basta
con dividirlo en problemas más chicos y luego combinarlos;
 nos ayudan a no repetir código, no volver a escribir lo mismo muchas veces.
Al trabajar con expresiones complejas, rápidamente surge la necesidad de contar con un
mecanismo similar, por los motivos que acabamos de esbozar.
¿Querés saber cuál es ese mecanismo? ¡Empecemos! 
Ejercicios

  1. Y esto, ¿con qué se come?


  2. La importancia de nombrar las cosas
  3. MoverSegunBolitas, versión 2
  4. todasExcepto
  5. Una función de otro tipo
  6. En libertad
  7. Cualquier bolita nos deja bien
  8. Siempre al borde...
  9. Las compañeras ideales
  10. Lo ideal también se puede romper
  11. ¿Hay bolitas lejos?
  12. Estoy rodeado de viejas bolitas
  13. Sin límites

Ejercicio 1: Y esto, ¿con qué se come?


Tomate unos pocos minutos y tratá de entender qué hace este
procedimiento:

procedure MoverSegunBolitas() {
if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10) {
Mover(Este)
} else {
Mover(Norte)
}
}

Cuando lo logres interpretar (o te canses ), presioná Enviar y mirá el resultado.


1. procedure MoverSegunBolitas() {
2. if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10)
{
3. Mover(Este)
4. } else {
5. Mover(Norte)
6. }
7. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 Si hay más de 10 bolitas, se mueve al Este


Si hay menos de 10 bolitas, se mueve al Norte
Costó entender qué hace sin ejecutarlo, ¿no?
Eso es señal de que nos está faltando dividir en subtareas...

Ejercicio 2: La importancia de nombrar las


cosas
Como vimos, el problema de lo anterior era la falta de división en
subtareas: la expresión que cuenta la cantidad de bolitas que hay en la
celda es demasiado compleja, y cuesta entender a simple vista que hace
eso.

Entonces, lo que nos está faltando es algún mecanismo para poder darle un


nombre a esa expresión compleja; algo análogo a
los procedimientos pero que sirva para encapsular expresiones.

La buena noticia es que Gobstones nos permite hacer esto, y la herramienta


para ello es definir una función, que se escribe así:

function nroBolitasTotal() {
return (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde))
}

Pegá el código anterior en el editor y observá el resultado.


1. function nroBolitasTotal() {
2. return (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) +
nroBolitas(Verde))
3. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 nroBolitasTotal() -> 12

 nroBolitasTotal() -> 5

Algunas aclaraciones sobre las funciones:

 son un caso particular de las expresiones, y por lo tanto siguen las


mismas reglas que ellas: se escriben con la primera letra minúscula y
siempre denotan algún valor (en este caso, un número);
 en la última línea de su definición siempre va un return, seguido de una
expresión entre paréntesis: el valor que la función va a retornar

Ejercicio 3: MoverSegunBolitas, versión 2


Ahora que ya logramos mover la cuenta de las bolitas a una subtarea,
podemos mejorar el procedimiento que habíamos hecho antes.

Modificá la primera versión de MoverSegunBolitas para que use la


función nroBolitasTotal() en vez de la expresión larga.
1. procedure MoverSegunBolitas() {
2. if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) +
nroBolitas(Verde) > 10) {
3. Mover(Este)
4. } else {
5. Mover(Norte)
6. }
7. }
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:

  MoverSegunBolitas debe utilizar nroBolitasTotal
Resultados de las pruebas:
  Si hay más de 10 bolitas, se mueve al Este
Si hay menos de 10 bolitas, se mueve al Norte

Resolucion con error mia


1. 1.procedure function nroBolitasTotal() {
2. return (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde))
3. }
4. {
5. Mover(Este)
6. } else {
7. Mover(Norte)
8. }
9. }
¡Ups! Tu solución no se puede ejecutar
Resultados:

[1:1]: Se esperaba una definición (de programa, función, procedimiento, o tipo).


Se encontró: un número.

solucion dada en la consulta pero con


error
1. procedure MoverSegunBolitas() {
2. if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10) {
3. Mover(Este)
4. } else{
5. Mover(Norte)
6. }
7. }
César Alberto R. hace 18 días
Alguien podría ayudarme? me dió que estaba bien pero tenia que ver
nroBolitas

procedure MoverSegunBolitas() { if (nroBolitas(Azul) + nroBolitas(Negro) +


nroBolitas(Rojo) + nroBolitas(Verde) > 10) { Mover(Este) }
else{ Mover(Norte) } }
Martin G.  MENTORÍA  hace 18 días
¡Hola César!
La idea de este ejercicio es modificar la primera versión de MoverSegunBolitas
para que use la función nroBolitasTotal() en vez de la expresión larga.
Acordate que en el ejercicio anterior hicimos a la función nroBolitasTotal() que
hace esto:

1. function nroBolitasTotal() {
2. return (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde))
3. }

¿Notas que algo se repite entre el código que puse arriba y con el código
que tenemos que modificar?

procedure MoverSegunBolitas() {
if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10) {
Mover(Este)
} else{
Mover(Norte)
}
}

function nroBolitasTotal() {
return (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde))
}

SEGÚN LA VERSION UNO


1. procedure MoverSegunBolitas() {
2. if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) +
nroBolitas(Verde) > 10) {
3. Mover(Este)
4. } else {
5. Mover(Norte)
6. }
7. }

MoverSegunBolitas, versión 2
1. procedure MoverSegunBolitas() {
2. if (nroBolitasTotal() > 10) {
3. Mover(Este)
4. } else {
5. Mover(Norte)
6. }
7. }

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

  Si hay más de 10 bolitas, se mueve al Este

 Si hay menos de 10 bolitas, se mueve al Norte

Las funciones son una herramienta importantísima, que nos ayuda a escribir


programas de mayor calidad.

Sólo mirando el código de esta nueva versión del procedimiento podemos


entender de qué va nuestro problema, lo que reduce la distancia entre el
problema real y la estrategia que elegimos para resolverlo.

Ejercicio 4: todasExcepto
Te toca ahora definir tu primera función: todasExcepto(color). Lo que tiene que
hacer es sencillo, contar cuántas bolitas hay en la celda actual sin tener en
cuenta las del color recibido por parámetro.
Por ejemplo, todasExcepto(Verde) debería contar todas las bolitas azules, negras
y rojas que hay en la celda actual (o dicho de otra forma: todas las bolitas
que hay menos las verdes).
Definí la función todasExcepto para que retorne la cantidad de bolitas que no sean del
color que se le pasa por parámetro.
 ¡Dame una pista!
Ya definimos una función para contar todas las bolitas (nroBolitasTotal()) y
Gobstones ya trae una para contar las de un color en particular
(nroBolitas(color)).
Sólo te queda pensar cómo combinarlas. 

SOLUCION MIA CON ERROR


1. function todasExcepto(color) {
2. return (nroBolitasTotal(color))
3. }
Tu solución no pasó las pruebas
Resultados de las pruebas:

  todasExcepto() -> 8

El programa hizo BOOM.

BOOM
[2:9]: La función "nroBolitasTotal" espera recibir ningún parámetro pero se la invoca con un
argumento.

Dada en la consulta con error


1. function todasExcepto(color){
2. return(nroBolitas(Rojo)+ nroBolitas(Azul) +
3. nroBolitas(Negro) - nroBolitas(Verde))
4. }

Hola buenas noches !!! Estuve realizando el ejercicio y casi estuve cerca de la
respuesta correcta (por lo que veo) lo que no se es como agregar el
nroBolitasTotal () . Intente de varias formas pero nada, si me pueden guiar
por favor, gracias !!

Martin G.  MENTORÍA  hace 10 meses

¡Hola Ángeles!
La idea es que la función nos diga cuantas bolitas hay que no sean del color
que llega por párametro, para eso lo que habría que hacer es calcular
cuantas bolitas hay en total (nroBolitasTotal()) y a eso restarle la cantidad de
bolitas del color que llega por párametro (nroBolitas(color)).
Otra solución con error
1. function todasExcepto(color){
2. return(nroBolitastotal()) - nroBolitas(color)
3. }
¡Ups! Tu solución no se puede ejecutar
Resultados:

[2:29]: Se esperaba un comando.


Se encontró: el operador de resta ("-").

SOLUCION CORRECTA
1. function todasExcepto(color){
2. return(nroBolitasTotal()- nroBolitas(color))
3. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  todasExcepto() -> 8
 todasExcepto() -> 10
Las funciones, como cualquier otra expresión, se pueden usar para definir
nuevas funciones.
Y volvemos así a lo más lindo de la programación: la posibilidad de construir
nuestras propias herramientas parándonos sobre cosas que hicimos antes,
logrando que lo que hacemos sea cada vez más poderoso. 

Ejercicio 5: Una función de otro tipo


Como ya sabés, las expresiones no sólo sirven para operar con números.
Vamos a definir ahora una función que retorne un
valor booleano (True / False).
Lo que queremos averiguar es si el color Rojo es dominante dentro de una
celda. Veamos algunos ejemplos.
En este casillero:

444 33
0 0
22 1

rojoEsDominante() retorna False (hay 2 bolitas rojas contra 8 de otros colores).


Pero en este otro:

444 33
0 0
9 1

rojoEsDominante() retorna True (hay 9 bolitas rojas contra 8 de otros colores)

Definí la función rojoEsDominante() que nos diga si la cantidad de bolitas rojas es


mayor que la suma de las bolitas de los otros colores. En
la Biblioteca está todasExcepto(color) lista para ser invocada

¡Dame una pista!

Otra forma de pensarlo: el color rojo es dominante cuando el número de


bolitas rojas es mayor que todas excepto las rojas.
Biblioteca

procedure PonerN(n, color) {


repeat(n) {
Poner(color)
}
}

procedure SacarN(n, color) {


repeat(n) {
Sacar(color)
}
}

procedure MoverN(n, dir) {


repeat(n) {
Mover(dir)
}
}

function nroBolitasTotal() {
/*
...
*/
}

/*
Nos dice cuantas bolitas hay si no contamos el color recibido por parámetro. Por ejemplo,
si tenemos un casillero con 1 bolita roja, 2 verdes, 3 negras y 4 azules
todasExcepto(Negro) nos retornaría 7 (1 + 2 + 4).
*/

function todasExcepto(color) {
/*
...
*/
}

Solucion mia mal

1. function rojoEsDominante(){
2. return(nroBolitasTotal()> nroBolitas(color))
3. }
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:

  rojoEsDominante debe utilizar todasExcepto

Resultados de las pruebas:

  rojoEsDominante() -> False

El programa hizo BOOM.

BOOM
[2:41]: La variable "color" no está definida.

rojoEsDominante() -> True


El programa hizo BOOM.

BOOM
[2:41]: La variable "color" no está definida.

Solucion con error en la consulta

function rojoEsDominante(){
(nroBolitas(Rojo) > todasExcepto(Rojo)){
return True;
}
}
Creo que está bien, pero me sigue dando error. Creo que no está tomando
como definida la función todasExcepto, no me la pone de otro color como
otras.
Mauro G. hace 10 meses
Hola! El código está bien solo que la forma en la cual lo escribiste no es la
correcta. La comparación que estás haciendo dentro de los parentesis te
devuelve un booleano, y todo esto es básicamente lo que debés devolver
con el return. No es una sintaxis correcta hacer esa comparación y devolver
true.
Mayra M. hace 10 meses
¡Hola Paula! Buen dia, como bien dice Mauro el código está bien, solo que
deberias poner la expresión directamente en el return sin el True. Por otro
lado recordá que en Gobstones no ponemos ;
Otra solución con erroren la consulta
function rojoEsDominante(){
if (nroBolitas(Rojo) > todasExcepto(Rojo)){
return True;
}
else {
return False;
}
}
Martin G.  MENTORÍA  hace 10 meses
¡Hola Fernando!
No hace falta el if que estás haciendo porque nroBolitas(Rojo) >
todasExcepto(Rojo) ya es un expresión booleana, es decir, ya por sí misma tiene
un valor de verdad (true o false) por lo que no nos hace falta verificarlo con un
if. Entonces, hay que retornar la expresión nroBolitas(Rojo) > todasExcepto(Rojo) y
nada más.
SOLUCION CORRECTA
1. function rojoEsDominante(){
2. return(nroBolitas(Rojo) > todasExcepto(Rojo))
3. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 rojoEsDominante() -> False porque el rojo es menor

 rojoEsDominante() -> True porque el rojo es mayor


Las funciones pueden retornar distintos tipos: un color, una dirección, un
número o un booleano.
Básicamente, lo que diferencia a un tipo de otro son las operaciones que se
pueden hacer con sus elementos: tiene sentido sumar números, pero no
colores ni direcciones; tiene sentido usar Poner con un color, pero no con un
booleano. Muchas veces, pensar en el tipo de una función es un primer
indicador útil de si lo que estamos haciendo está bien.

Ejercicio 6: En libertad
Queremos definir la función esLibreCostados(), que determine si el cabezal
tiene libertad para moverse hacia los costados (es decir, Este y Oeste).

Antes que nada, pensemos, ¿qué tipo tiene que denotar nuestra función?


Será...

 ... ¿un color? No.


 ... ¿un número? Tampoco.
 ... ¿una dirección? Podría, pero no. Fijate que lo que pide es "saber si
puede moverse" y no hacia dónde.
 ... ¿un booleano? ¡Sí!  Cómo nos dimos cuenta: lo que está pidiendo
tiene pinta de pregunta que se responde con sí o no, y eso es
exactamente lo que podemos representar con un valor
booleano: Verdadero o Falso.

Pero, ups, hay un problema más; hay que hacer DOS preguntas: ¿se puede
mover al Este? Y ¿se puede mover al Oeste?. 

Bueno, existe el operador && que sirve justamente para eso: toma dos


expresiones booleanas y devuelve True solo si ambas son verdaderas. Si
sabés algo de lógica, esto es lo que comunmente se denomina conjunción y
se lo suele representar con el símbolo ∧.

Por ejemplo, si quisieramos saber si un casillero tiene más de 5 bolitas y


el Rojo es el color dominante podríamos escribir:

nroBolitasTotal() > 5 && rojoEsDominante()


Definí la función esLibreCostados() que indique si el cabezal puede moverse
tanto al Este como al Oeste.
Dame una pista!

¡No te olvides de que existe una función puedeMover(direccion)!

Solucion mia correcta

1. function esLibreCostados(){
2. return(puedeMover(Este)&&puedeMover(Oeste))
3. }

¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:
 esLibreCostados() -> False
esLibreCostados() -> True

Ejercicio 7: Cualquier bolita nos deja bien


Definí la función hayAlgunaBolita() que responda a la pregunta ¿hay alguna bolita en la
celda actual?
Otra vez una pregunta, por lo tanto hay que retornar un booleano. Además,
podemos ver que acá también hay que hacer más de una pregunta, en
particular cuatro: una por cada una de los colores.
A diferencia del ejercicio anterior, lo que queremos saber es si alguna de
ellas es verdadera, por lo tanto hay que usar otro operador: la disyunción,
que se escribe | | y retorna verdadero si al menos alguna de las
dos preguntas es verdadera.
De nuevo, si sabés algo de lógica, esta operación suele representarse con el
símbolo ∨.
 ¡Dame una pista!
Recordá que existe la función hayBolitas(color), que indica si hay alguna bolita
del color especificado. Además, el operador | | se puede usar varias veces,
como si fuera una suma: unaCosa | | otraCosa | | otraCosaMas.
Solucion no valida mia VA SOLMENTE ()
function hayAlgunaBolita(color){
return(hayBolitas(color)||hayBolitas(color)||hayBolitas(color)||
hayBolitas(color))
}
Tu solución no pasó las pruebas ROJO VERDE
Resultados de las pruebas:
 hayAlgunaBolita() -> False
El programa hizo BOOM.
BOOM
[5:11]: La función "hayAlgunaBolita" espera recibir un parámetro pero se la invoca con ningún
argumento.

 hayAlgunaBolita() -> True


El programa hizo BOOM.

Solucion de la consulta correcta

function hayAlgunaBolita(){
return (hayBolitas(Verde)||hayBolitas(Rojo)||hayBolitas(Azul)||
hayBolitas(Negro))
}
Agustín V. hace 29 días
Hola! Me está pasando que generalmente puedo hacer los ejercicios, pero
en varias ocasiones en la descripción de los mismos no hay indicios sobre
qué forma del lenguaje (en este caso sería, "hayBolitas()"), debemos usar, y al
lado del editor no hay nada en la biblioteca. Por ejemplo, yo pude resolver
este ejercicio porque primero lo hice mal y luego el mensaje de error me
decía que tenía que utilizar "hayBolitas()", pero sino cómo hubiese sabido yo
eso? No sé si me explico.

Christian C.  MENTORÍA  hace 29 días


Hola Agustín, ¿Cómo estás?
Muchos de los ejercicios tienen debajo el botón ¡Dame una pista! que brinda
información adicional respecto al ejercicio en cuestión. En este caso en
particular, te recomienda usar la función hayBolitas(color) y también el
operador | |. Te recomiendo que siempre veas esa sección para orientarte en
la resolución, ¡es muy útil! Recordá de todos modos que tampoco está mal
equivocarse y llegar luego al resultado correcto con la ayuda del mensaje de
error. Es parte del proceso de aprendizaje, y lo que importa es que al final
logres resolverlo.

SOLUCION CORRECTA
function hayAlgunaBolita(){
return(hayBolitas(Rojo)||hayBolitas(Verde)||hayBolitas(Azul)||hayBolitas(Negro))

}
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  hayAlgunaBolita() -> False


 hayAlgunaBolita() -> True
  hayAlgunaBolita() -> True
  hayAlgunaBolita() -> True

Tanto && como | | pueden usarse varias veces sin la necesidad de usar


paréntesis, siempre y cuando tengan expresiones booleanas a ambos lados.

Ejercicio 8: Siempre al borde...


Te recordamos los operadores lógicos que vimos hasta ahora:

 Negación: "da vuelta" una expresión booleana - ejemplo: not


hayBolitas(Rojo).
 Conjunción: determina si se cumplen ambas condiciones -
ejemplo: puedeMover(Norte) && puedeMover(Sur).
 Disyunción: determina si se cumple alguna de las condiciones -
ejemplo: esInteligente() || tieneBuenaOnda().

Con la ayuda de esa tablita, definí la función estoyEnUnBorde() que determine si el


cabezal está parado en algún borde.
 ¡Dame una pista!
Si el cabezal está en un borde, no se puede mover en alguna dirección.
SSOLUCION MIA MAL
1. function estoyEnUnBorde(){
2. return(not puedeMover(direccion))tengo que hacerlo por cada borde ese es el
error
3. }
Tu solución no pasó las pruebas
Resultados de las pruebas:
  estoyEnUnBorde() -> True El cabezal esta en el borde inferior izquierdo
 El programa hizo BOOM.
 BOOM
 [2:25]: La variable "direccion" no está definida.

 estoyEnUnBorde() -> True


 El programa hizo BOOM. El cabezal esta en el borde medio derecho
 estoyEnUnBorde() -> False
 El programa hizo BOOM. El cabezal esta en el medio de la celda

Solucion con error dada en la consulta

function estoyEnUnBorde(){
return(puedeMover(Norte)|| puedeMover(Sur)&& puedeMover(Oeste)||
puedeMover(Este))
}

Pablo Eugenio Sebastian C. hace 5 meses


buenos dias, ahi pregunto si puede mov norte "o" sur... (verdadero) "y" si
puede mov este "o" oeste(verdadero) y la conjuncion del && deberia ser
verdadero si ambos lo son... nose de que otra manera pensarlo... alguna
sugerencia--? gracias!!!

Mercedes D. hace 5 meses


Hola Pablo! El uso de el procedimiento puedeMover devuelve un valor tipo
booleano (true o talse). En la función que está definida en este ejercicio, le
estás preguntando si puede moverse hacia una dirección, si puede hacerlo
devolverá true y la función estoyEnUnBorde también sera true. Para que la
función cumpla con la consgina, debe devolver true cuando no se puede
mover en cierta dirección, para lograr eso podes usar not. Además, el objetio
es saber si el cabezal está pegado a cualquiera de los cuatro bordes, eso
quiere decir que puede estar en el borde superior derecho o en el superior
izquierdo o en el inferior derecho o en el inferior izquierdo. Es importante
definir todas las partes de la función teniendo en cuenta esto y no pensando
en que puede estar en el borde superior derecho y en el borde superior
izquierdo.

Me dio error DE ESTA CONSULTA

1. function estoyEnUnBorde(){
2. return(not(puedeMover(Norte)|| puedeMover(Sur)&&
puedeMover(Oeste)||puedeMover(Este)))
3. }
 Tu solución no pasó las pruebas
Resultados de las pruebas:
  estoyEnUnBorde() -> True: Se esperaba True pero se obtuvo False.
 El cabezal esta en el borde inferior izquierdo
EstoyEnUnBorde() -> True: Se esperaba True pero se obtuvo False
 El cabezal esta en el borde medio derecho
 estoyEnUnBorde() -> False El cabezal esta en el medio de la celda

SOLUCION CORRECTA

1. function estoyEnUnBorde(){
2. return(not puedeMover(Norte) || not puedeMover(Sur) || not
puedeMover(Este) || not puedeMover(Oeste))
3. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

  estoyEnUnBorde() -> True El cabezal esta en el borde inferior izquierdo


 estoyEnUnBorde() -> True El cabezal esta en el borde medio derecho
 estoyEnUnBorde() -> False El cabezal esta en el medio de la celda
 Como en la aritmética, en la lógica también existe el concepto
de precedencia y ciertas operaciones se resuelven antes que otras:
primero la negación (not), después la conjunción (&&) y por último la
disyunción (||).
 Por esta razón, la expresión not puedeMover(Norte) || not puedeMover(Este) ||
not puedeMover(Sur) || not puedeMover(Oeste)  se puede escribir sin tener que
poner paréntesis en el medio.

Ejercicio 9: Las compañeras ideales


Vamos a ver ahora funciones que hacen cosas antes de retornar un
resultado. Para ejemplificar esto, vamos a querer que definas una función
que nos diga si hay una bolita de un color específico, pero en la celda de al
lado.

Definí la función hayBolitasAl(direccion, color) que informe si hay alguna bolita del color


especificado en la celda vecina hacia la dirección dada.
Ojo: como ya dijimos, la última línea siempre tiene que tener un return.

 ¡Dame una pista!

Acordate que el cabezal sólo puede mirar la celda actual. Por lo tanto, si lo


que queremos es ver si hay bolitas al lado primero habrá que moverse en
esa dirección.

SOLUCION MIA MAL

1. function hayBolitasAl(direccion, color){


2. Mover (direccion)
3. hayBolitas (color)
4. return (previodireccion)ESTO NO VA, VA LO QUE HAY EN 3
5. }

Ups! Tu solución no se puede ejecutar


Resultados:

[3:14]: Se esperaba un operador de asignación (":=").


Se encontró: un paréntesis izquierdo ("(").

function hayBolitasAl(dirección, color){

return (Mover(direccion) || hayBolitas(color)}


SOLUCION CORRECTA
1. function hayBolitasAl(direccion, color){
2. Mover (direccion)
3. return (hayBolitas (color))
4. }
 ¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:

 hayBolitasAl() -> True

hayBolitasAl() -> False


¿Viste qué pasó? El cabezal "no se movió" y sin embargo la función devolvió
el resultado correcto.

Esto pasa porque en Gobstones las funciones son puras, no tienen efecto


real sobre el tablero. En ese sentido decimos que son las compañeras
ideales: después de cumplir su tarea dejan todo como lo encontraron.

Ejercicio 10: Lo ideal también se puede


romper
Como en la definición de hayBolitasAl se usa Mover, es obvio que hay casos en
los cuales podría romperse: basta con posicionar el cabezal en el origen y
preguntar si hayBolitas de algún color al Oeste.

Pero, ¿no era que las funciones eran puras y no tenían efecto real? ¿Qué
pasa si una función hace BOOM?

Hagamos la prueba: vamos a probar la función hayBolitasAl del ejercicio anterior con


casos donde no pueda moverse el cabezal. Presioná Enviar y mirá el resultado.
Solución del ejercicio dada por mumuki
1. function hayBolitasAl(direccion, color) {
2. Mover(direccion)
3. return (hayBolitas(color))
4. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
BOOM
[2:3]: No se puede mover hacia la dirección Sur: cae afuera del tablero.

BOOM
[2:3]: No se puede mover hacia la dirección Oeste: cae afuera del tablero.

¡BOOM! 

Las funciones también pueden producir BOOM y por lo tanto tenés que


tener el mismo cuidado que al programar un procedimiento: que el cabezal
no salga del tablero, no intentar sacar bolitas de un color que no hay, etc.

Pensándolo así, podemos decir que las funciones deshacen sus efectos una


vez que terminan, pero para poder devolver un resultado necesitan que sus
acciones puedan ejecutarse.

Ejercicio 11: ¿Hay bolitas lejos?


Ejercitemos un poco más esto de las funciones con procesamiento.
Te toca programar una nueva versión de hayBolitasAl que mire si hay bolitas a
cierta distancia de la celda actual. A esta función la vamos a
llamar hayBolitasLejosAl y recibirá tres parámetros: una dirección hacia donde
deberá moverse, un color por el cual preguntar y una distancia que será la
cantidad de veces que habrá que moverse.
Por ejemplo: hayBolitasLejosAl(Norte, Verde, 4) indica si hay alguna bolita Verde
cuatro celdas al Norte de la posición actual.

Para este tablero devolvería True: Y para este tablero devolvería False:


0 1
0 1
4 4
1
4 4
3 3
3 3
2 2
2 2
1 1
1 1
0 0
0 0
0 1
0 1

Definí la función hayBolitasLejosAl(direccion, color, distancia).


 ¡Dame una pista!
La idea de "mover el cabezal muchas veces" la resolvimos varias lecciones
atrás con el procedimiento MoverN. Podrías usarlo, ¿no? 
Solucion mia mal
1. function hayBolitasLejosAl(direccion, color, distancia){
2. { esto no va
3. MoverN(Norte, 4) esto debe ir (distancia, direccion)
4. } esto no va
5. return(hayBolitas(color))
6. }
Tu solución no pasó las pruebas
Resultados de las pruebas:
  hayBolitasLejosAl() -> True: El programa hizo BOOM.
 BOOM
 [26:10]: Se esperaba un número pero se recibió una dirección.

Solucion de la consulta con error


1. function hayBolitasLejosAl(direccion,color,distancia){
2. MoverN(distancia,direccion)
3. return (hayBolitas(Negro)||hayBolitas(Azul)||hayBolitas(Verde))||
hayBolitas(Rojo))
4. }
Ayuda! Creo que estoy bien encaminada, pero no sé si lo que falla es la
secuencia en que planteo la función, o la ubicación de paréntesis , o por ahí
es peor y ni me doy cuenta :(
Hola María! En realidad la lógica es correcta. El error que te está marcando
es que hay un parentesis de más cerrando el hayBolitas(Verde). Pero
igualmente hay otro error: no estás aprovechando el parámetro color que la
función está pidiendo.
1. function hayBolitasLejosAl(direccion,color,distancia){
2. MoverN(distancia,direccion)
3. return (hayBolitas(Negro)||hayBolitas(Azul)||hayBolitas(Verde)||
hayBolitas(Rojo))
4. }

Todo el código con operandos OR dentro del return podés resumirlo


chequeando si hay bolitas del color que la función está recibiendo. En lugar
de forzar los colores a mano, probá utilizando el hayBolitas con color

Tu solución no pasó las pruebas


Resultados de las pruebas:

  hayBolitasLejosAl() -> True


 hayBolitasLejosAl() -> True
 hayBolitasLejosAl() -> False: Se esperaba False pero se obtuvo True.

SOLUCION CORRECTA

1. function hayBolitasLejosAl(direccion,color,distancia){
2. MoverN(distancia,direccion)
3. return (hayBolitas(color))
4. }
¡Muy bien! Tu solución pasó todas las pruebas
Resultados de las pruebas:
hayBolitasLejosAl()-> True Aquí esta a distancia hacia el norte la bolita del cabezal
hayBolitasLejosAl()->True Aquí esta la bolita a distancia y el cabezal en el este
hayBolitasLejosAl() -> False
Se puede realizar cualquier tipo de acción antes de retornar un valor, y
nada de lo que hagamos tendrá efecto real sobre el tablero.
Interesante esto de las funciones, ¿no?

Ejercicio 12: Estoy rodeado de viejas


bolitas
Valiéndote de hayBolitasAl, definí la función estoyRodeadoDe(color) que indica si el cabezal
está rodeado de bolitas de ese color.
Decimos que el cabezal "está rodeado" si hay bolitas de ese color en las cuatro
direcciones: Norte, Este, Sur y Oeste.
 ¡Dame una pista!

Ya tenés una forma de determinar si hay bolitas en una dirección. Combiná


eso con el conectivo lógico que corresponda y tendrás tu nueva función
andando.

Biblioteca
procedure PonerN(n, color) {
repeat(n) {
Poner(color)
}
}
procedure SacarN(n, color) {
repeat(n) {
Sacar(color)
}
}
procedure MoverN(n, dir) {
repeat(n) {
Mover(dir)
}
}
function hayBolitasAl(direccion, color) {
Mover(direccion)
return (hayBolitas(color))
}

Solucion mia mal


1. function estoyRodeadoDe(color){
2. hayBolitas(color)
3. return (direccion(Norte)||direccion(Este)||direccion(Oeste)||
direccion(Sur)
4. }
¡Ups! Tu solución no se puede ejecutar
Resultados:

[2:11]: Se esperaba un operador de asignación (":=").


Se encontró: un paréntesis izquierdo ("(").

Solucion no valida dada en la consulta

function estoyRodeadoDe(color) {
return (hayBolitasAl(Norte, color))
(hayBolitasAl(Este,color))
(hayBolitasAl(Oeste,color))
(hayBolitasAl(Sur, color))
}
Hola! me estaría costando encontrar el error, necesito ayuda!

Diana L.  MENTORÍA  hace 5 meses


¡Hola Ariana! ¿Cómo estás?
Como bien hiciste, queremos saber si hay bolitas del color en todas las
direcciones (Norte, Sur, Este y Oeste), el problema es que nos está faltando el
conector lógico. Recordemos que teniamos dos conectores lógicos: && y ||.
Si tuvieramos por ejemplo que cumplir estas tres condiciones para poder ver
si vamos a una playa en una función:

 Esta soleado
 Tengo auto
 Hay una playa cerca

Lo que vamos a hacer es definir una función que una esas condiciones con
un Y lógico, ya que queremos que se cumplan las tres a la vez:
function puedoIrALaPlaya(){
return ( estaSoleado() && tengoAuto() && hayPlayaCerca() )
}

Fijate que tomamos las tres condiciones, las unimos con && (nuestro Y
lógico) y tooodo eso lo retornamos.
Ahora en este ejercicio tenemos 4 condiciones que se tienen que cumplir a
la vez:

 Hay bolitas del color al Este


 Hay bolitas del color al Oeste
 Hay bolitas del color al Norte
 Hay bolitas del color al Sur
 ¿Cómo hacemos que se vea si se cumplen a la vez? ¿Usamos un y
lógico o un o lógico?

SOLUCION CORRECTA

1. function estoyRodeadoDe(color) {
2. return (hayBolitasAl(Norte, color)&&
3. hayBolitasAl(Este,color)&&
4. hayBolitasAl(Oeste,color)&&
5. hayBolitasAl(Sur, color))
6. }

 ¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

  estoyRodeadoDe() -> True El cabezal esta en el medio rodeado de bolitas

estoyRodeadoDe() -> False El cabezal esta en el medio solo rodeado en 3 lados


 estoyRodeadoDe() -> False El cabezal esta en el medio solo rodeado en 2 lados
Por si todavía no nos creías: a pesar de que el cabezal se movió cuatro veces
por cada prueba, al finalizar la función vemos que siempre quedó en la
posición inicial.

Ejercicio 13: Sin límites


Para cerrar, vamos a definir la función hayLimite(), que determina si hay algún
tipo de límite a la hora de mover el cabezal.

El límite puede ser por alguno de dos factores: porque estoy en un borde y


entonces no me puedo mover en alguna dirección, o porque estoy rodeado
de bolitas rojas que me cortan el paso. Si ocurre alguna de esas dos
condiciones, quiere decir que hay un límite.

Usando estoyEnUnBorde y estoyRodeadoDe, definí hayLimite.
 ¡Dame una pista!

Cuidado con el orden de las expresiones: para poder preguntar si está


rodeado, primero deberías chequear si está en un borde.

Biblioteca

procedure PonerN(n, color) {


repeat(n) {
Poner(color)
}
}

procedure SacarN(n, color) {


repeat(n) {
Sacar(color)
}
}

procedure MoverN(n, dir) {


repeat(n) {
Mover(dir)
}
}
function hayBolitasAl(direccion, color) {
Mover(direccion)
return (hayBolitas(color))
}

function estoyRodeadoDe(color) {
return (hayBolitasAl(Norte, color) && hayBolitasAl(Este, color) && hayBolitasAl(Sur,
color) && hayBolitasAl(Oeste, color))
}

function estoyEnUnBorde() {
return (not puedeMover(Norte) || not puedeMover(Este) || not puedeMover(Sur) ||
not puedeMover(Oeste))
}

Ejercicio dado en la consulta con error


function hayLimite() {
return (function estoyEnUnBorde(),function hayBolitasAl(direccion, Rojo))

}
¡Así es, último ejercicio de Fundamentos! Este ejercicio nos pide que usando
estoyEnUnBorde y estoyRodeadoDe definamos la función hayLimite. Recordá que
para usar las funciones estoyEnUnBorde y estoyRodeadoDe, al igual que cuando
invocamos un procedimiento, sólo debemos escribir su nombre seguido de
() donde de ser necesario indicaremos el parámetro. Entonces, tenemos que
usar estas dos funciones para resolver este ejercicio, la primera estoyEnUnBorde
ya la estas usando. En vez de usar hayBolitasAl necesitamos usar estoyRodeadoDe
que por parámetro tendrá ¿qué color? Por otro lado el límite puede ser por
alguno de estos factores, o por un borde o por estar rodeado. ¿Qué
operador lógico podemos usar cuando necesitamos que alguna de esas dos
condiciones se cumpla? Intentalo y cualquier cosa siempre podés volver a
escribirnos

Otra solución mal


1. function hayLimite() {
2. return (estoyEnUnBorde()&&estoyRodeadoDe (Rojo))
3. }
Tu solución no pasó las pruebas
Resultados de las pruebas: Esta mal el operador debe ser ||

  hayLimite() -> True


Se esperaba True pero se obtuvo False. Esta rodeado de rojas y el cabezal
en el medio

 hayLimite() -> True


Se esperaba True pero se obtuvo False. No hay ninguna roja y el cabezal en la
esquina inferior izquierda

hayLimite() -> False Esta rodeado de 3 rojas y el cabezal en el medio

SOLUCION CORRECTA

1. function hayLimite(){
2. return (estoyEnUnBorde() || estoyRodeadoDe(Rojo))
3. }

 ¡Muy bien! Tu solución pasó todas las pruebas


Resultados de las pruebas:

 hayLimite() -> True Esta rodeado de rojas y el cabezal en el medio

 hayLimite() -> True No hay ninguna roja y el cabezal en la esquina inferior izquierda

 hayLimite() -> False Esta rodeado de 3 rojas y el cabezal en el medio

¡Terminaste Funciones!
Esta lección fue bastante intensa, aprendiste unas cuantas cosas:

 conociste las funciones, que son una buena forma de nombrar


expresiones compuestas;
 también vimos que se pueden usar funciones para calcular cosas que
necesitan salir de la celda actual y que el efecto desaparece una vez
que la función se ejecuta;
 ejercitamos los conectivos lógicos || y &&, y vimos que ambos
funcionan con cortocircuito.

¡Sigamos programando! 

Capítulo 2: Programación Imperativa


¿Ya estás para salir del tablero? ¡Acompañanos a aprender más
sobre programación imperativa y estructuras de datos de la mano del
lenguaje JavaScript!

Lecciones
1. Funciones y tipos de datos

  1. Introducción a JavaScript


  2. Funciones, definición
  3. Funciones, uso
  4. Probando funciones
  5. Haciendo cuentas
  6. Poniendo topes
  7. Libros de la buena memoria
  8. Booleanos
  9. Palabras, sólo palabras
  10. Operando strings
  11. ¡GRITAR!
  12. ¿Y qué tal si...?
  13. ¿De qué signo sos?
  14. El retorno del booleano
  15. Los premios
  16. Tipos de datos
  17. Datos de todo tipo

2. Práctica Funciones y Tipos de Datos

  1. Comprando Hardware


  2. ¿Me conviene?
  3. Triangulos
  4. Cuadrados
  5. ¿Está afinado?
  6. ¿Está cerca?
  7. Cartelitos
  8. Más Cartelitos
  9. Cartelitos óptimos
  10. Cara o ceca
  11. ¡Envido!
  12. ¡Quiero retruco!
  13. ¡Quiero vale cuatro!

3. Variables y procedimientos

  1. ¿Y el tablero?
  2. Impresión por pantalla
  3. Martin Fierro
  4. ¿Y los procedimientos?
  5. ¿Y el program?
  6. Coerciones
  7. El círculo de la vida
  8. PIenso que así es más fácil
  9. Esto no tiene valor
  10. Variables globales
  11. La buena fortuna
  12. ¿Y esto cuánto vale?

4. Lógica booleana

  1. ¡Que el último apague la luz!


  2. Negar no cuesta nada
  3. Los peripatéticos
  4. La verdad detrás de la conjunción
  5. ¡Juguemos al T.E.G.!
  6. Y ahora... ¿quién podrá ayudarnos?
  7. ¡Buen día!
  8. La verdad es que no hay una verdad
  9. ¡Hola! Mi nombre es Xor
  10. Precedencia
  11. Un ejercicio sin precedentes
  12. ¿Puedo subir?

5. Listas

  1. Series favoritas


  2. Y esto, es una lista
  3. Juegos de azar
  4. Listas vacías
  5. ¿Cuántos elementos tenés?
  6. Agregando sabor
  7. Trasladar
  8. ¿Y dónde está?
  9. Contiene
  10. Enésimo elemento
  11. Más premios
  12. No te olvides de saludar

6. Registros

  1. Los primeros registros


  2. Tu propio monumento
  3. Accediendo al campo
  4. Temperatura de planeta
  5. Moviendo archivos
  6. Registros de dos milenios
  7. Postres complejos
  8. Listas de registros
  9. 60 dulces minutos
  10. Hay un registro en mi registro
  11. ¡Azúcar!

7. Recorridos

  1. Las ganancias semestrales


  2. ¿Y el resto de las ganancias?
  3. Todas las ganancias, la ganancia
  4. Nos visita un viejo amigo
  5. Cuentas claras
  6. La ganancia promedio
  7. Quién gana, quién pierde
  8. Soy el mapa, soy el mapa
  9. A filtrar, a filtrar cada cosa en su lugar
  10. Un promedio más positivo
  11. Esto es lo máximo
  12. Como mínimo
  13. Los mejores meses del año

Apéndice
¿Querés saber más? Consultá el apéndice de este capítulo

Funciones y tipos de datos


¡Hola! Quizás no te diste cuenta pero ya tenés las bases de la programación:
ya sabés declarar funciones y procedimientos, usar variables, tomar
decisiones empleando la estructura de control if, hacer tareas múltiples
veces. 

Sin embargo, en los programas "reales" rara vez trabajamos con tableros y
bolitas de colores: la programación va más allá de eso. ¿Cómo es entonces
esto de vivir fuera del tablero?

Para responder esta pregunta, primero nos adentraremos en el mundo de


JavaScript, un lenguaje muy popular que no tiene tablero, pero en el que de
todas formas podremos aplicar todo lo visto hasta ahora y descubrir nuevas
ideas y formas de resolver problemas 

¡Acompañanos!

Ejercicios

  1. Introducción a JavaScript


  2. Funciones, definición
  3. Funciones, uso
  4. Probando funciones
  5. Haciendo cuentas
  6. Poniendo topes
  7. Libros de la buena memoria
  8. Booleanos
  9. Palabras, sólo palabras
  10. Operando strings
  11. ¡GRITAR!
  12. ¿Y qué tal si...?
  13. ¿De qué signo sos?
  14. El retorno del booleano
  15. Los premios
  16. Tipos de datos
  17. Datos de todo tipo

Ejercicio 1: Introducción a JavaScript


¿Ya te cansaste de jugar con bolitas de colores?  Tenemos una buena noticia.
En este capítulo vamos a aprender programación imperativa de la mano de
uno de los lenguajes de programación más utilizados de la industria del
software: JavaScript.

Ejercicio 2: Funciones, definición


Gobstones y JavaScript tienen mucho en común. Por ejemplo, en ambos
lenguajes podemos definir funciones y usarlas muchas veces.

Sin embargo, como siempre que aprendas un lenguaje nuevo, te vas a topar
con un pequeño detalle: tiene una sintaxis diferente . La buena noticia es
que el cambio no será tan terrible como suena, así que veamos nuestra
primera función JavaScript:

function doble(numero) {
return 2 * numero;
}

Diferente, pero no tanto. Si la comparás con su equivalente Gobstones...

function doble(numero) {
return (2* numero)
}

...notarás que los paréntesis en el return no son necesarios, y que la última


línea la terminamos con ; .
Veamos si se va entendiendo: definí ahora la función mitad, que tome un número
por parámetro y retorne su mitad. Tené en cuenta que el operador de división en
JavaScript es /.
 ¡Dame una pista!

Para saber la mitad de un número debemos dividirlo por 2. ¡Cuidado!  No es


lo mismo hacer un número dividido 2 que 2 dividido ese número. Por
ejemplo:

10/2
5
2/10
0.2

CONSOLA
function mitad(numero){ return(1/2*numero)}
=> <function>
Solución
function mitad(numero){ return(1/2*numero)}
¡Muy bien! Tu solución pasó todas las pruebas

Perfecto, ¿viste que no era tan terrible? 

Si no le pusiste ; al final de la sentencia habrás visto que funciona igual. De


todas formas ponelo, ya que de esa manera evitamos posibles problemas.

function mitad(numero){ return(1/2*numero); }


Siempre que aprendamos un lenguaje nuevo vamos a tener que aprender
una nueva sintaxis. Sin embargo y por fortuna, si tenés los conceptos claros,
no es nada del otro mundo .

Aprendamos ahora a usar estas funciones.

Ejercicio 3: Funciones, uso


¿Y esto con qué se come? Digo, ehm.... ¿cómo se usan estas funciones?
¿Cómo hago para pasarles argumentos y obtener resultados?
Basta con poner el nombre de la función y, entre paréntesis, sus argumentos.
¡Es igual que en Gobstones!

doble(3)

Y además podemos usarlas dentro de otras funciones. Por ejemplo:

function doble(numero) {
return 2 * numero;
}

function siguienteDelDoble(numero) {
return doble(numero) + 1;
}

O incluso mejor:

function doble(numero) {
return 2 * numero;
}

function siguiente(numero) {
return numero + 1;
}

function siguienteDelDoble(numero) {
return siguiente(doble(numero));
}

Veamos si se entiende; definí las siguientes funciones:

 anterior: toma un número y devuelve ese número menos uno


 triple: devuelve el triple de un número
 anteriorDelTriple, que combina las dos funciones anteriores: multiplica a un
número por 3 y le resta 1

SOLUCION MIA PARA MEJORAR


function anterior(numero) {
return numero - 1;
}
function triple(numero) {
return 3 * numero;
}

function anteriorDelTriple(numero) {
return triple(numero) - 1;
}
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:

  anteriorDelTriple debe utilizar anterior

Resultados de las pruebas:

  anterior anterior(1) es 0
  anterior anterior(10) es 9
  triple triple(1) es 3
  triple triple(3) es 9
  anteriorDelTriple anteriorDelTriple(1) es 2
  anteriorDelTriple anteriorDelTriple(3) es 8
  anteriorDelTriple anteriorDelTriple(10) es 29

solución mia con error


function anterior(numero) {
return numero - 1;
}
function triple(numero) {
return 3 * numero;
}
Aca tendria que haber puesto asi
function anterior(numero) { function anteriorDelTriple(numero) {
return triple(numero) - 1; return (anterior(triple(numero)));
}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:

  anteriorDelTriple debe utilizar triple
  anteriorDelTriple debe utilizar anterior
  la solución debe declarar anteriorDelTriple

Problemas que encontramos:

 parece que estás usando anteriorDelTriple pero no está definido. ¿Puede


que hayas escrito mal su nombre o tengas que definirlo?

 Detalles
Resultados de las pruebas:

Resultados de las pruebas:

  anterior anterior(1) es 0 Ver detalles

2 == 0

  anterior anterior(10) es 9 Ver detalles

29 == 9

  triple triple(1) es 3
  triple triple(3) es 9
  anteriorDelTriple anteriorDelTriple(1) es 2 Ver detalles

anteriorDelTriple is not defined

  anteriorDelTriple anteriorDelTriple(3) es 8 Ver detalles

anteriorDelTriple is not defined

  anteriorDelTriple anteriorDelTriple(10) es 29 Ver detalles

anteriorDelTriple is not defined


SOLUCION CON ERROR A MEJORAR EN LA CONSULTA
function anterior(numero){
return numero-1;
}
function triple(numero){
return numero*3;
}
function anteriorDelTriple(numero){
return triple(numero)-1;
anterior(numero);

me da bien pero me dice que hay para mejorar, la funcionanteriorDelTriple


no entiendo
Juan Ignacio E.  MENTORÍA  hace 23 días
¡Hola Gustavo!
Como bien dice el enunciado del problema podemos usar funciones dentro
de otras funciones.
La función anterior que definiste toma un número y devuelve ese número
menos uno y la función triple te devuelve el triple de un número, entonces
cómo podemos combinar estas dos funciones para definir anteriorDelTriple,
que multiplica a un número por 3 y le resta 1.
Prestale atención a este ejemplo que es muy similar a la solución del
problema:

function doble(numero) {
return 2 * numero;
}

function siguiente(numero) {
return numero + 1;
}

function siguienteDelDoble(numero) {
return siguiente(doble(numero));
}

Aquí la función doble(numero) devuelve el doble de un número, siguiente(numero)


toma un número y devuelve ese número más uno y siguienteDelDoble(numero)
combina las funciones doble(numero) y siguiente(numero) pasándole como
parámetro la función doble a siguiente y de esa manera devuelve el doble de
un número y le suma 1
Solución dada en la consulta con un error expreso de poner disfunction, que
colocando function da bien
disfunction anterior(numero) {
return numero - 1;
}
function triple(numero) {
return numero * 3;
}
function anteriorDelTriple(numero) {
return (anterior(triple(numero)))
}
Jose Maria W. hace 5 meses
hola, el ejercicio lo entendi (lo escribi mal a proposito para llegar acá) El
tema es que no entiendo la sintaxis de Java, es decir, cuando llevan
mayusculas o minusculas... , porque veo que la mayoria empiezan en
minusculas y llevan inicial de palabra en mayusculas, aunque mas adelante
en mitad de este capitulo alguna empiezan con mayusculas, acaso es
obligacion o meramente personal?
Otra pregunta es que se pone en el final de cada capitulo, que recomiendan
descargar el apendice asi nos queda la teoria, etc.., pero no encontre forma
de descargarlo para su posterior impresion
alejandra A.  MENTORÍA  hace 5 meses
¡Hola, Jose! ¿Cómo estás?
Java y JavaScript son dos lenguajes de programación diferentes. Tienen en
común que ambos son lenguajes de programación C, esto significa que
están estructurados de la misma manera. Sin embargo, son muy diferentes
en cuanto a su uso y funcionamiento. El lenguaje JavaScript es utilizado
ampliamente para construir software en todo el mundo, siendo una de las
principales tecnologías de la Web y se trata de un lenguaje interpretado, es
decir que se lee y traduce línea a línea al mismo tiempo que se ejecuta el
programa. Por otro lado, Java es un lenguaje compilado: pasa por una JVM
(Java Virtual Machine) para ser interpretado y traducido al lenguaje de la
«máquina».
El estilo o convención de nonombrado que se usa para escribir nombres
compuestos por varias palabras, en Javascript suele ser el camelCase , es
uno de los más utilizados y extendidos para este lenguaje. Consiste en
escribir la primera palabra en minúsculas y luego la primera letra de cada
palabra siguiente con la primera letra en mayúsculas. Esta sería la forma más
utilizada en Javascript aunque existen otras. Te dejo un link para que si
quisieras puedas seguir investigando:
https://lenguajejs.com/javascript/introduccion/convenciones-de-nombres/
En cuanto al Apéndice, si quisieras imprimirlo haciendo click derecho (o en
Windows presionando "Ctrl + P") podrás acceder al cuadro de diálogo de
impresión.
SOLUCION CORRECTA
function anterior(numero) {
return numero - 1;
}
function triple(numero) {
return numero * 3;
}
function anteriorDelTriple(numero) {
return (anterior(triple(numero)));
}
¡Muy bien! Tu solución pasó todas las pruebas

Quizás ahora estés pensando: si no tengo un tablero, ¿cómo sé si mi función


hace lo que debe? Acompañanos...

Ejercicio 4: Probando funciones


Quizás ya lo notaste pero, junto al editor, ahora aparece una solapa nueva:
la consola.
La consola es una herramienta muy útil para hacer pruebas rápidas sobre lo
que estás haciendo: te permite, por ejemplo, probar expresiones, funciones
que vengan con JavaScript, o incluso funciones que vos definas en el
editor.
La podés reconocer fácilmente porque arranca con el chirimbolito , que se
llama prompt.
Para entender mejor cómo funciona, en qué puede ayudarnos y algunos
consejos sobre su uso, te recomendamos mirar este video.
Veamos si se entiende, probá en la consola las siguientes expresiones:

 4+5
 Math.round(4.5)
 funcionMisteriosa(1, 2, 3) (ya la definimos por vos y la podés usar)

Veamos si se entiende, probá en la consola las siguientes expresiones:


  4 + 5
=> 9
  Math.round(4.5)
=> 5
  funcionMisteriosa(1, 2, 3)
=> 9
   

Ejercicio 5: Haciendo cuentas


Además de los operadores matemáticos +, -, / y *, existen muchas otras
funciones matemáticas comunes, algunas de las cuales ya vienen con
JavaScript y están listas para ser usadas.

Sin embargo, la sintaxis de estas funciones matemáticas es apenitas diferente


de lo que veníamos haciendo hasta ahora: hay que prefijarlas con Math.. Por
ejemplo, la función que nos sirve para redondear un número es Math.round:

function cuantoSaleAproximadamente(precio, impuestos) {


return Math.round(precio * impuestos);
}

Probá en la consola las siguientes expresiones:

 Math.round(4.4)
 Math.round(4.6)
 Math.max(4, 7)
 Math.min(4, 7)

CONSOLA
  Math.round(4.4)
=> 4
  Math.round(4.6)
=> 5
  Math.max(4, 7)
=> 7
  Math.min(4, 7)
=> 4

Ejercicio 6: Poniendo topes


Hagamos un alto en nuestro camino y miremos las
funciones Math.max y Math.min, que nos pueden ahorrar más trabajo del que
parece.
Necesitamos una función que diga cuánta plata queda en tu cuenta (que
tiene un cierto saldo) si extráes un cierto monto:

// el saldo es $100, el monto a extraer, $30


extraer(100, 30)
70 //quedan $70 ($100 - $30 = $70)

Pero como no queremos quedarnos en negativo, si el monto a extraer es


mayor al saldo, nuestro saldo debe quedar en cero.

extraer(100, 120)
0 //Ups, quisimos sacar más plata de la que teníamos.
//Nos quedamos con $0

Como ves, esto es casi una resta entre saldo y monto, con la salvedad de que


estamos poniendo un tope inferior: no puede dar menos de cero .
En otras palabras (¡preparate!, esto te puede volar la
cabeza ) extraer devuelve el máximo entre la resta saldo - monto y 0.
¿Te animás a completar la solución que está en el editor?
 ¡Dame una pista!
¿No te convencimos de que el máximo entre saldo - monto y 0 resuelve nuestro
problema? Compará estos ejemplos con los dos anteriores:

Math.max(100 - 30, 0)
70 // da el máximo entre 70 y 0, que es 70

Math.max(100 - 120, 0)
0 // da el máximo entre -20 y 0, que es 0

Solución
1. function extraer(saldo, monto) {
2. return Math.max(..completar.., ..completar..);
3. }

SOLUCION MIA MAL


function extraer(saldo, monto) {
return Math.max(saldo-monto), 0);
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

solucion.js:2
return Math.max(saldo-monto), 0);
^

SyntaxError: Unexpected token )

Hola, hice bien el ejercicio (ahi le puse a proposito la "F" mayuscula para
poder ingresar acá) pero no entendi como probarlo en la consola

Mercedes D. hace 5 meses


Hola José Maria! Para probar el ejercicio en la consola hay que copiarlo en
ese espacio y luego presionar enter. En este caso tenes que indicar: * El
nombre de la función: extraer * El saldo de la cuenta: un valor númerico * El
monto a extraer: un valor númerico
Ej: extraer (2400,200)

OTRA SOLUCION DE LA CONSULTA CON ERROR


function extraer(saldo, monto) {
return Math.max(saldo - monto, (0))0;
}
Vicente A. hace 6 días
Buenas noches. Me dice que el resultado funciono, pero que podría mejorar.
Me evacuan la duda por favor, gracias.

Guillermo Ignacio B.  MENTORÍA  hace 5 días


¡Hola Vicente! El código está bastante bien encaminado, pero fijate que
Math.max evalúa cual es el máximo entre dos números. Tomemos los
ejemplos de la pista, en el primer ejemplo se obtiene el máximo entre 100 - 30
(es decir, 70) y 0. Fijate que cada número a evaluar está separado por coma,
el primero es una expresión (cuyo resultado es un número) y el segundo
directamente es un número. Esto sería lo mismo que decir Math.max(70, 0) y
obtenemos como resultado 70. Pasando al código vemos que el primer
número está bien, saldo - monto, pero luego hay un 0 entre paréntesis, lo cual
no debería pasar, sino que hay que usar solo 0, ya que la idea es ver el
máximo entre saldo - monto y 0. Luego por fuera de los paréntesis hay otro 0, el
cual no debería estar, por lo que también habría que borrarlo. Modificando
esto el programa debería funcionar bien.

Solución correcta

1. function extraer(saldo, monto) {


2. return Math.max(saldo - monto, 0);
3. }
¡Muy bien! Tu solución pasó todas las pruebas

¡Bien hecho! Ahora andá y probalo en la consola 

Como ves, la función Math.max nos sirvió para implementar un tope inferior.


De forma análoga, la función Math.min nos puede servir para implementar
un tope superior.

Ah, y si estás pensando “en Gobstones podría haber hecho esto con un if”,
¡tenés razón!. Pero esta solución es mucho más breve y simple .

Solución correcta

1. function extraer(saldo, monto) {


2. return Math.max(saldo - monto, 0);
3. }
Consola
  extraer(200, 150)
=> 50
  extraer(50, 100)
=> 0
   

Ejercicio 7: Libros de la buena memoria


¡Veamos más operadores! Dani ama el primer día de cada mes , y por eso
definió esta función...

function esDiaFavorito(diaDelMes) {
return diaDelMes === 1 ;
}

...y la usa así (y la dejó en la biblioteca para que la pruebes):

esDiaFavorito(13)
false
esDiaFavorito(1)
true

Como ves, en JavaScript contamos con operadores como ===, >=, >, <,<= que


nos dicen si dos valores son iguales, mayores-o-iguales, mayores, etc. Los
vamos a usar bastante .

¡Ahora te toca a vos! Dani también dice que a alguien leGustaLeer, cuando la


cantidad de libros que recuerda haber leído es mayor a 20. Por ejemplo:

leGustaLeer(15)
false

leGustaLeer(45)
true

Definí y probá en la consola la función leGustaLeer.


SOLUCION MIA CON ERROR
function leGustaLeer(librosLeidos) {
return librosLeidos === 20 ;
}

Tu solución no pasó las pruebas PORQUE NO LEI BIEN LA CONSIGNA QUE ES IGUAL O
MAYOR A 20.
Resultados de las pruebas:

  si recuerda haber leído 25 libros, le gusta leer Ver detalles

 leGustaLeer(25) debe retornar true

  si recuerda haber leído 80 libros, le gusta leer Ver detalles

 esPar(80) debe retornar true

  si recuerda haber leído 1 libro, no le gusta leer


  si recuerda haber leído 15 libros, no le gusta leer
  leGustaLeer devuelve siempre algo

CONSOLA
 leGustaLeer(15)
=> false
  leGustaLeer(20)
=> true
  leGustaLeer(30)
=> false
   
SOLUCION MIA CORRECTA
function leGustaLeer(librosLeidos) {
return librosLeidos >= 20 ;
}
Consola
 leGustaLeer(20)
=> true
  leGustaLeer(80)
=> true
  leGustaLeer(15)
=> false
¡Muy bien! Tu solución pasó todas las pruebas

¡Bien hecho!

Capaz pasó desapercibido, pero leGustaLeer devuelve true o false, es decir, es


una función que devuelve booleanos. Eso significa que en JavaScript, no sólo
hay números sino que también..... hay booleanos

Ejercicio 8: Booleanos
Ahora miremos a los booleanos con un poco más de detalle:
 Se pueden negar, mediante el operador !: !hayComida
 Se puede hacer la conjunción lógica entre dos booleanos (and,
también conocido en español como y lógico), mediante el
operador &&: hayComida && hayBebida
 Se puede hacer la disyunción lógica entre dos booleanos (or, también
conocido en español como o lógico), mediante el
operador ||: unaExpresion || otraExpresion
Veamos si se entiende; definí las siguientes funciones:
 estaEntre, que tome tres números y diga si el primero es mayor al segundo y
menor al tercero.
 estaFueraDeRango: que tome tres números y diga si el primero es menor al
segundo o mayor al tercero
Ejemplos:

estaEntre(3, 1, 10)
true
estaEntre(90, 1, 10)
false
estaEntre(10, 1, 10)
false
estaFueraDeRango(17, 1, 10)
true

SSOLUCION MIA MAL


function estaEntre(60, 40, 75) {
return 60 && 40 && 75;
estaFueraDeRango (60, 40, 75)
}
¡Ups! Tu solución no se puede ejecutar
Objetivos que no se cumplieron:

  la solución debe declarar estaFueraDeRango


  estaFueraDeRango debe tener tres parámetros
  estaEntre tiene código inalcanzable

Resultados:

solucion.js:1
function estaEntre(60, 40, 75) {
^^
SyntaxError: Unexpected number

Solución dada en la consulta con error


function estaEntre(num, rangoMin, rangoMax){
return (num>rangoMin) && (num<rangoMax);
}

function estaFueraDeRango(num, rangoMin, rangoMax){


return !((num > rangoMin) && (num < rangoMax));
}
Buenas.
En los casos estaEntre(10,1,10) y (4,4,9)el resultado es flase y con
estaFueraDeRango(10,1,10) y (4,4,9) el resultado es true, pero la plataforma
dice que es false

Lara F.  MENTORÍA  hace 10 meses


¡Hola, Uciel! El problema está en los operadores de la función
estaFueraDeRango, fijate que la consigna nos dice : que tome tres números y
diga si el primero es menor al segundo O mayor al tercero , por lo tanto el
único operador que necesitamos será el or. También fijate que el num debe
ser menor al rangoMin (<) y mayor al rangoMax (>). Intentá con esas
modificaciones

Con las modificaciones aplicadas y no pasa las pruebas

function estaEntre(num, rangoMin, rangoMax){


return (num>rangoMin) && (num<rangoMax);
}
function estaFueraDeRango(num, rangoMin, rangoMax){
return !((num > rangoMin) || (num < rangoMax));
}
Tu solución no pasó las pruebas
Resultados de las pruebas:

  estaEntre(10, 1, 10) es false


  estaEntre(4, 4, 9) es false
  estaEntre(12, 1, 10) es false
  estaEntre(200, 54, 112) es false
  estaEntre(67, 50, 100) es true
  estaEntre(2, 1, 100) es true
  estaFueraDeRango(10, 1, 10) es false
  estaFueraDeRango(4, 4, 9) es false
  estaFueraDeRango(12, 1, 10) es true Ver detalles

 false == true

  estaFueraDeRango(200, 54, 112) es true Ver detalles


 false == true

  estaFueraDeRango(67, 0, 100) es false


  estaFueraDeRango(2, 0, 100) es false
  estaEntre devuelve siempre algo
  estaFueraDeRango devuelve siempre algo
OOTRA SOLUCIONDE LA CONSULT CON ERROR
function estaEntre(num, rangoMin, rangoMax){
return (num>rangoMin) && (num<rangoMax);
}
function estaFueraDeRango(num, rangoMin, rangoMax){
return !((num > rangoMin) && (num < rangoMax));
}
El problema está en los operadores de la función estaFueraDeRango, fijate que la
consigna nos dice : que tome tres números y diga si el primero es menor al segundo O
mayor al tercero , por lo tanto el único operador que necesitamos será el or.
También fijate que el num debe ser menor al rangoMin (<) y mayor al rangoMax
(>). Intentá con esas modificaciones
SOLUCION CORRECTA
function estaEntre(num1, num2, num3){
return(num1 > num2 && num1 < num3)
}
function estaFueraDeRango(num1, num2, num3){
return(num1 > num2 && num1 > num3)
}

CONSOLA
 true
  estaEntre(40, 30, 60)
=> true
  estaFueraDeRango(3, 1, 10)
=> false
  estaFueraDeRango(60, 40, 30)
=> true

 ¡Muy bien! Tu solución pasó todas las pruebas

¡Bien hecho!
Ya fueron suficientes booleanos y cuentas por ahora, ¿no? Exploremos algo
más interesante: los strings.

Ejercicio 9: Palabras, sólo palabras


Muchas veces queremos escribir programas que trabajen con texto :
queremos saber cuántas palabras hay en un libro, o convertir minúsculas a
mayúsculas, o saber en qué parte de un texto está otro.

Para este tipo de problemas tenemos los strings, también llamados cadenas


de caracteres:

 "Ahora la bebé tiene que dormir en la cuna"


 'El hierro nos ayuda a jugar'
 "¡Hola Miguel!"

Como se observa, todos los strings están encerrados entre comillas simples
o dobles. ¡Da igual usar unas u otras! Pero sé consistente: por ejemplo, si
abriste comilla doble, tenés que cerrar comilla doble. Además, un string
puede estar formado por (casi) cualquier carácter: letras, números, símbolos,
espacios, etc.

¿Y qué podemos hacer con los strings? Por ejemplo, compararlos, como a
cualquier otro valor:

"hola" === "Hola"


false

"todo el mundo" === "todo el mundo"


true

Veamos si queda claro: definí la función esFinDeSemana que tome un string que


represente el nombre de un día de la semana, y nos diga si es "sábado" o "domingo".

esFinDeSemana("sábado")
true
esFinDeSemana("martes")
false

 ¡Dame una pista!


Para saber si un día es fin de semana, ese día tiene que ser "sábado" o ese día
tiene que ser "domingo". Recordá que el "o lógico" opera booleanos, no
strings. 
SOLUCION MIA MAL
function esFinDeSemana(feriado){
return feriado === sabado || feriado === domingo)
}
¡Ups! Tu solución no se puede ejecutar
Resultados:

solucion.js:2
return feriado === sabado || feriado === domingo)
^
SyntaxError: Unexpected token )

Solución de la consulta con error


function esFinDeSemana(dia){
return "dia"== "sábado" || "dia"== "domingo"
}
No entiendo xq el código me da OK para todos los días, pero para sábado y
domingo me da que es falso el ||
Muchas gracias.

Diana L.  MENTORÍA  hace 10 meses


¡Hola Marcos!
Cuando usamos los parámetros dentro de nuestra función, lo hacemos sin
usar las comillas. Por ejemplo : return dia == "sábado". Probá quitandole las
comillas.

Solución mia valida a mejorar


function esFinDeSemana(dia){
return dia == "sabado" || dia == "domingo"
}
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:

  esFinDeSemana debería usar los operadores de equivalencia === y !== en


lugar de los operadores de similitud == y !=
Resultados de las pruebas:

  esFinDeSemana("sábado")
  esFinDeSemana("domingo")
  esFinDeSemana("lunes")
  esFinDeSemana("jueves")

SOLUCION MIA CORRECTA


function esFinDeSemana(feriado){
return feriado === "sabado" || feriado === "domingo"
}
¡Muy bien! Tu solución pasó todas las pruebas

CONSOLA
 esFinDeSemana ("sabado")
=> true
  esFinDeSemana ("lunes")
=> false
  esFinDeSemana ("domingo")
=> true

Ejercicio 10: Operando strings


¿Y qué podemos hacer con los strings, además de compararlos? ¡Varias
cosas! Por ejemplo, podemos preguntarles cuál es su cantidad de letras:

longitud("biblioteca")
10
longitud("babel")
5

O también podemos concatenarlos, es decir, obtener uno nuevo que junta


dos strings:

"aa" + "bb"
"aabb"
"sus anaqueles " + "registran todas las combinaciones"
"sus anaqueles registran todas las combinaciones"

O podemos preguntarles si uno comienza con otro:

comienzaCon("una página", "una")


true
comienzaCon("la biblioteca", "todos los fuegos")
false

Veamos si queda claro: definí la función longitudNombreCompleto, que tome un nombre y


un apellido, y retorne su longitud total, contando un espacio extra para separar a
ambos:

longitudNombreCompleto("Cosme", "Fulanito")
14

SOLUCION MIA CON ERROR


function longitudNombreCompleto(longitud)
return longitud ("nombre" + "apellido");
Ups! Tu solución no se puede ejecutar
Resultados:

solucion.js:2
return longitud ("nombre" + "apellido");
^^^^^^
SyntaxError: Unexpected token return

Biblioteca
/**/

function longitud(unString) /* ... */


// Retorna cuan largo es un string
//
// Por ejemplo:
//
// longitud("hola")
// 4

function convertirEnMayuscula(unString) /* ... */


// Convierte una palabra en mayúsculas
//
// Por ejemplo:
//
// convertirEnMayuscula("hola")
// "HOLA"

function comienzaCon(unString, otroString) /* ... */


// Retorna un booleano que nos dice si unString empieza con otroString
//
// Por ejemplo:
//
// comienzaCon("hola todo el mundo", "hola todo")
// true

SOLUCION CORRECTA
function longitudNombreCompleto(nombre,apellido){
return longitud(nombre+apellido+1) ESTE MAS 1 ES POR EL ESPACIO DE SEPARACION
}
¡Muy bien! Tu solución pasó todas las pruebas

CONSOLA
 longitudNombreCompleto("juan" , "perez")
=> 10
   

También podría gustarte