From 9ee6245859a22f29c83741a59754b8c67481119b Mon Sep 17 00:00:00 2001 From: Ryad MEHIRI Date: Wed, 21 Oct 2026 10:59:55 +0200 Subject: [PATCH] =?UTF-8?q?D=C3=A9couper=20main=20en=20fonctions=20courtes?= =?UTF-8?q?=20(M=20de=20main=20:=208=20=E2=86=92=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit main enchaînait 6 boucles et 1 test (M = 8), le plus grand M du fichier après F9. Les calculs passent dans analyser, qui remplit une structure Resultats ; le rapport est construit par construire_rapport à l'aide de ajouter_formatee (vsnprintf puis ajouter_ligne), qui garde tout le format du rapport au même endroit ; ecrire_fichier et afficher terminent. Le plus grand M du fichier est maintenant 5. Rapport identique octet par octet. Empreinte inchangée (ff68d260a7a58441). Co-Authored-By: Claude Opus 5.5 --- banque.c | 181 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 76 deletions(-) diff --git a/banque.c b/banque.c index 68b57e4..3bd5305 100644 --- a/banque.c +++ b/banque.c @@ -16,6 +16,7 @@ * Profiling : gcc -O0 -g -pg banque.c -o banque && ./banque && gprof ./banque gmon.out */ +#include #include #include @@ -278,85 +279,113 @@ unsigned long empreinte(const char *s) return h; } +/* Tous les indicateurs calculés, pour le rapport et l'affichage */ +typedef struct { + long somme_requetes; + int nb_clients; + long totaux_clients[NB_CLIENTS]; + long totaux_jours[NB_JOURS]; + int debut, fin; + long meilleure; + int categories[12]; + long nb_paires; + long nb_facons; +} Resultats; + +/* Recherches par id, dans l'ordre d'origine des transactions (F6) */ +long sommer_requetes(const Transaction *t, int n) +{ + int *position = indexer_par_id(t, n); + long somme = 0; + unsigned long etat = 12345; + for (int q = 0; q < NB_REQUETES; q++) { + etat = etat * 1103515245UL + 12345UL; + /* tout id de 0 à n-1 existe : le résultat n'est jamais NULL */ + somme += rechercher_par_id(t, position, (int)((etat >> 8) % n))->montant; + } + free(position); + return somme; +} + +void compter_categories(const Transaction *t, int n, int *categories) +{ + for (int i = 0; i < n; i++) + categories[categorie(&t[i])]++; +} + +/* Calcule tous les indicateurs. À la fin, t est trié par montant (F1). */ +void analyser(Transaction *t, int n, Resultats *r) +{ + r->somme_requetes = sommer_requetes(t, n); /* avant le tri : ordre d'origine */ + r->nb_clients = nb_clients_distincts(t, n); + total_par_client(t, n, r->totaux_clients); + total_par_jour(t, n, r->totaux_jours); + r->meilleure = meilleure_periode(r->totaux_jours, NB_JOURS, &r->debut, &r->fin); + compter_categories(t, n, r->categories); + trier_par_montant(t, n); + r->nb_paires = nb_paires_opposees(t, n); /* a besoin du tri */ + r->nb_facons = nb_facons_rendre(MONTANT_MONNAIE, NB_PIECES); +} + +/* Formate une ligne comme printf et l'ajoute à la fin du rapport (F10) */ +char *ajouter_formatee(char *fin, const char *format, ...) +{ + char ligne[128]; + va_list arguments; + va_start(arguments, format); + vsnprintf(ligne, sizeof(ligne), format, arguments); + va_end(arguments); + return ajouter_ligne(fin, ligne); +} + +char *construire_rapport(const Resultats *r, const Transaction *t) +{ + char *rapport = malloc(1 << 20); + char *fin = rapport; /* position du '\0' final du rapport */ + *fin = '\0'; + fin = ajouter_formatee(fin, "clients distincts;%d\n", r->nb_clients); + fin = ajouter_formatee(fin, "somme des requetes;%ld\n", r->somme_requetes); + fin = ajouter_formatee(fin, "meilleure periode;%d;%d;%ld\n", r->debut, r->fin, r->meilleure); + fin = ajouter_formatee(fin, "paires opposees;%ld\n", r->nb_paires); + fin = ajouter_formatee(fin, "facons de rendre %d;%ld\n", MONTANT_MONNAIE, r->nb_facons); + for (int c = 0; c < 12; c++) + fin = ajouter_formatee(fin, "categorie;%d;%d\n", c, r->categories[c]); + for (int c = 0; c < NB_CLIENTS; c++) + fin = ajouter_formatee(fin, "client;%d;%ld\n", c, r->totaux_clients[c]); + for (int j = 0; j < NB_JOURS; j++) + fin = ajouter_formatee(fin, "jour;%d;%ld\n", j, r->totaux_jours[j]); + for (int i = 0; i < NB_TRANSACTIONS; i += 10) + fin = ajouter_formatee(fin, "rang;%d;%d;%ld\n", i, t[i].id, t[i].montant); + return rapport; +} + +void ecrire_fichier(const char *nom, const char *texte) +{ + FILE *f = fopen(nom, "w"); + if (f != NULL) { + fputs(texte, f); + fclose(f); + } +} + +void afficher(const Resultats *r, const char *rapport) +{ + printf("Clients distincts : %d\n", r->nb_clients); + printf("Somme des requêtes : %ld\n", r->somme_requetes); + printf("Meilleure période : jours %d à %d (%ld)\n", r->debut, r->fin, r->meilleure); + printf("Paires opposées : %ld\n", r->nb_paires); + printf("Façons de rendre %d : %ld\n", MONTANT_MONNAIE, r->nb_facons); + printf("Empreinte : %016lx\n", empreinte(rapport)); +} + int main(void) { Transaction *t = generer_transactions(NB_TRANSACTIONS); - char *rapport = malloc(1 << 20); - char ligne[128]; - rapport[0] = '\0'; - char *fin_rapport = rapport; /* position du '\0' final du rapport */ - - /* recherches par id, dans l'ordre d'origine */ - long somme_requetes = 0; - unsigned long etat = 12345; - int *position = indexer_par_id(t, NB_TRANSACTIONS); - for (int q = 0; q < NB_REQUETES; q++) { - etat = etat * 1103515245UL + 12345UL; - const Transaction *r = rechercher_par_id(t, position, (int)((etat >> 8) % NB_TRANSACTIONS)); - somme_requetes += r->montant; /* tout id de 0 à n-1 existe : r n'est jamais NULL */ - } - free(position); - - int nb_clients = nb_clients_distincts(t, NB_TRANSACTIONS); - - static long totaux_clients[NB_CLIENTS]; - total_par_client(t, NB_TRANSACTIONS, totaux_clients); - - static long totaux_jours[NB_JOURS]; - total_par_jour(t, NB_TRANSACTIONS, totaux_jours); - int debut, fin; - long meilleure = meilleure_periode(totaux_jours, NB_JOURS, &debut, &fin); - - int categories[12] = {0}; - for (int i = 0; i < NB_TRANSACTIONS; i++) - categories[categorie(&t[i])]++; - - trier_par_montant(t, NB_TRANSACTIONS); - long nb_paires = nb_paires_opposees(t, NB_TRANSACTIONS); /* a besoin du tri */ - - long nb_facons = nb_facons_rendre(MONTANT_MONNAIE, NB_PIECES); - - /* rapport */ - snprintf(ligne, sizeof(ligne), "clients distincts;%d\n", nb_clients); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - snprintf(ligne, sizeof(ligne), "somme des requetes;%ld\n", somme_requetes); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - snprintf(ligne, sizeof(ligne), "meilleure periode;%d;%d;%ld\n", debut, fin, meilleure); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - snprintf(ligne, sizeof(ligne), "paires opposees;%ld\n", nb_paires); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - snprintf(ligne, sizeof(ligne), "facons de rendre %d;%ld\n", MONTANT_MONNAIE, nb_facons); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - for (int c = 0; c < 12; c++) { - snprintf(ligne, sizeof(ligne), "categorie;%d;%d\n", c, categories[c]); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - } - for (int c = 0; c < NB_CLIENTS; c++) { - snprintf(ligne, sizeof(ligne), "client;%d;%ld\n", c, totaux_clients[c]); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - } - for (int j = 0; j < NB_JOURS; j++) { - snprintf(ligne, sizeof(ligne), "jour;%d;%ld\n", j, totaux_jours[j]); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - } - for (int i = 0; i < NB_TRANSACTIONS; i += 10) { - snprintf(ligne, sizeof(ligne), "rang;%d;%d;%ld\n", i, t[i].id, t[i].montant); - fin_rapport = ajouter_ligne(fin_rapport, ligne); - } - - FILE *f = fopen("rapport.txt", "w"); - if (f != NULL) { - fputs(rapport, f); - fclose(f); - } - - printf("Clients distincts : %d\n", nb_clients); - printf("Somme des requêtes : %ld\n", somme_requetes); - printf("Meilleure période : jours %d à %d (%ld)\n", debut, fin, meilleure); - printf("Paires opposées : %ld\n", nb_paires); - printf("Façons de rendre %d : %ld\n", MONTANT_MONNAIE, nb_facons); - printf("Empreinte : %016lx\n", empreinte(rapport)); - + Resultats r = {0}; + analyser(t, NB_TRANSACTIONS, &r); + char *rapport = construire_rapport(&r, t); + ecrire_fichier("rapport.txt", rapport); + afficher(&r, rapport); free(rapport); free(t); return 0;