Partage

[Exercices] Venez vous entraîner !

Ce mois: Parseur de fonctions mathématiques

23 août 2008 à 22:33:20

Bonjour, j'ai encore un question à propos du dernier exercice. Peut on afficher le résultat comme à la télé? C'est à dire : au lieu d'afficher comme dans l'énoncé,
(2*3)*(10+1)*10

on affiche à la place :
2 * 3 = 6
10 + 1 = 11
6 * 11 = 66
66 * 10 = 660


Merci d'avance pour votre réponse
24 août 2008 à 10:58:27

@Zebra : Oui bien sûr. Selon moi c'est plus dificile à faire, mais c'est plus facile à suivre. Bonne idée !

@leopard : Je suis pas contre l'idée, mais la difficulté d'un exercice peut être assez subjective et dépend aussi de ce qu'on utilise comme outil. Le dernier exercice "version MatteX" est difficile pour un zéro parce qu'il utilise énormément la SL qui n'est pas présentée sur ce site.
Une version n'utilisant que des outils "simples" serait sûrement jugée beaucoup plus simples.
Mais il est vrai que cet exercice est plus difficile que celui sur les statistiques.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
24 août 2008 à 11:12:04

J'attends aussi avec impatience la solution des statistiques :) (qui est le seul exercice que j'ai réussi :D ).
24 août 2008 à 11:14:39

Au vu des questions et du succès du BF, j'avais complètement oublié l'exo sur les statistiques. Mais je pense pulier une correction d'ici demain.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
24 août 2008 à 21:51:15

Sinon on pourrait avoir une solution de BF simplifiée stp ?
25 août 2008 à 8:47:19

Oui, oui, ça vient. Je suis pas à plein temps sur le Sdz non-plus hein...
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
25 août 2008 à 11:47:39

T'en es où dans tuto des notions avancées ?
25 août 2008 à 13:41:37

Je pense reprendre la rédaction en septembre quand j'aurai du temps libre.

EDIT: J'ai ajouté une solution plus simple pour le code BF.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
26 août 2008 à 0:44:35


Citation : Nanoc


Niveau 2


Quand on propose un tirage, on est pas assuré qu'on puisse bien atteindre le résultat souhaité, ce qui n'est pas pratique pour les gens qui jouent.
Le but est ici d'écrire un programme qui donne un tirage (résultat + les 6 nombres) qui assure qu'on puisse atteindre le résultat.



Je ne vois pas l'intérêt de cette question : par exemple, on n'a qu'à donner pour valeur au tirage la somme des six nombres.

Citation : Nanoc


Mais j'avoue que je n'ai pas pensé à faire ça, ce qui complique pas mal l'exerice d'où le niveau 2.


Je ne vois pas ce qu'il y a de compliqué.

Citation : Nanoc


Le but n'est pas ici de reproduire le jeu mais plutôt de reproduire le programme informatique qui aide le présentateur à vérifier que la solution est correcte.



Pas clair du tout. Vérifier qu'une solution convient ou pas est trivial, il suffit de vérifier les calculs. Je ne vois pas où tu veux en venir et je ne pense pas être le seul.

26 août 2008 à 14:48:28

1 et 2) Plus je vais en avant, plus je me dis que je me suis complètement planté en réflechissant sur le point 2 qui est finalement très simple. Je vais reformuler tout ça.

3) En clair: Le but n'est pas de présenter les 6 nombres et le résultat à une personne, attendre que celle-ci donne la réponse et vérifier si elle est correcte.
Le but est de réaliser un programme qui cherche la solution du problème. Qui joue à la place de l'humain au jeu.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
26 août 2008 à 15:54:44

Citation : Nanoc


Le but est de réaliser un programme qui cherche la solution du problème. Qui joue à la place de l'humain au jeu.


Oui, ça je pense que c'était clair, le compte est bon est un classique de la programmation.

D'ailleurs, il doit être aussi possible de faire un Mot le plus long comme dans le jeu de la télé.

Et au passage, une bonne idée de programmation est de faire un solveur de Boggle, comme celui-ci : massiveboggle (attendre la fin du jeu pour voir le solveur opérer).
26 août 2008 à 16:03:02

Le mot le plus long viendra :)
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
Anonyme
27 août 2008 à 14:23:25

OMGWTFBBQ !
Pas fou non ?
27 août 2008 à 21:31:32

Citation : Nanoc

Le mot le plus long viendra :)




Le problème c'est que la qualité du programme découle de la liste de mot qui va avec le logiciel... plus la liste est complète plus le programme est 'fort'. Donc faudrait trouver la même pour tout le monde!
27 août 2008 à 21:48:38

Pourquoi pas recopier le dictionnaire :D ?
Anonyme
27 août 2008 à 23:24:00

Citation : gymnopaul

Pourquoi pas recopier le dictionnaire :D ?

Pourquoi pas prendre la liste des mot de OpenOffice ou autre? ;)
28 août 2008 à 8:31:01

Evidemment que ca dépend du dictionnaire. Mais pour un dictionnaire donné, on peut toujours comparer les programmes à la vitesse de recherche.
Parce que chercher une séquence aléatoire dans un fichier de 100'000 entrées c'est pas forcément évident à faire de manière efficace.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
28 août 2008 à 10:35:36

Citation : Hiura

Pourquoi pas prendre la liste des mot de OpenOffice ou autre? ;)


Ah oui c'est pas bête :D ...

Je parlais au second degré :-° ...

Citation : Nanoc

Evidemment que ca dépend du dictionnaire. Mais pour un dictionnaire donné, on peut toujours comparer les programmes à la vitesse de recherche.
Parce que chercher une séquence aléatoire dans un fichier de 100'000 entrées c'est pas forcément évident à faire de manière efficace.


Alors oui c'est un très bon exercice :) .
Anonyme
28 août 2008 à 16:13:54

Citation : gymnopaul

Je parlais au second degré :-° ...

T'inquiète, j'avais compris. ;)
28 août 2008 à 17:58:28

Citation : Lecureuil

Ou un interpréteur Malbolge ? :-°
:lol:



Vas y fais toi plaisir :-° tu nous fais signe quand tu est au bord du suicide :):p

Le mot le plus long, ca ma l'air assez interressant cela vivement cette exercice :D
30 août 2008 à 18:49:12

bonjour

N'ayant plus d'idée de logiciel pour Qt, je me suis dit qu'un peu d'entrainement serais le bien venus :lol: .
J'ai donc commencé le dernier exercice ("Les chiffres..."), et j'ai reussi a faire choisir aléatoirement le nombre a atteindre, mais pour les 6 de la liste je n'y arrive pas ! voici mon code :


Main.cpp
#include <iostream>
#include "chiffre.h"

using namespace std;

int main()
{
    Chiffre chiffre;

    chiffre.randomNbToDo();
    chiffre.randomNbCh();
    getchar();
    return 0;
}


Chiffre.h

#ifndef DEF_CHIFFRE
#define DEF_CHIFFRE

class Chiffre
{
    public:
        Chiffre();
        void randomNbToDo();
        void randomNbCh();

    private:
        int nbToDo;
        int nbChoose[5];
};

#endif


Chiffre.cpp

#include <iostream>
#include <time.h>

#include "chiffre.h"

using namespace std;

Chiffre::Chiffre()
{
}

void Chiffre::randomNbToDo()
{
    srand(time(NULL));

    int nbMax = 1000;
    nbToDo = (rand() % (nbMax)) + 1;
    cout << "Nombre a atteindre : " << nbToDo << endl;
}

void Chiffre::randomNbCh()
{
    int listePossible[] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100};
    srand(time(NULL));

    for(int i = 0; i < 5; i++)
    {
        nbChoose[i] = (rand() % (listePossible)) + 1;
        cout << "Nombre choisi : " << nbChoose[i] << endl;
    }
}



voici les erreurs que me donne le comilateur :

-------------- Build: Release in Chiffres ---------------

Compiling: chiffre.cpp
C:\Users\Vincent\Desktop\Programmation\Exercices CMD\Chiffre et lettres\Chiffres\chiffre.cpp: In member function `void Chiffre::randomNbCh()':
C:\Users\Vincent\Desktop\Programmation\Exercices CMD\Chiffre et lettres\Chiffres\chiffre.cpp:28: error: invalid operands of types `int' and `int[14]' to binary `operator%'
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 0 warnings


merci de votre aide :)
30 août 2008 à 18:54:50

la prochaine fois tu ouvre un sujet approrié.
pour ton probleme: il vient du fait que tu fait un int mopdulo pointeur, donc forcement le compilo n'est pas content.
30 août 2008 à 19:57:42

nbChoose[i] = (rand() % (listePossible)) + 1;
Devient
nbChoose[i] = listePossible[(rand() % (sizeof(listePossible) / sizeof(int)) + 1)];

Tu peux remplacer les deux sizeof par la taille du tableau listePossible
30 août 2008 à 20:16:16

En C++, on utilise rarement sizeof. Ici, on en a clairement pas besoin.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
30 août 2008 à 21:12:18

Oui je suis d'accord, seulement j'ai écrit le bout de code à l'aveugle. :p Je voulais pas compter le nombre des élèment.
Pourquoi "rarement" ?
30 août 2008 à 21:40:17

Parce que les allocations dynamiques n'en ont pas besoin.
30 août 2008 à 22:34:01

Parce qu'à moins de devoir manipuler finement la mémoire en on a pas besoin. Pour continuer la discussion, merci de créer un nouveau thread.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
30 août 2008 à 22:38:16

ok merci :) mais sa ne doit pas etre tres bon car voici le resultat :

Nombre a atteindre : 79
Nombre choisi : 10
Nombre choisi : 8
Nombre choisi : 2293484  // ??
Nombre choisi : 8
Nombre choisi : 100



que voudrait il utiliser alors a la place des sizeof ?? ou est ce mon code qui est mal codé ??

merce
ps : la prochaine fois je créerais un topic ;)
30 août 2008 à 23:04:15

Solution du mois de juillet 2008

(Enfin !)

Avec un peu de retard, je vous présente la solution de l'exercice du mois de juillet sur les statistiques des fichiers. J'ai reçu une dizaine de réponses et j'ai finalement retenu celle de Leilo. J'ai d'ailleurs reçu une explication complète du programme que je vous donne tel-quel ici.
J'ai retenu ce code parce qu'il utilise les exceptions, les manipulateurs de flux et que la lecture du fichier se fait de manière correcte. C'est un excellent exemple, il manque juste un peu de commentaires à mon goût.

Solution complète



Cher Nanoc, ^^

Voici mon code pour l'exercice sur les "Statistiques sur des fichiers",
La grande difficulté de cette exercice était l'algo de calcul des mots et des paragraphes. En effet pour ma part mon algo se contente de compter les blancs entre chaque mots et d'en déduire le nombre de mots, par exemple si dans une phrases il y a 3 blancs

mot1 blanc mot2 blanc mot3 blanc mot4

Ici trois blanc donc quatre mots. ;)

Néanmoins il faut ignorer tout blanc se situant en début ou fin de ligne, là se situé une première dificulté.
En outre il ne suffisait pas de compter le nombre d'espaces ou de tabulations pour avoir le nombre de blancs,
un blanc peut aussi être une suite d'espaces ou de tabulations, là se situe la seconde dificulté,

Enfin il fallait reitérer le même procéder pour compter les paragraphes mais cette fois ci avec les '\n'

paragraphe 1
'\n'
paragraphe 2
'\n'
paragraphe 3

Deux ' \n ' donc trois paragraphes :p
et on se confronte encore au même difficultés de '\n' situés au debut ou/et à la fin :(
De même 2 paragraphes peuvent être séparés par plusieurs '\n' :o

PS: j'ai voulu utiliser un maximum la STL et ai donc pensé utiliser le predicat isspace() de <cctype> mais pour certain caractères tel que ' à ' la fonction renvoyé true alors qu'elle ne devait pas , j'ai donc implementé mon propre prédicat IsSpace() :(

Remarque de Nanoc: Oui std::isspace() est une excellente idée, mais il ne marche qu'avec les caractères ASCII standards c'est-à-dire sans les accents.

PS2: j'ai volontairement tout placé dans un fichier pour me simplifier la vie :D

J'espère ne pas trop t'avoir dégouté avec mes explications mais je tenai à t'en faire part dans le cas ou te ne comprendrai pas mon algo voila ^^ Bonne lecture


//fichier main.cpp

#include <iostream>
#include <fstream>
#include <iomanip>
//#include <cctype>   // isspace()

using namespace std;

int  GereArguments(char argc ,char *argv[])           ;
bool IsSpace      (char C )                           ;
void Calcul       (const string & , ostream & = cout );
void AfficherAide (void);


int main(char argc,char*argv[])
{
    bool retour;
    try
    {
        retour = GereArguments(argc,argv);
    }
    catch(const string & e)
    {
        cerr << e;
        retour = EXIT_FAILURE;
    }
    return retour;
}

int  GereArguments(char argc ,char *argv[])
{
    if (argc > 4 || argc < 2)
    {
        AfficherAide();
        return EXIT_FAILURE;
    }
    string NomFichier = argv[1];

    if (argc > 2 )
    {
        string Argument2  = argv[2];
        if (Argument2 != "-d")
        {
            AfficherAide();
            return EXIT_FAILURE;
        }
        if (argc == 3) throw string("Veuillez preciser le nom du fichier de sortie\n");

        string FichierDeSortie = argv[3];

        ofstream FluxDeSortie(FichierDeSortie.c_str(),ios::out | ios::trunc);
        if (FluxDeSortie)
        {
            Calcul(NomFichier, FluxDeSortie);            
        }
        else
            throw string("Erreur dans l'ouverture du fichier destination : " + FichierDeSortie );
    }
    else
    {
        Calcul(NomFichier);
    }
    return EXIT_SUCCESS;
}

void Calcul (const string & FichierAnalyse, ostream & FluxDeSortie )
{
    ifstream FluxAnalyse (FichierAnalyse.c_str(), ios::in);

    if(FluxAnalyse)
    {
        cout << "Calcul en cour..." << endl   ;
        string Buffer                         ;

        unsigned int NbCaracEnTout     = 0    ;
        unsigned int NbCaracSansEspace = 0    ;
        unsigned int NbMots            = 0    ;
        unsigned int NbParagraphe      = 0    ;
        bool         PrecIsSpace       = true ;
        bool         PrecIsCR          = true ;
        bool         BufferEstVide            ;

        while ( getline(FluxAnalyse,Buffer) )
        {
            BufferEstVide = (Buffer == "");


            if ( BufferEstVide && !PrecIsCR )++NbParagraphe;

            PrecIsCR =  BufferEstVide;

            PrecIsSpace = true ;
            for (unsigned i = 0 ; i < Buffer.size() ; i++)
            {
                ++NbCaracEnTout;

                if ( IsSpace(Buffer[i]) )
                {

                    if ( 0 == i || i == Buffer.size()-1 || IsSpace( Buffer[i+1] ) )continue;
                    if (!PrecIsSpace) ++NbMots;

                }
                else
                {
                    ++NbCaracSansEspace;
                    PrecIsSpace = false ;
                }
             }
             if ( !BufferEstVide )++NbMots;

        }
        if (!PrecIsCR) ++NbParagraphe;


        FluxDeSortie << "+"          << setfill('-') << setw(40) << "+"
                     << setfill('-') << setw(8)      << "+"      << endl

                     << setfill(' ') << "| "    << left  << setw(37) << "Nombre de caracteres :"
                     << setfill(' ') << " | "   << right << setw(5) << NbCaracEnTout << " |"   << endl

                     << "| "    << left  << "Nombre de caracteres (hors espace) : "
                     << " | "   << right << setw(5 ) << NbCaracSansEspace << " |"   << endl

                     << "| "    << left  << setw(37) << "Nombre de mots :  "
                     << " | "   << right << setw(5 ) << NbMots << " |"   << endl

                     << "| "    << left  << setw(37) << "Nombre de paragraphes : "
                     << " | "   << right << setw(5 ) << NbParagraphe  << " |"   << endl

                     << "+" << setfill('-') << setw(40) << "+"
                     << setfill('-') << setw(8) << "+" << endl ;
    }
    else
               throw string("Erreur pour l'ouverture du fichier : "+ FichierAnalyse);

    if (FluxDeSortie != cout) cout  << "Calcul termine avec succes \n";
}



bool IsSpace (char C)
{
    return ( C == ' '  ||
             C == '\t' ||
             C == '\n' );
}

void AfficherAide (void)
{
    cout <<"Aide: \nCeci est un programme permettant de calculer differente statistiques a partir d'un "
           "fichier texte situe dans le repertoire courant de l'executable\n\n"
           "Commande : Statisqtique Nom_du_Fichier_A_Analyser\n\n"
           "Option   : -d Nom_du_Fichier_Ou_Sauver_Les_Resultats \n\n"
           "Exemple  : - Statistique test.txt --> Permet d'analyser le fichier test.txt\n"
           "           - Statistique test.txt -d temp.txt --> Analyse le fichier test.txt et stoque les resultats dans temp.txt \n";
}



Remarques sur les codes reçus



En fait, je n'ai pas grand chose à dire ce mois, les codes étaient globalement très bien. Les points suivants sont néanmoins à soulever:

  • C'est bien d'utiliser les manipulateurs de flux, mais c'est encore mieux de les utiliser tout le temps. Par exemple pour faire le cadre avec des "+".
  • Lancer des exceptions, c'est très bien. Les rattraper et agir en conséquence (ici: afficher un messafe d'erreur) c'est encore mieux.


Il ne sert à rien d'envoyer votre code si il ne fonctionne pas ou pire, si il ne compile pas.


Merci à tous ceux qui ont participé. Et bonne chance avec l'exercice suivant !
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.