Licence 3 Informatique – Génie Logiciel
Exercice 1 : Fizz Buzz L'énoncé rappelle que le code doit être guidé par les tests (approche Test Driven Development). Nous devons donc obligatoirement commencer par écrire la classe de test. Création des tests unitaires pour FizzBuzz Nous allons utiliser la méthode assertEquals(expected, value) pour vérifier que les retours de la méthode getResult(int val) correspondent aux spécifications.
D'après le document Licence 3 Informatique – Génie Logiciel
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Programming, Testing, Software Engineering · PDF · 2 pages · 1975
Afficher l'aperçu du document
Exercice 1 : Fizz Buzz
L'énoncé rappelle que le code doit être guidé par les tests (approche Test Driven Development). Nous devons donc obligatoirement commencer par écrire la classe de test.
Création des tests unitaires pour FizzBuzz
Nous allons utiliser la méthode assertEquals(expected, value) pour vérifier que les retours de la méthode getResult(int val) correspondent aux spécifications. Il est important de tester les différents cas de figure :
- Un multiple de 3 (ex: 3, 9)
- Un multiple de 5 (ex: 5, 10)
- Un multiple de 15 (ex: 15, 30)
- Un nombre qui n'est dans aucun de ces cas (ex: 7)
- Le cas particulier du 0 (qui est divisible par 15, 3 et 5)
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class FizzBuzzTest {
@Test
public void testGetResult() {
FizzBuzz fb = new FizzBuzz();
// Test des cas classiques (ni multiples de 3, ni de 5)
assertEquals("7", fb.getResult(7));
assertEquals("22", fb.getResult(22));
// Test de la divisibilité par 3
assertEquals("Fizz", fb.getResult(3));
assertEquals("Fizz", fb.getResult(9));
// Test de la divisibilité par 5
assertEquals("Buzz", fb.getResult(5));
assertEquals("Buzz", fb.getResult(10));
// Test de la divisibilité par 15 (3 et 5)
assertEquals("FizzBuzz", fb.getResult(15));
assertEquals("FizzBuzz", fb.getResult(30));
// Test du 0 (mathématiquement divisible par 15, 3 et 5)
assertEquals("FizzBuzz", fb.getResult(0));
}
}
Implémentation de la solution et méthode principale
L'implémentation doit tester la divisibilité par 15 avant celle par 3 ou 5. En effet, si l'on vérifiait val % 3 == 0 en premier, la valeur 15 retournerait "Fizz" et l'exécution s'arrêterait là, ce qui est incorrect.
public class FizzBuzz {
public String getResult(int val) {
// L'ordre est crucial : on teste d'abord le multiple commun
if (val % 15 == 0) {
return "FizzBuzz";
} else if (val % 3 == 0) {
return "Fizz";
} else if (val % 5 == 0) {
return "Buzz";
} else {
return String.valueOf(val);
}
}
public static void main(String[] args) {
FizzBuzz fb = new FizzBuzz();
// L'énoncé demande d'afficher les valeurs comprises entre 0 et 100
for (int i = 0; i <= 100; i++) {
System.out.println(fb.getResult(i));
}
}
}
Implémentation du mode avancé
Pour le mode avancé, nous devons inclure la vérification de la présence d'un chiffre dans le nombre. La méthode la## Exercice 1 : Fizz Buzz
L'objectif de cet exercice est de mettre en pratique le développement piloté par les tests (TDD). Nous devons donc écrire les tests pour vérifier la logique métier avant d'écrire l'algorithme lui-même.
Bien que l'énoncé ne précise pas explicitement ce qui doit être retourné lorsqu'un nombre n'est divisible ni par 3, ni par 5, le comportement standard du kata FizzBuzz est de retourner le nombre lui-même sous forme de chaîne de caractères. Nous allons tester ce cas par défaut en plus des conditions demandées.
Question 1 - Tests unitaires de la classe FizzBuzz
Nous utilisons le framework JUnit pour écrire nos tests. Nous allons vérifier les quatre cas possibles : un multiple de 3, un multiple de 5, un multiple de 15, et un nombre quelconque.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class FizzBuzzTest {
@Test
public void testGetResultMultipleDeTrois() {
FizzBuzz fb = new FizzBuzz();
// 9 est divisible par 3 seulement
assertEquals("Fizz", fb.getResult(9));
}
@Test
public void testGetResultMultipleDeCinq() {
FizzBuzz fb = new FizzBuzz();
// 10 est divisible par 5 seulement
assertEquals("Buzz", fb.getResult(10));
}
@Test
public void testGetResultMultipleDeQuinze() {
FizzBuzz fb = new FizzBuzz();
// 30 est divisible par 15 (donc par 3 et 5)
assertEquals("FizzBuzz", fb.getResult(30));
}
@Test
public void testGetResultAutreNombre() {
FizzBuzz fb = new FizzBuzz();
// 7 n'est divisible ni par 3 ni par 5
assertEquals("7", fb.getResult(7));
}
}
Question 2 - Implémentation de la classe FizzBuzz et méthode principale
L'ordre des conditions est crucial : il faut vérifier la divisibilité par 15 (ou par 3 et par 5 simultanément) en premier, sinon le programme s'arrêtera prématurément sur la condition "divisible par 3" ou "divisible par 5" et renverra un résultat partiel incorrect.
public class FizzBuzz {
public String getResult(int val) {
if (val % 15 == 0) {
return "FizzBuzz";
} else if (val % 3 == 0) {
return "Fizz";
} else if (val % 5 == 0) {
return "Buzz";
} else {
return String.valueOf(val);
}
}
public static void main(String[] args) {
FizzBuzz fb = new FizzBuzz();
// L'énoncé demande d'afficher les valeurs de 0 à 100
for (int i = 0; i <= 100; i++) {
System.out.println(fb.getResult(i));
}
}
}
Note sur le zéro : En mathématiques, 0 est un multiple de tout entier (0 = 15 × 0). Par conséquent, pour i = 0, le programme affichera FizzBuzz. C'est le comportement attendu selon les règles strictes de divisibilité.
Question 3 - Mode avancé pour les conditions étendues
Dans cette variante, nous ajoutons une condition logique "OU" pour rechercher la présence du chiffre dans l'écriture décimale du nombre. La conversion en String permet d'utiliser la méthode contains.
public class FizzBuzzAvance {
public String getResult(int val) {
String stringVal = String.valueOf(val);
boolean condition3 = (val % 3 == 0) || stringVal.contains("3");
boolean condition5 = (val % 5 == 0) || stringVal.contains("5");
if (condition3 && condition5) {
return "FizzBuzz";
} else if (condition3) {
return "Fizz";
} else if (condition5) {
return "Buzz";
} else {
return stringVal;
}
}
}
Exercice 2 : Berlin-Uhr
L'horloge berlinoise divise le temps en blocs. Pour convertir une heure (ex: 12:18:48), il faut utiliser les divisions euclidiennes et les modulos (le reste de la division). L'énoncé donne les états R (Rouge), J (Jaune) et O (Off).
Calcul pour 12:18:48 :
- Secondes (48) : 48 est pair. La lampe ronde est allumée. Disons
J(Jaune) pour allumée, etOpour éteinte. Résultat :J - Ligne 1 (Blocs de 5h) : 12 ÷ 5 = 2 blocs pleins. 2 lampes rouges sur 4. Résultat :
RROO - Ligne 2 (Blocs de 1h) : 12 reste 2 (12 % 5 = 2). 2 lampes rouges sur 4. Résultat :
RROO - Ligne 3 (Blocs de 5min) : 18 ÷ 5 = 3 blocs. 3 lampes sur 11. La 3ème lampe est rouge, les autres jaunes. Résultat :
JJROOOOOOOO - Ligne 4 (Blocs de 1min) : 18 % 5 = 3. 3 lampes jaunes sur 4. Résultat :
JJJO
Question 1 - Tests unitaires de la classe BerlinUhr
Nous allons tester individuellement les composants de l'horloge avec la valeur d'exemple pour nous assurer que chaque ligne est correctement formatée.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class BerlinUhrTest {
@Test
public void testSecondesPair() {
BerlinUhr horloge = new BerlinUhr();
assertEquals("J", horloge.calculerSecondes(48));
}
@Test
public void testSecondesImpair() {
BerlinUhr horloge = new BerlinUhr();
assertEquals("O", horloge.calculerSecondes(59));
}
@Test
public void testLigneHeuresSuperieures() {
BerlinUhr horloge = new BerlinUhr();
// 12 heures -> 12 / 5 = 2 lampes
assertEquals("RROO", horloge.calculerLigne5Heures(12));
}
@Test
public void testLigneHeuresInferieures() {
BerlinUhr horloge = new BerlinUhr();
// 12 heures -> 12 % 5 = 2 lampes
assertEquals("RROO", horloge.calculerLigne1Heure(12));
}
@Test
public void testLigneMinutesSuperieures() {
BerlinUhr horloge = new BerlinUhr();
// 18 minutes -> 18 / 5 = 3 lampes. La 3eme est un quart d'heure (Rouge)
assertEquals("JJROOOOOOOO", horloge.calculerLigne5Minutes(18));
}
@Test
public void testLigneMinutesInferieures() {
BerlinUhr horloge = new BerlinUhr();
// 18 minutes -> 18 % 5 = 3 lampes
assertEquals("JJJO", horloge.calculerLigne1Minute(18));
}
}
Question 2 - Implémentation de la classe BerlinUhr
L'implémentation repose sur des constructeurs de chaînes (StringBuilder) pour générer dynamiquement les lignes avec les caractères R, J et O.
public class BerlinUhr {
public String calculerSecondes(int secondes) {
return (secondes % 2 == 0) ? "J" : "O";
}
public String calculerLigne5Heures(int heures) {
return genererLigne(heures / 5, 4, "R");
}
public String calculerLigne1Heure(int heures) {
return genererLigne(heures % 5, 4, "R");
}
public String calculerLigne5Minutes(int minutes) {
int lampesAllumees = minutes / 5;
StringBuilder ligne = new StringBuilder();
for (int i = 1; i <= 11; i++) {
if (i <= lampesAllumees) {
// Les lampes 3, 6 et 9 représentent les quarts d'heure en rouge
if (i % 3 == 0) {
ligne.append("R");
} else {
ligne.append("J");
}
} else {
ligne.append("O");
}
}
return ligne.toString();
}
public String calculerLigne1Minute(int minutes) {
return genererLigne(minutes % 5, 4, "J");
}
private String genererLigne(int allumees, int total, String couleur) {
StringBuilder ligne = new StringBuilder();
for (int i = 0; i < allumees; i++) {
ligne.append(couleur);
}
for (int i = allumees; i < total; i++) {
ligne.append("O");
}
return ligne.toString();
}
public void afficherHorloge(String temps) {
String[] parts = temps.split(":");
int heures = Integer.parseInt(parts[0]);
int minutes = Integer.parseInt(parts[1]);
int secondes = Integer.parseInt(parts[2]);
System.out.println(calculerSecondes(secondes));
System.out.println(calculerLigne5Heures(heures));
System.out.println(calculerLigne1Heure(heures));
System.out.println(calculerLigne5Minutes(minutes));
System.out.println(calculerLigne1Minute(minutes));
}
}
Exercice 3 : Calculatrice Postfixée ou calculatrice polonaise
La notation polonaise inverse (NPI) évalue l'opérateur dès qu'il est rencontré en utilisant les opérandes qui le précèdent immédiatement.
Question 1 - Structure de données adaptée et justification
La structure de données la plus adaptée est la Pile (Stack), qui fonctionne sur le principe LIFO (Last In, First Out / Dernier entré, premier sorti).
Pourquoi ? L'algorithme d'évaluation de la notation postfixée est naturel avec une pile## Exercice 1 : Fizz Buzz
L'objectif de cet exercice est d'appliquer le développement piloté par les tests (TDD). Les instructions précisent bien qu'il faut écrire le test avant le code de la solution.
Écriture des tests unitaires (Classe FizzBuzzTest)
Pour concevoir nos tests, nous devons anticiper le comportement attendu de la méthode getResult(int val).
Les cas de test doivent couvrir les classes d'équivalence suivantes :
- Un nombre divisible par 15 (ex: 15, 30) doit retourner "FizzBuzz". Note importante : 0 est divisible par 15 (le reste de 0 ÷ 15 est 0), donc 0 devrait également retourner "FizzBuzz".
- Un nombre divisible uniquement par 3 (ex: 3, 9) doit retourner "Fizz".
- Un nombre divisible uniquement par 5 (ex: 5, 10) doit retourner "Buzz".
- Un nombre quelconque non divisible par 3 ou 5 (ex: 1, 2, 4) doit retourner le nombre sous forme de chaîne de caractères.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class FizzBuzzTest {
@Test
public void testGetResultStandard() {
FizzBuzz fb = new FizzBuzz();
// Tests des nombres standards non divisibles par 3 ou 5
assertEquals("1", fb.getResult(1));
assertEquals("2", fb.getResult(2));
assertEquals("4", fb.getResult(4));
// Tests des multiples de 3
assertEquals("Fizz", fb.getResult(3));
assertEquals("Fizz", fb.getResult(9));
// Tests des multiples de 5
assertEquals("Buzz", fb.getResult(5));
assertEquals("Buzz", fb.getResult(10));
// Tests des multiples de 15
assertEquals("FizzBuzz", fb.getResult(15));
assertEquals("FizzBuzz", fb.getResult(30));
// Test du cas particulier du zéro
assertEquals("FizzBuzz", fb.getResult(0));
}
}
Écriture de la classe FizzBuzz et de la méthode principale
L'ordre des conditions est crucial dans l'implémentation. Si l'on vérifie la divisibilité par 3 en premier, le nombre 15 renverra "Fizz" au lieu de "FizzBuzz", car 15 modulo 3 vaut 0 et le programme n'ira pas plus loin. Il faut toujours vérifier la condition la plus restrictive (modulo 15) en premier.
public class FizzBuzz {
public String getResult(int val) {
// La condition la plus stricte (divisible par 3 ET par 5, soit 15)
// doit absolument être testée en premier.
if (val % 15 == 0) {
return "FizzBuzz";
}
if (val % 3 == 0) {
return "Fizz";
}
if (val % 5 == 0) {
return "Buzz";
}
// Si aucune condition n'est remplie, on retourne le nombre en texte
return String.valueOf(val);
}
public static void main(String[] args) {
FizzBuzz fb = new FizzBuzz();
// Affichage de toutes les valeurs comprises entre 0 et 100
for (int i = 0; i <= 100; i++) {
System.out.println(fb.getResult(i));
}
}
}
Mode avancé pour les plus rapides
Les règles s'enrichissent : "divisible par" devient "divisible par OU composé de".
- Pour "Fizz" : un nombre comme 13 contient le caractère '3', il doit retourner "Fizz".
- Pour "Buzz" : un nombre comme 52 contient '5', il doit retourner "Buzz".
- Un nombre comme 53 (contient 5 et 3) ou 35 (divisible par 5 et contient 3) doit retourner "FizzBuzz".
Voici l'ajout des tests correspondants, suivi de l'implémentation :
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class FizzBuzzAvanceTest {
@Test
public void testGetResultAvance() {
FizzBuzz fb = new FizzBuzz();
// Contient un 3
assertEquals("Fizz", fb.getResultAvance(13));
assertEquals("Fizz", fb.getResultAvance(31));
// Contient un 5
assertEquals("Buzz", fb.getResultAvance(52));
// Combinaisons (contient 5 et 3, ou divisible par 5 et contient 3)
assertEquals("FizzBuzz", fb.getResultAvance(35));
assertEquals("FizzBuzz", fb.getResultAvance(53));
}
}
// Méthode à ajouter à la classe FizzBuzz existante
public String getResultAvance(int val) {
String strVal = String.valueOf(val);
boolean estFizz = (val % 3 == 0) || strVal.contains("3");
boolean estBuzz = (val % 5 == 0) || strVal.contains("5");
if (estFizz && estBuzz) {
return "FizzBuzz";
} else if (estFizz) {
return "Fizz";
} else if (estBuzz) {
return "Buzz";
} else {
return strVal;
}
}
Exercice 2 : Berlin-Uhr
Écriture des tests de la classe BerlinUhr
Pour la représentation des ampoules allumées ou éteintes, nous allons utiliser les caractères définis dans le sujet :
- 'R' : Rouge
- 'J' : Jaune
- 'O' : Off (éteint)
La lampe des secondes (tout en haut) clignote. Le sujet indique "allumée lorsque pair, éteinte sinon", nous utiliserons 'J' pour allumée car c'est la couleur historique de l'horloge de Berlin (et la lettre R serait ambiguë avec les lignes rouges). L'horloge renverra un tableau de 5 chaînes de caractères représentant les 5 éléments (Seconde, Heures x5, Heures x1, Minutes x5, Minutes x1).
Prenons l'exemple fourni : 12:18:48.
- Secondes (48) : pair, donc allumé -> "J"
- Heures (12) : 12 / 5 = 2 lampes rouges sur 4 -> "RROO"
- Heures unité (12 % 5) = 2 lampes rouges sur 4 -> "RROO"
- Minutes (18) : 18 / 5 = 3 lampes allumées. La 3ème (le quart d'heure) est rouge, les autres jaunes -> "JJROOOOOOOO"
- Minutes unité (18 % 5) = 3 lampes jaunes sur 4 -> "JJJO"
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class BerlinUhrTest {
@Test
public void testAfficherHeureBerlin() {
BerlinUhr horloge = new BerlinUhr();
String[] resultatAttendu = {
"J", // Secondes
"RROO", // Ligne 5 heures
"RROO", // Ligne 1 heure
"JJROOOOOOOO", // Ligne 5 minutes (le 3ème R marque 15 min)
"JJJO" // Ligne 1 minute
};
assertArrayEquals(resultatAttendu, horloge.convertirHeure("12:18:48"));
}
}
Écriture de la classe BerlinUhr
Pour construire les lignes, une bonne pratique est d'isoler la logique de remplissage avec O (Off) dans une méthode utilitaire.
public class BerlinUhr {
public String[] convertirHeure(String heureAConvertir) {
String[] timeParts = heureAConvertir.split(":");
int heures = Integer.parseInt(timeParts[0]);
int minutes = Integer.parseInt(timeParts[1]);
int secondes = Integer.parseInt(timeParts[2]);
String[] affichage = new String[5];
// 1. Grosse lampe des secondes
affichage[0] = (secondes % 2 == 0) ? "J" : "O";
// 2. Ligne des 5 heures (4 lampes, couleur R)
affichage[1] = construireLigne(heures / 5, 4, "R");
// 3. Ligne de 1 heure (4 lampes, couleur R)
affichage[2] = construireLigne(heures % 5, 4, "R");
// 4. Ligne des 5 minutes (11 lampes, couleurs J et R pour les quarts)
affichage[3] = construireLigneMinutes(minutes / 5);
// 5. Ligne de 1 minute (4 lampes, couleur J)
affichage[4] = construireLigne(minutes % 5, 4, "J");
return affichage;
}
// Méthode utilitaire pour construire des lignes simples
private String construireLigne(int lampesAllumees, int totalLampes, String couleur) {
StringBuilder ligne = new StringBuilder();
for (int i = 0; i < totalLampes; i++) {
if (i < lampesAllumees) {
ligne.append(couleur);
} else {
ligne.append("O");
}
}
return ligne.toString();
}
// Méthode spécifique pour la ligne des 5 minutes (gestion du quart d'heure rouge)
private String construireLigneMinutes(int lampesAllumees) {
StringBuilder ligne = new StringBuilder();
for (int i = 1; i <= 11; i++) {
if (i <= lampesAllumees) {
// Les lampes 3, 6 et 9 (multiples de 3) sont rouges
if (i % 3 == 0) {
ligne.append("R");
} else {
ligne.append("J");
}
} else {
ligne.append("O");
}
}
return ligne.toString();
}
}
Exercice 3 : Calculatrice Postfixée ou calculatrice polonaise
Choix de la structure de données
La structure de données la plus adaptée est la Pile (Stack en Java).
Pourquoi ? La notation polonaise inverse (NPI) fonctionne naturellement avec le principe LIFO (Last In, First Out / Dernier arrivé, premier sorti). Chaque fois qu'on rencontre un nombre (opérande), on l'empile. Lorsqu'on rencontre un opérateur, on dépile les deux derniers nombres, on effectue l'opération, puis on empile le résultat pour la suite du calcul.
Différenciation entre les chiffres et les nombres
Pour distinguer un chiffre simple (ex: 3) d'un nombre (ex: 34), on sépare chaque élément de la chaîne de caractères (les "tokens") par un séparateur fixe, traditionnellement l'espace. Lors de la lecture, on va découper la chaîne (fonction split(" ")). Ainsi, "3 4" générera deux éléments "3" et "4", tandis que "34" génèrera un seul élément "34".
Gestion des nombres négatifs
Les nombres négatifs sont gérés en collant le signe "-" directement devant les chiffres, sans espace (par exemple : "-3"). Lors de la lecture d'un élément, si la chaîne est exactement "-" (taille de 1), c'est l'opérateur de soustraction. S'il y a un signe "-" suivi de chiffres (ex: "-3"), l'analyseur lexical (parser) le convertira nativement en une valeur négative.
Écriture des tests
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class CalculatricePolonaiseTest {
@Test
public void testCalculsSimples() {
CalculatricePolonaise calc = new CalculatricePolonaise();
// 3 + 4 = 7
assertEquals(7.0, calc.calculer("3 4 +"), 0.001);
// (3 + 4) * 5 = 35
assertEquals(35.0, calc.calculer("3 4 + 5 *"), 0.001);
// Test nombre négatif et soustraction : 10 - (-5) = 15
assertEquals(15.0, calc.calculer("10 -5 -"), 0.001);
// Test avec des nombres à plusieurs chiffres : 100 / 4 = 25
assertEquals(25.0, calc.calculer("100 4 /"), 0.001);
}
}
Écriture de la classe CalculatricePolonaise
Le code inclut la méthode de calcul ainsi qu'une méthode principale main permettant l'interaction au clavier avec la classe Scanner.
import java.util.Scanner;
import java.util.Stack;
public class CalculatricePolonaise {
public double calculer(String expression) {
Stack<Double> pile = new Stack<>();
// On sépare la chaîne selon les espaces multiples
String[] elements = expression.trim().split("\\s+");
for (String element : elements) {
if (element.isEmpty()) continue;
switch (element) {
case "+":
pile.push(pile.pop() + pile.pop());
break;
case "*":
pile.push(pile.pop() * pile.pop());
break;
case "-":
// Attention à l'ordre : le premier dépilé est l'opérande droit
double droiteSous = pile.pop();
double gaucheSous = pile.pop();
pile.push(gaucheSous - droiteSous);
break;
case "/":
double droiteDiv = pile.pop();
double gaucheDiv = pile.pop();
if (droiteDiv == 0) {
throw new ArithmeticException("Division par zéro");
}
pile.push(gaucheDiv / droiteDiv);
break;
default:
// Si ce n'est pas un opérateur, c'est un nombre. On le convertit.
pile.push(Double.parseDouble(element));
break;
}
}
// À la fin, le résultat final est le seul élément restant dans la pile
return pile.pop();
}
public static void main(String[] args) {
CalculatricePolonaise calc = new CalculatricePolonaise();
Scanner scanner = new Scanner(System.in);
System.out.println("--- Calculatrice Polonaise ---");
System.out.println("Entrez une expression postfixée (ex: '3 4 + 5 *') ou 'q' pour quitter :");
while (scanner.hasNextLine()) {
String ligne = scanner.nextLine();
if ("q".equalsIgnoreCase(ligne.trim())) {
System.out.println("Fin du programme.");
break;
}
try {
double resultat = calc.calculer(ligne);
System.out.println("Résultat : " + resultat);
} catch (Exception e) {
System.out.println("Erreur dans l'expression : vérifier la syntaxe (" + e.getMessage() + ")");
}
}
scanner.close();
}
}
Méthode
Face à une épreuve centrée sur les tests unitaires et le TDD (Test-Driven Development), votre démarche doit être systématique :
- Testez avant de coder : Le sujet l'exige. N'écrivez pas un seul algorithme avant d'avoir formalisé vos attentes. Les tests doivent prévoir les cas nominaux (fonctionnement normal), les cas limites (les zéros, l'ordre des opérateurs) et les cas erronés (divisions par zéro).
- Identifiez les "classes d'équivalence" : Dans l'exercice 1, ne testez pas tous les nombres. Prenez un représentant pour les multiples exclusifs de 3, un pour les multiples de 5, un pour les multiples de 15, et un pour les nombres standard. N'oubliez pas les frontières (comme 0).
- Misez sur la structure de données appropriée : Dans l'exercice 3, la notation polonaise est un cas d'école. La reconnaissance immédiate que ce problème relève d'une structure de Pile (Stack) résout 90 % de l'algorithme. Soyez attentif au sens de dépilement pour la soustraction et la division (premier élément sorti = opérande de droite !).
- Isolez la logique complexe : Dans l'horloge de Berlin (Exercice 2), découper le formatage visuel ("RROO", "JJRO...") dans une méthode utilitaire
construireLigneévite de répéter de nombreuses bouclesforet rend le code principal lisible.
Commentaires
Aucun commentaire pour le moment. Posez la première question.