IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

[C++0x] Convertisseur de chiffre arabe en romain


Sujet :

Langage C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 58
    Points : 52
    Points
    52
    Par défaut [C++0x] Convertisseur de chiffre arabe en romain
    Bonjour à tous !

    Suite à une discussion sur l'irc python, quelqu'un a lancé le défi de faire un code en C++0x qui soit plus court en ligne et en nombre de caractère que le code python correspondant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    numlist = [(1000,'M'), (900,'CM'), (500,'D'), (400,'CD'), (100,'C'), (90,'XC'), (50,'L'),(40,'XL'), (10,'X'), (9,'IX'), (5,'V'), (4,'IV'), (1,'I')]
     
    def arabe(n):
        res = ""
        for k, v in numlist:
            while n >= k:
                n -= k
                res += v
        return res
    Selon lui il existe une version en C++0x qui soit plus courtes que ce code. Cependant, moi-même je n'arrive pas à faire mieux que ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>
    #include <vector>
    #include <utility>
     
    using namespace std;
     
    const vector< pair<int, string> > numlist = {pair<int, string>(1000,"M"), pair<int, string>(900,"CM"), pair<int, string>(500,"D"), pair<int, string>(400,"CD"), pair<int, string>(100,"C"), pair<int, string>(90,"XC"), pair<int, string>(50,"L"), pair<int, string>(40,"XL"), pair<int, string>(10,"X"), pair<int, string>(9,"IX"), pair<int, string>(5,"V"), pair<int, string>(4,"IV"), pair<int, string>(1,"I")};
     
    string arabToRoman(int n)
    {
        string result;
        for(size_t i(0); i < numlist.size(); ++i)
        {
            while(n >= numlist[i].first)
            {
                n -= numlist[i].first;
                result += numlist[i].second;
            }
        }
     
        return result;
    }
     
    int main()
    {
        for(int i(1); i < 4000; ++i)
            cout << arabToRoman(i) << '\n';
        return 0;
    }
    Quelqu'un arriverait à faire un code plus concis en C++0x? J'ai pas trouvé mieux mais il semblerait qu'il existe plus court.

    Merci de votre aide !

  2. #2
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const vector< pair<int, string> > numlist = { {1000,"M"}, {900,"CM"}, {500,"D"}, {400,"CD"}, {100,"C"}, {90,"XC"}, {50,"L"}, {40,"XL"}, {10,"X"}, {9,"IX"}, {5,"V"}, {4,"IV"}, {1,"I"}};
    string arabToRoman(int n)
    {
        string result;
        for( auto i : numlist )
        {
            while(n >= i.first)
            {
                n -= i.first;
                result += i.second;
            }
        }
        return result;
    }
    C'est déjà plus court mais pas aussi court (et non testé). J'ai utilisé les features qui existent en C++0x et dont visiblement tu n'avais pas connaissance.

    edit> OUPS j'ai fait une grosse erreur, je corrige ça de suite

    edit2> Hop fixé et encore plus court.

  3. #3
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Je n'ai pas de compilateur c++0x sous la main mais est-ce que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const map< int, string > numlist = { {1000,"M"}, {900,"CM"}, {500,"D"}, {400,"CD"}, {100,"C"}, {90,"XC"}, {50,"L"}, {40,"XL"}, {10,"X"}, {9,"IX"}, {5,"V"}, {4,"IV"}, {1,"I"}};
    Marcherait dans ce cas là? Ca serait plus réduit et marcherait pour tous les cas.

    Au passage, on peut aussi chipoter sur l'utilisation des accolades :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    string arabToRoman(int n)
    {
        string result;
        for( auto i : numlist )
            while(n >= i.first)
            {
                n -= i.first;
                result += i.second;
            }
        return result;
    }
    En tout cas je trouve que c'est interessant comme exercice pour se mettre a C++0x : prendre un bout de code et l'ecrire de manière plus simple.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 58
    Points : 52
    Points
    52
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const map< int, string > numlist = { {1000,"M"}, {900,"CM"}, {500,"D"}, {400,"CD"}, {100,"C"}, {90,"XC"}, {50,"L"}, {40,"XL"}, {10,"X"}, {9,"IX"}, {5,"V"}, {4,"IV"}, {1,"I"}};
    ça marche très bien ! Merci de l'astuce !

    Et le reste du code est tout à fait correct à mes yeux. Je n'ai pas pu tester le code car GCC ne supporte pas encore les "Range-based for". Peut-être qu'un autre compilateur gère cela. Mais je suis sûr qu'il fonctionne. Beau boulot !

  5. #5
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Tu peux eventuellement remplacer le for par une des fonctions de <algorithm> et utiliser une lambda qui incluerait le code du while ?

    Sinon de rien
    Vivement qu'on ait des compilers avec la plupart des features, qu'on réduise le code qu'on ecrit.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 58
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Tu peux eventuellement remplacer le for par une des fonctions de <algorithm> et utiliser une lambda qui incluerait le code du while ?
    Oui mais bon le résultat est assez moche au final (je trouve) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>
    #include <vector>
    #include <utility>
    #include <algorithm>
     
    using namespace std;
     
    const vector< pair<int, string> > numlist = {{1000,"M"}, {900,"CM"}, {500,"D"}, {400,"CD"}, {100,"C"}, {90,"XC"}, {50,"L"}, {40,"XL"}, {10,"X"}, {9,"IX"}, {5,"V"}, {4,"IV"}, {1,"I"}};
     
    string arabToRoman(int n)
    {
        string result;
        for_each(numlist.begin(), numlist.end(), [&](pair<int, string> i)
        {
            while(n >= i.first)
            {
                n -= i.first;
                result += i.second;
            }
        });
        return result;
    }
     
    int main()
    {
        for(int i(1); i < 4000; ++i)
            cout << arabToRoman(i) << endl;
        return 0;
    }
    La version basée sur le nouveau for est bien plus élégante à mes yeux en tout cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/10/2012, 14h23
  2. Chiffres romains en chiffres arabes
    Par Alain Defrance dans le forum Contribuez
    Réponses: 0
    Dernier message: 09/02/2011, 22h27
  3. Chiffres arabes en chiffres romains
    Par khayyam90 dans le forum Contribuez
    Réponses: 0
    Dernier message: 09/02/2011, 22h26
  4. [Dvp.NET|Intégré] [VB.Net/C#] Convertir un chiffre arabe en chiffre romain
    Par Philippe Vialatte dans le forum Contribuez
    Réponses: 10
    Dernier message: 10/11/2008, 23h51
  5. Inverseur chiffres arabes <-> romains
    Par arraroussama dans le forum Assembleur
    Réponses: 1
    Dernier message: 26/02/2006, 21h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo