Aujourd'hui, la plupart des gens dans le monde utilisent les chiffres arabes (0–9). Mais si tu remontais deux mille ans en arrière, tu découvrirais que la plupart des Européens utilisaient plutôt les chiffres romains.
Pour écrire un chiffre romain, on utilise les lettres latines suivantes, qui ont chacune une valeur :
| M | D | C | L | X | V | I |
|---|---|---|---|---|---|---|
| 1000 | 500 | 100 | 50 | 10 | 5 | 1 |
Un chiffre romain est une suite de ces lettres, et sa valeur est la somme des valeurs de ces lettres.
Par exemple, XVIII a la valeur 18 (10 + 5 + 1 + 1 + 1 = 18).
Il y a cependant une règle qui complique les choses : une même lettre ne peut pas être utilisée plus de trois fois de suite.
Cela signifie qu'on ne peut pas exprimer des nombres comme 4 avec le IIII qui semble pourtant naturel.
À la place, pour ces nombres, on utilise une méthode de soustraction entre deux lettres.
On conçoit donc 4 non pas comme 1 + 1 + 1 + 1, mais comme 5 - 1.
Et, ce qui peut sembler un peu déroutant pour notre esprit moderne, on écrit le plus petit nombre en premier.
Cela ne s'applique que dans les cas suivants : 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD) et 900 (CM).
L'ordre compte dans les chiffres romains ! Les lettres (et les composés particuliers ci-dessus) doivent être ordonnées par valeur décroissante, de gauche à droite.
Voici quelques exemples :
105 => CV
---- => --
100 => C
+ 5 => V
106 => CVI
---- => --
100 => C
+ 5 => V
+ 1 => I
104 => CIV
---- => ---
100 => C
+ 4 => IV
Et un dernier exemple plus complexe :
1996 => MCMXCVI
----- => -------
1000 => M
+ 900 => CM
+ 90 => XC
+ 5 => V
+ 1 => I
Ta tâche consiste à convertir un nombre écrit en chiffres arabes en chiffres romains.
Dans cet exercice, on ne s'intéresse qu'aux chiffres romains traditionnels, dans lesquels le plus grand nombre est MMMCMXCIX (soit 3 999).
Il existe de nombreuses façons différentes de convertir des chiffres arabes en chiffres romains. On te recommande d'adopter d'abord une approche naïve pour te familiariser avec le concept de chiffres romains, puis de chercher des méthodes plus efficaces.
Pense à regarder notre vidéo Analyse approfondie à la fin pour explorer les différentes approches possibles !
Pour changer un peu, tu peux aussi essayer une solution avec une fonction unfold. Tu connais sans doute déjà foldLeft/Right : « map » toute une collection en autre chose (en général, autre chose qu'une collection). unfoldLeft/Right sont les opérations « inverses » : « map » quelque chose (en général, autre chose qu'une collection) en une collection. Utiliser unfold est donc un ajout logique au répertoire standard de la programmation fonctionnelle, et cela en fait partie.
Cet exercice peut se voir comme un cas d'application de unfold : « map » un Int en String (qui est bien sûr implicitement un Seq[Char]).
Malheureusement, unfoldLeft/Right ne fait pas partie de la bibliothèque de collections de Scala. Mais tu peux récupérer l'implémentation ici.
Inscris-toi sur Exercism pour apprendre et maîtriser Scala avec 95 exercices, et un vrai mentorat humain, le tout gratuitement.
Découvre une variété de solutions différentes à cet exercice délicat, de la récursion aux tables de correspondance, en passant par une solution qui utilise des nombres à base mixte, et quelques triches simplistes en Common Lisp.