Exercice info en c

azertuiopinfo1 Messages postés 3 Statut Membre -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,

Je suis en train de résoudre cet exercice :


J'ai réussi presque tous les tests, mais j'ai dû oublier un détail car certains tests sont invalides.
Pouvez-vous m'aider s'il vous plaît.

#include <stdio.h>

int main(){
    int nbl, jours, act, x, y, i, p, t;
    scanf("%d", &nbl);
    scanf("%d", &jours);
    int emprunts[10001] = {0};
    int livres[10001] = {0};

    for (i = 0; i < jours; i = i + 1) {
        scanf("%d", &act);
        for (p = 0; p < act; p = p + 1) {
            scanf("%d", &x);
            scanf("%d", &y);
            if (livres[x] == 0) {
                livres[x] = y;
                emprunts[p] = 1;
            } else if (livres[x] > 0) {
                if (livres[x] <= y) {
                
                } else if (livres[x] > y) {
                    livres[x] = y;
                }
                emprunts[p] = 0;
            } else {
            
            }
        }
        
        for (t = 0; t < act; t = t + 1) {
            if (livres[t] >0) {
                livres[t] = livres[t] - 1;
            } else if (livres[t] == 0) {
            
            }
        }
        
        for (int k = 0; k < act; k = k + 1) {
            printf("%d\n", emprunts[k]);
        }
    }
}


N'hésitez pas à me donner des conseils j'ai commencé à programmer récemment.

3 réponses

  1. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102
     
    Bonjour,

    Penses à nommer correctement chacune de tes variables, sans cela le code est un casse tête à lire.

    Tu veux décompter le temps d'utilisation des livres. Tu écris
     for (t=0; t<act; t=t+1) 
    , non ce sont tous les livres qui doivent être traités, il faut à la place
     for (t=0; t<nbl; t=t+1) 
    .

    Quand un livre n'est pas disponible, le prêt est refusé et la durée demandée n'a aucun intérêt, il faut supprimer les lignes:
                                    if (livres [x]<=y)
                                        {}
                                 
                                    else if (livres [x]>y) 
                                        {
                                        livres[x]=y;
                                        }
    1
    1. azertuiopinfo1 Messages postés 3 Statut Membre
       
      j'ai bien compris,
      merci à vous.
      0
  2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    Concernant ta question
    • Peux-tu nous indiquer quels tests ne passent pas ?
    • Essaye de privilégie les copier coller quand c'est possible aux captures d'écran. C'est plus pratique pour tout le monde et plus écologique.


    Concernant les consignes
    • Attention, tu ne suis pas les conventions de nommage donnée dans ton exercice. Même si ça n'influe pas sur le comportement du programme, c'est un peu dommage.
    • Je ne comprends pas pourquoi tu alloues 10001 entrées alors que l'exercice te dit qu'il n'y en aura pas plus de 1000. La mémoire est une ressource précieuse et il ne faut pas la gaspiller :-)


    En terme de code
    • Pour incrémenter une variable tu peux utiliser
      i++
      ou
      ++i
      au lieu de
      i = i + 1
      . Il existe aussi la syntaxe
      i += 1
      (qui s'utilise plutôt quand le pas est différent de
      1
      ).
    • La valeur
      10001
      est d'autant plus étonnante qu'elle se finit par un 1. Je pense que c'est parce que tu as dû voir les chaînes de caractères pour lesquels on t'a expliqué qu'il fallait prévoir un caractère de plus pour stocker le
      '\0'
      qui par convention délimite la fin d'une chaîne de caractère. Ici tu ne manipules pas de chaînes de caractères, donc il n'y a pas de raison de prévoir "une case de plus".
    • Il est inutile de garder des bloc vides (certains de tes
      if
      et ou des
      else
      le sont). Une manière de faire peut être de modifier tes tests à l'aide d'opérateur booléans (
      &&
      pour le ET logique ;
      ||
      pour le OU logique ;
      !
      pour le NON logique). Typiquement, comme le souligne Dalfab, le test :


                    if (livres[x] <= y) {
                    
                    } else if (livres[x] > y) {
                        livres[x] = y;
                    }


    s'écrit directement :

                    if (livres[x] > y) {
                        livres[x] = y;
                    }


    De la même, vu que tes entiers sont positifs, certains tests sont inutiles. Par exemple :

                if (livres[x] == 0) {
                   // livres[x] == 0
                } else if (livres[x] > 0) {
                   // livres[x] > 0
                } else {
                   // ne peut pas arriver
                }


    se réécrit plus simplement :

                if (livres[x] > 0) {
                   // livres[x] > 0
                } else {
                   // livres[x] == 0
                }
    • Tu peux utiliser des types plus précis. Dans ton cas les entiers sont positifs, tu pourrais utiliser directement des
      unsigned int
      (en abrégé :
      unsigned
      ).
    • Vu que tu peux déclarer des variables directement dans ton
      for
      autant le faire pour tous tes index (comme tu l'as fait pour
      k
      ).
    • Pas besoin de multiplier les noms de variables (
      k
      ,
      t
      ,
      i
      , ...), autant utiliser le même nom partout (disons
      i
      ) pour désigner l'index en cours d'utilisation. Ou alors, mieux vaut utiliser un nom parlant (par exemple, comme le suggère l'énoncé,
      iLivre
      ,
      iEmprunt
      , etc...). Notons cependant que le style camel case est plutôt réservé au au Java, et parfois au C++. En C et en C++, on utiliser plutôt tendance à utiliser des noms de variables écrit comme suit
      nom_de_variable
      , e.g.
      i_livre
      . Note aussi qu'on utilise généralement des noms comme i, j, k pour des index entiers ; m, n pour des tailles entières ; x, y pour des réels ; s pour des chaînes ; ...
    • Pense à commenter ton code.
    • Tu devrais contrôler que le nombre de livres n'excède pas la taille préallouée, car si un utilisateur saisit une valeur plus grande, le programme plantera (erreur de segmentation). Il serait plus élégant de contrôler cette valeur par exemple avec
      assert()
      .
    • Le tableau
      emprunts
      n'est pas utile (et je l'aurais plutôt nommé
      est_disponible
      pour être plus parlant). Tu peux directement savoir si un livre est disponible en consultant le tableau
      livres
      (et que j'aurais plutôt appelé
      emprunts
      pour le coup !). Cela t'éviterait d'allouer deux tableaux au lieu d'un (et je rappelle que la mémoire, c'est précieux !). Je te laisse faire cette réécriture, mais voici déjà en appliquant mes premiers conseils ce à quoi pourrait ressembler ton programme :


    #include <stdio.h>
    #include <assert.h>
    #define NB_LIVRES 1000
    
    int main(){
        unsigned nbLivres, nbJours, nbClients;
        unsigned est_disponible[NB_LIVRES] = {0};
        unsigned livres[NB_LIVRES] = {0};
                       
        scanf("%d", &nbLivres);
        assert(nbLivres <= NB_LIVRES);
        scanf("%d", &nbJours);
                          
        for (unsigned iJour = 0; iJour < nbJours; iJour++) {
            scanf("%d", &nbClients);
            for (iClient = 0; iClient < nbClients; iClient++) {
                unsigned iLivre, iDuree; 
                scanf("%d", &iLivre);    
                scanf("%d", &iDuree);    
                if (livres[iLivre] > 0) {
                    if (livres[iLivre] > iDuree) {
                        livres[iLivre] = iDuree;
                    }
                    est_disponible[iClient] = 0;
                } else {
                    livres[iLivre] = iDuree;
                    est_disponible[iClient] = 1;
                }           
            }               
                            
            // Mise à jour des réservations
            for (unsigned iLivre = 0; iLivre < act; iLivre++) {
                if (livres[iLivre] > 0) {
                    livres[iLivre]--;
                }           
            }               
                            
            // Affichage des disponibilités
            for (unsigned iClient = 0; iClient < nbClients; iClient++) {
                printf("%d\n", est_disponible[iClient]);
            }               
        }                   
    } 


    Concernant le style

    Je t'invite à regarder ton message initial que j'ai réindenté afin qu'il soit plus compact et plus agréable à lire :
    • espace autour des opérateur
    • espace derrière les virgules
    • chacun à son style au niveau des accolades, mais celui-ci est communément utilisé et permet de consommer moins de hauteur.


    Bonne chance
    0
    1. azertuiopinfo1 Messages postés 3 Statut Membre
       
      j'ai lu plusieurs fois votre message , merci pour ces bons conseils .
      Je suis motivé pour progresser alors merci
      0
      1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940 > azertuiopinfo1 Messages postés 3 Statut Membre
         
        Super, c'est le but :-) Est-ce que ton problème est résolu ? Si oui, voir ce lien, et sinon, dis-nous ce qu'il reste à voir.
        0