Tracks
/
Clojure
Clojure
/
Ejercicios
/
Juegos de cartas
Juegos de cartas

Juegos de cartas

Ejercicio de aprendizaje

Introducción

En Clojure, las listas son colecciones, igual que las listas en otros lenguajes. Al igual que otros lenguajes de la familia Lisp, Clojure usa paréntesis para expresar listas.

Las listas de Clojure se pueden crear de una de dos maneras. La función list puede crear una lista, o puedes aplicar quote a una lista literal.

Las listas son especiales porque Clojure las trata como llamadas. Espera que la llamada comience con un operador, que normalmente es una función. Los demás elementos de la lista se consideran operandos, lo que significa que se convierten en los argumentos de la función.

El tratamiento especial que Clojure da a las listas es la razón por la que no podemos crear una lista literal directamente. Aplicar quote a una lista, o su forma abreviada ', indica que la lista no debe evaluarse.

A diferencia de algunos lenguajes modernos, las listas de Clojure son heterogéneas, es decir, pueden contener varios tipos de elementos internamente, por ejemplo, '(2 "a" "b" 3). A diferencia de otros Lisps, una lista vacía en Clojure se evalúa como verdadera y no equivale a nil ni a false.

Instrucciones

Elyse está deseando jugar un poco de póker (y otros juegos de cartas) durante su próximo viaje a Las Vegas. Como es muy fanática del «autoseguimiento», quiere armar unas funciones pequeñas que la ayuden con las tareas de seguimiento y te ha pedido ayuda para pensarlas bien.

1. Seguimiento de las rondas de póker

Elyse es especialmente aficionada al póker y quiere llevar un registro de cuántas rondas juega, y cuáles rondas son. Cada ronda tiene su propio número, y cada mesa muestra el número de la ronda que se está jugando en ese momento. Elyse elige una mesa y se sienta a jugar su primera ronda. Planea jugar tres rondas.

Implementa una función rounds que recibe el número de la ronda actual y devuelve una única list con esa ronda y las dos siguientes que vienen:

(rounds 27)
;;=> (27 28 29)

2. Mantener todas las rondas en el mismo lugar

Elyse jugó algunas rondas en la primera mesa, luego se tomó un descanso y jugó algunas rondas más en una segunda mesa... ¡pero terminó con una lista diferente por cada mesa! Quiere juntar las dos listas para poder llevar el registro de todas las rondas de póker en el mismo lugar.

Implementa una función concat-rounds que recibe dos listas y devuelve una única list que consiste en todas las rondas de la primera list, seguidas de todas las rondas de la segunda list:

(concat-rounds '(27 28 29) '(35 36))
;;=> (27 28 29 35 36)

3. Encontrar rondas anteriores

Hablando de algunas rondas anteriores de póker, otro jugador comenta lo parecido que resultaron dos de ellas. Elyse no está segura de si jugó esas rondas o no.

Implementa una función contains-round? que recibe dos argumentos: una lista de rondas jugadas y un número de ronda. La función devolverá true si la ronda está en la lista de rondas jugadas, y false si no:

(contains-round? '(27 28 29 35 36) 29)
;;=> true

(contains-round? '(27 28 29 35 36) 30)
;;=> false

4. Promediar los valores de las cartas

Elyse quiere probar un juego nuevo llamado Black Joe. Es parecido al Black Jack, donde tu objetivo es que las cartas de tu mano sumen un valor objetivo, pero en Black Joe el objetivo es que el promedio de los valores de las cartas sea 7. El promedio se puede hallar sumando todos los valores de las cartas y luego dividiendo esa suma entre la cantidad de cartas de la mano.

Implementa una función card-average que devuelva el valor promedio de una mano de Black Joe.

(card-average '(5 6 7))
;;=> 6.0

5. Promedios alternativos

En Black Joe, la velocidad es importante. Elyse va a intentar encontrar una forma más rápida de calcular el promedio.

Se le han ocurrido dos maneras de obtener un número parecido al promedio:

  • Tomar el promedio del primer y el último número de la mano.
  • Usar la mediana (la carta del medio) de la mano.

Implementa la función approx-average?, que recibe hand, una lista con los valores de las cartas de tu mano.

Devuelve true si una or ambas de las estrategias mencionadas arriba dan como resultado un número igual al promedio real.

Nota: la longitud de todas las manos es impar, para que sea más fácil encontrar la mediana.

(approx-average? '(1 2 3))
;;=> true

(approx-average? '(2 3 4 8 8))
;;=> true

(approx-average? '(1 2 3 5 9))
;;=> false

6. Más técnicas de promedio

Intrigada por los resultados de su experimento con promedios, Elyse se pregunta si tomar el promedio de las cartas en las posiciones pares frente al promedio de las cartas en las posiciones impares daría los mismos resultados. ¡Hora de otra función de prueba!

Implementa una función average-even-odd? que devuelva un Boolean que indique si el promedio de las cartas en los índices pares es igual al promedio de las cartas en los índices impares.

(average-even-odd? '(1 2 3))
;;=> true

(average-even-odd? '(1 2 3 4))
;;=> false

7. Reglas de la ronda de bonificación

Cada onceava mano en Black Joe es una mano de bonificación con una regla especial: si la última carta que sacas es un Jack, duplicas su valor.

Implementa una función maybe-double-last que recibe una mano y verifica si la última carta es un Jack (11). Si la última carta es un Jack (11), duplica su valor antes de devolver la mano.

(maybe-double-last '(5 9 11))
;;=> '(5 9 22)

(maybe-double-last '(5 9 10))
;;=> '(5 9 10)
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Clojure Exercism

¿Todo listo para empezar Juegos de cartas?

Regístrate en Exercism para aprender y dominar Clojure con 12 conceptos105 ejercicios y mentoría humana real, todo gratis.