Sujet du TP noté d'algorithmique et programmation (premier semestre).
Il s'est avéré que le sujet était trop long pour être réalisé en 1h30, il est plutôt adapté pour 2h.
Algorithmique et Programmation S1
Vous avez 1h30 pour réaliser ce TP noté.
Vous devez rendre votre travail dans un dossier spécifique contenant les fichiers sources de vos programme.
En mode examen sur les machines de l'université vous devez directement travail dans le dossier dédié à l'examen pour que votre travail ne soit pas perdu !
Notation :
18 points pour les exercices (+ 2 points bonus)
2 points sur 2 piliers d'évaluation suivants:
- Maîtrise générale des concepts (variables, tableaux, fonctions, structures, ...)
- Qualité du code (indentation, nommage, commentaires si nécessaire...)
Note finale = 18 + 2(Bonus) + 2 = 22 arrondie à 20.
Aide préliminaire
- Il faut inclure la bibliothèque
iostreampour utiliserstd::coutetstd::endlqui permettent respectivement d'afficher du texte et de passer à la ligne. - Il faut inclure respectivement les bibliothèques
string,vectoretarraypour utiliserstd::string,std::vectoretstd::array. - Pour convertir un type en un autre (cast), il faut utiliser la syntaxe suivante:
std::static_cast<type>(variable)
- Pour compiler manuellement un programme, il faut utiliser la commande
g++suivie du nom du fichier source et de l'option-osuivie du nom du fichier exécutable à générer (ex:g++ main.cpp -o main). Nous préciserons en plus l'option-Wallpour afficher les warnings (messages d'avertissement) et l'option-std=c++17pour utiliser la version C++17 du langage. - Ligne de compilation (pour un fichier
ex02.cpp):
g++ ex02.cpp -o ex02 -Wall -std=c++17
Exercice 1 (questionnaire) (3Pts: 4 questions de 0.75)
- Quelle est la différence entre un tableau statique et un tableau dynamique ?
- Quelle est la différence entre l'opérateur
=et l'opérateur==? - Qu’entendez-vous par passage par copie et passage par référence(
&) ? - A quoi servent les mots clés
constetunsigned? Quand et pourquoi les utiliser ?
Exercice 2 (maximum) (2Pts)
-
Écrire une fonction
maxqui prend en paramètre (par référence constante) un tableau d'entiers (tu es libre d'utiliser un tableau dynamique (std::vector) ou statique (std::array) ) et retourne la valeur maximale du tableau. -
Utiliser la fonction
maxpour afficher la valeur maximale des tableaux suivants:{1, 2, 3, 4, 5, 6, 7, 8, 9}{9, 8, 7, 6, 5, 4, 3, 2, 1}{1, 23, 7, 32, 5, 43}
Exercice 3 (voyelles) (3Pts)
- Écrire une fonction
isVowelqui prend en paramètre un caractère et retournetruesi le caractère est une voyelle,falsesinon.On considère que le caractère est une voyelle si c'est un des caractères suivants:
a,e,i,o,uouy. Attention, il faut compter les voyelles en majuscules et en minuscules. On peut utiliser la fonctionstd::tolower(de la bibliothèquecctype) pour convertir un caractère en minuscule. On peut également utiliser la représentation ASCII.
Quelques codes ASCII utiles:
| A Z | 0 9 | a z |
|---|---|---|
| 65 90 | 48 57 | 97 122 |
- Écrire une fonction
countVowelsqui prend en paramètre une chaîne de caractères (std::string) et retourne le nombre de voyelles dans la chaîne. - Afficher le nombre de voyelles dans les chaînes suivantes:
Hello World!Ceci est un testJe suis une phrase avec des voyelles
Exercice 4 (Géométrie) (2,5Pts + 1Pts bonus)
On dispose de la structure Point suivante:
struct Point {
float x;
float y;
};
- Écrire une fonction
distancequi prend en paramètre deux points et retourne la distance entre les deux points.
On utilisera la signature suivante:
float distance(Point const& p1, Point const& p2);
Pour rappel, la distance entre deux points
p1etp2est égale à la racine carrée de la somme des carrés des différences des coordonnées des points.
Vous pouvez utiliser les fonctions
sqrtetpowde la bibliothèquecmathpour calculer la racine carrée et la puissance d'un nombre.
#include <cmath>
float sqrt_test { std::sqrt(4) }; // racine carrée de 4 = 2
float pow_test { std::pow(2, 3) }; // 2^3 = 8
On considérera que la fonction précédente fonctionne pour la suite de l'exercice si ce n'est pas le cas.
- Écrire une fonction
isInCirclequi prend en paramètre un point (p), le centre d'un cercle (center) et son rayon (radius) et retournetruesi le pointpest dans le cercle,falsesinon.
On utilisera la signature suivante:
bool isInCircle(Point const& p, Point const& center, float radius);
-
Utiliser la fonction
isInCirclepour afficher si les points suivants sont dans le cercle de centre(0, 1)et de rayon2.4f:(0, 0)(1, 1)(3, 4)
-
(BONUS) Écrire une fonction
isCirclesIntersectqui prend en paramètre deux cercles (sous la forme de deux points et deux rayons) et retournetruesi les deux cercles s'intersectent,falsesinon.
Deux cercles s'intersectent si leurs centres sont à une distance inférieure à la somme de leur rayon.
-
(BONUS) Définir un structure
Circlequi contiendra les attributs suivants:center: centre du cercle (utiliser la structurePoint)radius: rayon du cercle
Réécrire les deux fonctions précédentes (surcharge) en utilisant la structure
Circleà la place des paramètresPointetfloat. -
(BONUS) Utiliser la fonction
isCirclesIntersectpour afficher si les deux cercles suivants s'intersectent:- Cercle 1: centre
(0, 0), rayon1 - Cercle 2: centre
(2, 0), rayon1
- Cercle 1: centre
Exercice 6 (Robot) (7.5Pts (10 questions de 0.75) + 1Pts bonus)
Pour cet exercice, je vous fourni un dossier dédié à l'exercice.
Ce dossier contient un sous-dossier src avec les fichiers sources ainsi qu'un fichier CMakeLists.txt pour compiler le programme.
la structure du dossier ressemble à ça:
robot/
L src/
| L main.cpp
| L direction.cpp
| L direction.hpp
| L point.cpp
| L point.hpp
| L robot.cpp
| L robot.hpp
L CMakeLists.txt
Compilation manuelle avec cmake
Ouvrir un terminal dans le dossier
robotcontenant le fichierCMakeLists.txtet exécuter les commandes suivantes:
mkdir build: créer un dossierbuild(qui va servir à stocker les fichiers de compilation)cd build: se déplacer dans le dossierbuildcmake ..: générer les fichiers de compilation dans le dossierbuildà partir du fichierCMakeLists.txtdu dossier parentmake: compiler le programme (générer l'exécutable à partir des fichiers de compilation Makefile)./main: exécuter le programme (remplacermainpar le nom de l'exécutable généré) (dans notre cas le cmake est configuré pour générer un exécutablerobotdans le dossierbinon peut donc exécuter le programme depuis le dossierbuildavec la commande../bin/robot)".." signifie le dossier parent.
"." signifie le dossier courant.
-
Le fichier
direction.hppcontient un enumDirectionavec les valeurs suivantes :north(Nord)south(Sud)east(Est)west(Ouest)
Créer le prototype d'une fonction
to_stringdans le fichierdirection.hppqui prends en paramètre une direction et retourne une chaîne de caractères (std::string) représentant cette Direction (ex:Direction::north"north"). -
Créer la définition de la fonction
to_stringdans le fichierdirection.cpp. -
Définir une structure
Pointdans le fichierpoint.hpp. Elle contiendra les attributs suivants :x: position en x (utiliser le typeint)y: position en y (utiliser le typeint)
La structure devra contenir les méthodes suivantes :
void display(): affiche les coordonnées du point sous la forme(x, y).void move(Direction const d, unsigned int const n): déplace le point dencases dans la directiond.
-
Implémenter les méthodes de la structure
Pointdans le fichierpoint.cpp.
On considère que la direction
northcorrespond à une augmentation de la coordonnéey(southune diminution dey) et que la directioneastcorrespond à une augmentation de la coordonnéex(westune diminution dex).
-
Créer une structure
Robotdans le fichierrobot.hppqui contiendra les attributs suivants :name: nom du robot (std::string)position: position du robot (utiliser la structurePoint)direction: direction du robot (utiliser l'enumDirection)
La structure devra contenir les méthodes suivantes :
void display(): affiche les informations du robot sous la formename((x, y), direction).void turnLeft(): tourne le robot de 90° vers la gauche. (ex:northdevientwest)void turnRight(): tourne le robot de 90° vers la droite.void move(unsigned int const n): déplace le robot dencases dans la direction du robot.
-
Implémenter les méthodes de la structure
Robotdans le fichierrobot.cpp. -
Ajouter le prototype d'une fonction
createRobotNamedans le fichierrobot.hpp, elle retournera un nom de robot généré aléatoirement sous la forme d'une chaîne de caractère avec un format contenant 2 lettres majuscules suivies de 3 chiffres aléatoires. (ex:AB123). -
Écrire la définition de la fonction
createRobotNamedans le fichierrobot.cpp.
Pour générer un nombre aléatoire, on peut utiliser la fonction std::rand (elle retourne un nombre aléatoire entre 0 et RAND_MAX).
On utilisera la fonction std::srand pour initialiser le générateur de nombres aléatoires avec la fonction std::time pour que les nombres générés soient différents à chaque exécution du programme.
Pour générer une lettre aléatoire, on peut utiliser la fonction rand et l'opérateur modulo (%) pour générer un nombre aléatoire entre 0 et 25:
#include <cstdlib> // pour utiliser la fonction std::rand
#include <ctime> // pour utiliser la fonction std::time
int main() {
// initialiser le générateur de nombres aléatoires
// A utiliser une seule fois dans le programme (dans le main par exemple)
std::srand(std::time(nullptr));
// générer un nombre aléatoire entre 0 et 25 (+1 pour inclure 25)
int random_number { std::rand() % (25+1) };
return 0;
}
On peut se servir de ce nombre pour générer une lettre majuscule (en utilisant la représentation ASCII des lettres majuscules). Quelques codes ASCII utiles sont indiqués à l'exercice 3.
-
Ajouter le prototype d'une fonction
createRobotdans le fichierrobot.hpp, elle prendra en paramètre un point et une direction et retournera un robot avec les paramètres passés en argument. le nom du robot sera généré aléatoirement avec la fonctioncreateRobotName. -
Compléter la fonction main du fichier
main.cpppour effectuer les actions suivantes:
- Créer un robot avec la fonction
createRobotà la position(0, 0)et la direction initialenorth. - Afficher le robot avec la méthode
display. - Effectuer les actions suivantes et afficher la valeur du robot avec la méthode
displayune fois les actions effectuées:- Tourner le robot à gauche
- Déplacer le robot de 3 cases
- Tourner le robot à droite
- Déplacer le robot de 5 cases
- Déplacer le robot de 2 cases
- Tourner deux fois le robot à gauche
- Déplacer le robot de 1 case
- Tourner le robot à droite
- Déplacer le robot de 2 cases
Utiliser les méthodes de la structure
Robotpour effectuer les actions.
- (Bonus) Utiliser un tableau pour stocker les actions à effectuer et les exécuter dans une boucle.
Vous pouvez utiliser des caractères (avec une
std::string(qui est un tableau de caractères) ou unstd::vector) pour symboliser les actions à effectuer:
L: tourner à gaucheR: tourner à droite3: déplacer le robot de 3 cases (de même pour tout les autres chiffres)- Seulement les chiffres
1à9sont à considérés, ainsi "12" correspond à un déplacement de 1 case puis un autre de 2 cases.