Parcours
/
Elixir
Elixir
/
Exercices
/
Meilleur score
Meilleur score

Meilleur score

Exercice d'apprentissage

Introduction

Les maps

Les maps en Elixir sont la structure de données qui permet de stocker des informations sous forme de paires clé-valeur. Dans d'autres langages, on les connaît aussi sous le nom de tableaux associatifs (PHP), de tables de hachage (Perl 5, Raku) ou de dictionnaires (Python).

Les clés et les valeurs peuvent être de n'importe quel type, mais si la clé est un atome, on peut utiliser une syntaxe abrégée. L'ordre des entrées d'une map n'est pas garanti, qu'on y accède ou qu'on la renvoie.

Les formes littérales

Une map vide se déclare simplement avec %{}. Si on veut ajouter des éléments à une map littérale, on peut utiliser deux formes :

# If the key is an atom:
%{atom_key: 1}

# If the key is a different type:
%{1 => :atom_value}

# You can even mix these if the atom form comes second:
%{"first_form" => :a, atom_form: :b}

Il n'existe pas de format canonique, alors choisis une façon cohérente de représenter les paires clé-valeur.

Les fonctions du module Map

Elixir fournit de nombreuses fonctions pour manipuler les maps dans le module Map. Certaines fonctions du module Map demandent qu'on leur passe une fonction anonyme pour faciliter la transformation de la map.

Les attributs de module comme constantes

En Elixir, on peut définir des attributs de module qui peuvent servir de constantes dans nos fonctions.

defmodule Example do
  # Defines the attribute as the value 1
  @constant_number 1

  def example_value() do
    # Returns the value 1
    @constant_number
  end
end

Lorsqu'on les utilise pour définir des constantes de module, les attributs peuvent être n'importe quelle expression évaluable au moment de la compilation. Après la compilation, les attributs de module ne sont plus accessibles, car ils sont développés pendant la compilation, un peu comme les macros définies dans des langages tels que le C.

Instructions

Dans cet exercice, tu mets en place un moyen de garder une trace des meilleurs scores du jeu le plus populaire de la salle d'arcade près de chez toi.

1. Définis une nouvelle map de meilleurs scores

Pour créer une nouvelle map de meilleurs scores, définis la fonction HighScore.new/0, qui ne prend aucun argument et renvoie une nouvelle map vide de meilleurs scores.

HighScore.new()
# => %{}

2. Ajoute des joueurs à la map des meilleurs scores

Pour ajouter un joueur à la map des meilleurs scores, définis HighScore.add_player/3, une fonction qui prend 3 arguments :

  • Le premier argument est la map des scores.
  • Le deuxième argument est le nom d'un joueur, sous forme de string.
  • Le troisième argument est le score, sous forme d'entier. Cet argument est optionnel : implémente le troisième argument avec une valeur par défaut de 0.

Stocke le score initial par défaut dans un attribut de module. On en aura de nouveau besoin.

score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "Dave Thomas")
# => %{"Dave Thomas" => 0}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"Dave Thomas" => 0, "José Valim"=> 486_373}

3. Supprime des joueurs de la map des scores

Pour supprimer un joueur de la map des meilleurs scores, définis HighScore.remove_player/2, qui prend 2 arguments :

  • Le premier argument est la map des scores.
  • Le deuxième argument est le nom du joueur, sous forme de string.
score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "Dave Thomas")
# => %{"Dave Thomas" => 0}
score_map = HighScore.remove_player(score_map, "Dave Thomas")
# => %{}

4. Réinitialise le score d'un joueur

Pour réinitialiser le score d'un joueur, définis HighScore.reset_score/2, qui prend 2 arguments :

  • Le premier argument est la map des scores.
  • Le deuxième argument est le nom du joueur, sous forme de string, dont tu souhaites réinitialiser le score.

La fonction doit aussi fonctionner si le joueur n'a pas de score.

score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"José Valim"=> 486_373}
score_map = HighScore.reset_score(score_map, "José Valim")
# => %{"José Valim"=> 0}

5. Mets à jour le score d'un joueur

Pour mettre à jour le score d'un joueur en l'ajoutant au score précédent, définis HighScore.update_score/3, qui prend 3 arguments :

  • Le premier argument est la map des scores.
  • Le deuxième argument est le nom du joueur, sous forme de string, dont tu souhaites mettre à jour le score.
  • Le troisième argument est le score que tu souhaites ajouter au meilleur score enregistré.

La fonction doit aussi fonctionner si le joueur n'a pas de score précédent : considère que le score précédent vaut 0.

score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"José Valim"=> 486_373}
score_map = HighScore.update_score(score_map, "José Valim", 5)
# => %{"José Valim"=> 486_378}

6. Récupère un tableau de joueurs

Pour obtenir un tableau de joueurs, définis HighScore.get_players/1, qui prend 1 argument :

  • Le premier argument est la map des scores.
score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "Dave Thomas", 2_374)
# => %{"Dave Thomas" => 2_374}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"Dave Thomas" => 2_374, "José Valim"=> 486_373}
HighScore.get_players(score_map)
# => ["Dave Thomas", "José Valim"]
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Elixir Exercism

Prêt à commencer Meilleur score ?

Inscris-toi sur Exercism pour apprendre et maîtriser Elixir avec 58 concepts168 exercices, et un vrai mentorat humain, le tout gratuitement.