Exercice info en c

Fermé
azertuiopinfo1 Messages postés 3 Date d'inscription vendredi 31 décembre 2021 Statut Membre Dernière intervention 4 janvier 2022 - Modifié le 4 janv. 2022 à 12:39
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 5 janv. 2022 à 12:41
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.
A voir également:

3 réponses

Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
31 déc. 2021 à 13:40
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
azertuiopinfo1 Messages postés 3 Date d'inscription vendredi 31 décembre 2021 Statut Membre Dernière intervention 4 janvier 2022
31 déc. 2021 à 15:25
j'ai bien compris,
merci à vous.
0
yg_be Messages postés 22723 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
31 déc. 2021 à 12:56
bonjour,
merci de préciser le langage quand tu utilises les balises pour poster du code: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

tu n'expliques pas le résultat que tu obtiens, ni en quoi il diffère du résultat attendu.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 4 janv. 2022 à 13:22
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
azertuiopinfo1 Messages postés 3 Date d'inscription vendredi 31 décembre 2021 Statut Membre Dernière intervention 4 janvier 2022
4 janv. 2022 à 17:13
j'ai lu plusieurs fois votre message , merci pour ces bons conseils .
Je suis motivé pour progresser alors merci
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > azertuiopinfo1 Messages postés 3 Date d'inscription vendredi 31 décembre 2021 Statut Membre Dernière intervention 4 janvier 2022
5 janv. 2022 à 12:41
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