En Clojure, les listes sont des collections, tout comme les listes dans d'autres langages. Comme dans les autres langages de la famille Lisp, Clojure utilise des parenthèses pour exprimer les listes.
On peut créer une liste en Clojure de deux façons. La fonction list permet de créer une liste, ou tu peux écrire quote devant une liste littérale.
Les listes sont particulières, car Clojure les traite comme des appels. Il s'attend à ce que l'appel commence par un opérateur, qui est généralement une fonction. Les autres éléments de la liste sont considérés comme des opérandes, ce qui signifie qu'ils deviennent les arguments de la fonction.
Le traitement particulier que Clojure réserve aux listes explique pourquoi on ne peut pas créer directement une liste littérale. Écrire quote ou son abréviation ' devant une liste indique que cette liste ne doit pas être évaluée.
Contrairement à certains langages modernes, les listes en Clojure sont hétérogènes : elles peuvent contenir en interne des éléments de types différents, par exemple '(2 "a" "b" 3).
Contrairement aux autres Lisp, une liste vide en Clojure est considérée comme vraie et n'est pas équivalente à nil ni à false.
Elyse se réjouit vraiment de jouer au poker (et à d'autres jeux de cartes) lors de son prochain voyage à Vegas. Grande adepte de l'« auto-suivi », elle veut assembler quelques petites fonctions qui l'aideront dans ses tâches de suivi, et elle t'a demandé de l'aider à réfléchir à leur conception.
Elyse adore particulièrement le poker et veut suivre le nombre de manches qu'elle joue, ainsi que quelles manches il s'agit. Chaque manche porte son propre numéro, et chaque table affiche le numéro de la manche en cours. Elyse choisit une table et s'assoit pour jouer sa première manche. Elle compte en jouer trois.
Implémente une fonction rounds qui prend le numéro de la manche courante et renvoie un seul list contenant cette manche et les deux suivantes :
(rounds 27)
;;=> (27 28 29)
Elyse a joué quelques manches à la première table, puis a fait une pause et a joué d'autres manches à une deuxième table… mais s'est retrouvée avec une liste différente pour chaque table ! Elle veut réunir les deux listes pour pouvoir suivre toutes ses manches de poker au même endroit.
Implémente une fonction concat-rounds qui prend deux listes et renvoie un seul list composé de toutes les manches de la première list, suivies de toutes les manches de la deuxième list :
(concat-rounds '(27 28 29) '(35 36))
;;=> (27 28 29 35 36)
En parlant de certaines manches de poker précédentes, un autre joueur fait remarquer que deux d'entre elles se sont déroulées de façon très similaire. Elyse ne sait pas trop si elle a joué ces manches ou non.
Implémente une fonction contains-round? qui prend deux arguments, une liste de manches jouées et un numéro de manche. La fonction renvoie true si la manche figure dans la liste des manches jouées, false sinon :
(contains-round? '(27 28 29 35 36) 29)
;;=> true
(contains-round? '(27 28 29 35 36) 30)
;;=> false
Elyse veut essayer un nouveau jeu appelé Black Joe. Il ressemble au Black Jack, où le but est que les cartes de ta main totalisent une valeur cible, sauf qu'au Black Joe, le but est que la moyenne des valeurs des cartes soit égale à 7. On obtient la moyenne en additionnant toutes les valeurs des cartes, puis en divisant cette somme par le nombre de cartes de la main.
Implémente une fonction card-average qui renvoie la valeur moyenne d'une main au Black Joe.
(card-average '(5 6 7))
;;=> 6.0
Au Black Joe, la vitesse compte. Elyse va chercher un moyen plus rapide de calculer la moyenne.
Elle a pensé à deux façons d'obtenir un nombre proche d'une moyenne :
Implémente la fonction approx-average?, qui prend hand, une liste contenant les valeurs des cartes de ta main.
Renvoie true si l'une or les deux des stratégies nommées ci-dessus donnent un nombre égal à la moyenne réelle.
Remarque : la taille de toutes les mains est impaire, ce qui facilite la recherche de la médiane.
(approx-average? '(1 2 3))
;;=> true
(approx-average? '(2 3 4 8 8))
;;=> true
(approx-average? '(1 2 3 5 9))
;;=> false
Intriguée par les résultats de son expérience sur les moyennes, Elyse se demande si faire la moyenne des cartes aux positions paires et celle des cartes aux positions impaires donnerait le même résultat. Il est temps d'écrire une nouvelle fonction de test !
Implémente une fonction average-even-odd? qui renvoie un booléen indiquant si la moyenne des cartes aux indices pairs est la même que la moyenne des cartes aux indices impairs.
(average-even-odd? '(1 2 3))
;;=> true
(average-even-odd? '(1 2 3 4))
;;=> false
Chaque 11ᵉ main au Black Joe est une main bonus, avec sa règle bonus : si la dernière carte que tu tires est un valet, tu doubles sa valeur.
Implémente une fonction maybe-double-last qui prend une main et vérifie si la dernière carte est un valet (11). Si la dernière carte est un valet (11), double sa valeur avant de renvoyer la main.
(maybe-double-last '(5 9 11))
;;=> '(5 9 22)
(maybe-double-last '(5 9 10))
;;=> '(5 9 10)
Inscris-toi sur Exercism pour apprendre et maîtriser Clojure avec 12 concepts105 exercices, et un vrai mentorat humain, le tout gratuitement.