Écrire un nombre en chiffres romains⚓︎
On souhaite dans cet exercice écrire des nombres entiers strictement positifs en chiffres romains.
Cette notation a évolué au fil des siècles. On se propose ici d'utiliser la méthode fixée au Moyen-Âge en se limitant aux entiers inférieurs à \(5\,000\).
1. Symboles utilisés
Les symboles valides sont les suivants :
Valeur | Symbole |
---|---|
\(1\) | I |
\(5\) | V |
\(10\) | X |
\(50\) | L |
\(100\) | C |
\(500\) | D |
\(1\,000\) | M |
Ainsi, MMXII
(\(2012\)) est une écriture valide, AM
non.
2. Ordre d'écriture
La représentation d'un nombre en chiffres romains se lit de gauche à droite. Dans le cas de base, on y rencontre des symboles de valeurs décroissantes.
Ainsi, XVI
est l'écriture valide du nombre \(16\), VIX
non.
La règle n°5 autorise toutefois certaines entorses à cette règle.
3. Notation additive
Dans le cas de base, les valeurs des symboles sont additionnées.
Ainsi LXXIII
représente \(50+10+10+1+1+1=73\).
4. Répétitions
Le symbole M
peut être répété autant de fois que nécessaire.
Tous les autres symboles ne peuvent pas être répétés plus de 3 fois (inclus).
Ainsi, MMMMVI
(\(4\,006\)) est une écriture valide, MMMMIIIIII
non.
Cette règle a été fixée au Moyen-Âge. L'écriture
MMMMIIIIII
était valide dans l'Antiquité !
5. Notation soustractive
Afin d'éviter les répétitions interdites, on s'autorise des entorses à la règle n°2.
On peut ainsi faire précéder les symboles :
X
etV
par un unique symboleI
,C
etL
par un unique symboleX
,M
etD
par un unique symboleC
.
Dans ces cas, la valeur qui précède est soustraite à la valeur précédée.
On a donc les correspondances suivantes :
Symboles | Valeurs |
---|---|
IV |
\(4\) |
IX |
\(9\) |
XL |
\(40\) |
... | ... |
Ainsi, MCMXLI
représente \(1\,000+900+40+1=1\,941\).
La fonction pour convertir
Écrire la fonction romain
qui prend en argument un nombre entier strictement positif valeur
et renvoie son écriture en chiffres romains.
Exemples
>>> romain(4)
'IV'
>>> romain(5)
'V'
>>> romain(6)
'VI'
>>> romain(5042)
'MMMMMXLII'
Un algorithme glouton
On procède de façon analogue au « Rendu de monnaie » : au lieu de rendre en priorité les « pièces » les plus grandes, ici, on écrit en priorité les « valeurs » les plus grandes.
Créer une chaîne de caractère vide et l'affecter à la variable résultat
Pour chaque nombre utilisable :
Tant que la valeur à convertir est supérieure ou égale à ce nombre :
Concaténer l'écriture romaine de ce nombre au résultat
Soustraire ce nombre à la valeur à convertir
Remarque
Vous avez peut-être utilisé un dictionnaire VALEURS= {1000: "M, 900:"CM", 500: "D", 400:"CD" ...}
🤔 Cela a fonctionné ...
Attention, depuis plusieurs versions, dans python les dictionnaires sont parcourus dans l'ordre dans lequel ils sont "écrits" ou saisis. Si vous travaillez sur une version plus ancienne de python, ce n'est pas le cas. Un dictionnaire n'est pas ordonné : l'ordre dans lequel sont écrits les couples (clé, valeur) n'a aucune importance. Vous ne pourrez pas utiliser cette méthode avec d'autres langages. Il faut utiliser pour un algorithme glouton une structure ordonnée.
Méthode arithmétique
On peut aussi procéder en utilisant des divisions euclidiennes afin de ne pas écrire de boucle while
. On rappelle en effet que :
1748 // 1000
est évalué à1
, c'est le quotient de la division euclidienne de \(1\,748\) par \(1\,000\) ;1748 % 1000
est évalué à748
, c'est le reste de cette même division.
def romain(valeur):
resultat = ""
for entier, symbole in VALEURS:
quotient = valeur // entier
valeur = valeur % entier
resultat += symbole * quotient # concaténation de caractères
return resultat
Et après ?
Les entiers supérieurs ou égaux à \(5\,000\) s'écrivent en utilisant une barre horizontale indiquant qu'il faut multiplier le facteur concerné par \(1\,000\).
Par exemple \(\overline{\text{VI}}\text{CCCVIII}\) représente \(6\,308\) car le \(\overline{\text{VI}}\) est multiplié par \(1\,000\).
Astuce (1)
Penser à un algorithme glouton.
Astuce (2)
On pourra utiliser la liste VALEURS = [..., (4, "IV"), ...]
après l'avoir complétée.
Astuce (3)
On pourra utiliser la liste VALEURS = [(1000, "M"), (900, "CM"), (500, "D"), ...]
après l'avoir complétée.