forked from menault/2026_TD3_DEV51_Qualite_Algo
Réduire la complexité de F9 en séparant débits et crédits
This commit is contained in:
@@ -348,3 +348,19 @@ disparaissent. F8 passe de **M = 4 à M = 5** : l'amélioration temporelle
|
|||||||
n'implique pas une baisse de M. Les tests comparent les résultats à la
|
n'implique pas une baisse de M. Les tests comparent les résultats à la
|
||||||
récursion initiale pour les sommes de -2 à 40 et de 0 à 8 types de pièces,
|
récursion initiale pour les sommes de -2 à 40 et de 0 à 8 types de pièces,
|
||||||
y compris la somme nulle et l'absence de pièces.
|
y compris la somme nulle et l'absence de pièces.
|
||||||
|
|
||||||
|
### F9 — Séparer les règles des débits et des crédits
|
||||||
|
|
||||||
|
`categorie` répartit les transactions entre débit, montant nul et crédit.
|
||||||
|
Les règles propres aux débits et aux crédits sont regroupées dans deux
|
||||||
|
fonctions auxiliaires, avec des retours directs. Le test du week-end
|
||||||
|
`jour % 7 >= 5` remplace les deux comparaisons reliées par `||`.
|
||||||
|
|
||||||
|
Le temps reste **`O(1)`** et la complexité cyclomatique de F9 passe de
|
||||||
|
**14 à 3**, sous l'objectif de 10. Les auxiliaires `categorie_debit`
|
||||||
|
et `categorie_credit` ont respectivement **M = 5** et **M = 7** : les
|
||||||
|
décisions ne sont pas simplement déplacées vers une autre fonction
|
||||||
|
dépassant l'objectif. Les tests confrontent les 20 montants situés aux
|
||||||
|
seuils et à leurs voisins, y compris `LONG_MIN` et `LONG_MAX`, à la fonction
|
||||||
|
initiale, pour 20 clients et 210 jours (cycle commun des modulos 7 et 30),
|
||||||
|
soit **84 000 classifications**.
|
||||||
|
|||||||
@@ -259,37 +259,44 @@ long nb_facons_rendre(int somme, int nb_pieces)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* F9 : catégorie d'une transaction (pour les statistiques) */
|
/* F9 : catégorie d'une transaction (pour les statistiques) */
|
||||||
|
static int categorie_debit(const Transaction *t)
|
||||||
|
{
|
||||||
|
if (t->montant < -20000) {
|
||||||
|
if (t->jour % 7 >= 5)
|
||||||
|
return 1;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (t->montant < -5000)
|
||||||
|
return 3;
|
||||||
|
if (t->client % 10 == 0)
|
||||||
|
return 4;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int categorie_credit(const Transaction *t)
|
||||||
|
{
|
||||||
|
if (t->montant > 30000) {
|
||||||
|
if (t->client % 10 == 0 && t->jour % 7 < 5)
|
||||||
|
return 6;
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
if (t->montant > 10000)
|
||||||
|
return 8;
|
||||||
|
if (t->montant > 1000) {
|
||||||
|
if (t->jour % 30 == 0)
|
||||||
|
return 9;
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
|
||||||
int categorie(const Transaction *t)
|
int categorie(const Transaction *t)
|
||||||
{
|
{
|
||||||
if (t->montant < 0) {
|
if (t->montant < 0)
|
||||||
if (t->montant < -20000) {
|
return categorie_debit(t);
|
||||||
if (t->jour % 7 == 5 || t->jour % 7 == 6)
|
if (t->montant == 0)
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 2;
|
|
||||||
} else if (t->montant < -5000) {
|
|
||||||
return 3;
|
|
||||||
} else {
|
|
||||||
if (t->client % 10 == 0)
|
|
||||||
return 4;
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
} else if (t->montant == 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
return categorie_credit(t);
|
||||||
if (t->montant > 30000) {
|
|
||||||
if (t->client % 10 == 0 && t->jour % 7 < 5)
|
|
||||||
return 6;
|
|
||||||
return 7;
|
|
||||||
} else if (t->montant > 10000) {
|
|
||||||
return 8;
|
|
||||||
} else if (t->montant > 1000) {
|
|
||||||
if (t->jour % 30 == 0)
|
|
||||||
return 9;
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
return 11;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* F10 : ajoute une ligne à la fin du rapport */
|
/* F10 : ajoute une ligne à la fin du rapport */
|
||||||
|
|||||||
@@ -224,6 +224,55 @@ static void tester_monnaie(void)
|
|||||||
assert(nb_facons_rendre(s, k) == monnaie_reference(s, k));
|
assert(nb_facons_rendre(s, k) == monnaie_reference(s, k));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int categorie_reference(const Transaction *t)
|
||||||
|
{
|
||||||
|
if (t->montant < 0) {
|
||||||
|
if (t->montant < -20000) {
|
||||||
|
if (t->jour % 7 == 5 || t->jour % 7 == 6)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 2;
|
||||||
|
} else if (t->montant < -5000) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
if (t->client % 10 == 0)
|
||||||
|
return 4;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
} else if (t->montant == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (t->montant > 30000) {
|
||||||
|
if (t->client % 10 == 0 && t->jour % 7 < 5)
|
||||||
|
return 6;
|
||||||
|
return 7;
|
||||||
|
} else if (t->montant > 10000) {
|
||||||
|
return 8;
|
||||||
|
} else if (t->montant > 1000) {
|
||||||
|
if (t->jour % 30 == 0)
|
||||||
|
return 9;
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tester_categories(void)
|
||||||
|
{
|
||||||
|
const long montants[] = {
|
||||||
|
LONG_MIN, -20001, -20000, -19999, -5001, -5000, -4999, -1,
|
||||||
|
0, 1, 999, 1000, 1001, 9999, 10000, 10001, 29999, 30000, 30001, LONG_MAX
|
||||||
|
};
|
||||||
|
for (size_t m = 0; m < sizeof(montants) / sizeof(*montants); m++) {
|
||||||
|
for (int c = 0; c < 20; c++) {
|
||||||
|
for (int j = 0; j < 210; j++) {
|
||||||
|
Transaction t = {0, c, j, montants[m]};
|
||||||
|
assert(categorie(&t) == categorie_reference(&t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
tester_tri();
|
tester_tri();
|
||||||
@@ -234,6 +283,7 @@ int main(void)
|
|||||||
tester_recherches();
|
tester_recherches();
|
||||||
tester_paires();
|
tester_paires();
|
||||||
tester_monnaie();
|
tester_monnaie();
|
||||||
|
tester_categories();
|
||||||
puts("Tests banque : OK");
|
puts("Tests banque : OK");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user