En Clojure, las listas son colecciones, igual que las listas de 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 dos maneras. La función list puede crear una lista, o puedes usar quote con una lista literal.
Las listas son especiales porque Clojure las trata como llamadas. Espera que la llamada empiece por un operador, que normalmente es una función. Los elementos restantes de la lista se consideran operandos, es decir, se convierten en los argumentos de la función.
Este trato especial que Clojure da a las listas es la razón por la que no podemos crear una lista literal directamente. Usar quote con 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 elementos de varios tipos, por ejemplo, '(2 "a" "b" 3).
A diferencia de otros Lisp, una lista vacía en Clojure es verdadera y no equivale a nil ni a false.
Elyse tiene muchas ganas de jugar un poco al póker (y a otros juegos de cartas) durante su próximo viaje a Vegas. Como es una gran fanática del «autoseguimiento», quiere crear unas cuantas funciones pequeñas que la ayuden con las tareas de seguimiento y te ha pedido ayuda para pensarlas bien.
Elyse es especialmente aficionada al póker y quiere llevar un registro de cuántas rondas juega, y de qué rondas se trata. 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. Tiene previsto jugar tres rondas.
Implementa una función rounds que toma el número de la ronda actual y devuelve un único list con esa ronda y las dos siguientes que están por llegar:
(rounds 27)
;;=> (27 28 29)
Elyse jugó unas cuantas rondas en la primera mesa, luego se tomó un descanso y jugó algunas rondas más en una segunda mesa... ¡pero acabó con un array distinto para cada mesa! Quiere juntar los dos arrays para poder llevar un registro de todas las rondas de póker en el mismo sitio.
Implementa una función concat-rounds que toma dos arrays y devuelve un único list formado por todas las rondas del primer list, seguidas de todas las rondas del segundo list:
(concat-rounds '(27 28 29) '(35 36))
;;=> (27 28 29 35 36)
Hablando de algunas de las rondas anteriores de póker, otro jugador comenta lo parecidas que le salieron dos de ellas. Elyse no está segura de si jugó esas rondas o no.
Implementa una función contains-round? que toma dos argumentos, un array de rondas jugadas y un número de ronda.
La función devolverá true si la ronda está en el array 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
Elyse quiere probar un juego nuevo llamado Black Joe. Es parecido al Black Jack, en el que el objetivo es que las cartas de tu mano sumen un valor concreto, pero en Black Joe el objetivo es que la media de los valores de las cartas sea 7. La media se puede calcular sumando todos los valores de las cartas y dividiendo después esa suma entre el número de cartas de la mano.
Implementa una función card-average que devuelva el valor medio de una mano de Black Joe.
(card-average '(5 6 7))
;;=> 6.0
En Black Joe la velocidad es importante. Elyse va a intentar encontrar una forma más rápida de calcular la media.
Se le han ocurrido dos formas de obtener un número parecido a la media:
Implementa la función approx-average? a la que se le pasa hand, un array que contiene los valores de las cartas de tu mano.
Devuelve true si una or ambas de las estrategias mencionadas antes dan como resultado un número igual a la media 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
Intrigada por los resultados de su experimento con las medias, Elyse se pregunta si calcular la media de las cartas en las posiciones pares frente a la media de las cartas en las posiciones impares daría el mismo resultado. ¡Es hora de otra función de prueba!
Implementa una función average-even-odd? que devuelve un Boolean que indica si la media de las cartas en los índices pares es igual a la media de las cartas en los índices impares.
(average-even-odd? '(1 2 3))
;;=> true
(average-even-odd? '(1 2 3 4))
;;=> false
Cada undécima mano de Black Joe es una mano con bonus y una regla de bonus: si la última carta que robas es una jota, duplicas su valor.
Implementa una función maybe-double-last que toma una mano y comprueba si la última carta es una jota (11).
Si la última carta es una jota (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)
Regístrate en Exercism para aprender y dominar Clojure con 12 conceptos105 ejercicios y mentoría humana real, todo gratis.