diff --git a/Algo/tp/Cpp/tp4/.idea/.gitignore b/Algo/tp/Cpp/tp4/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/Algo/tp/Cpp/tp4/.idea/discord.xml b/Algo/tp/Cpp/tp4/.idea/discord.xml
new file mode 100644
index 0000000..30bab2a
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/.idea/discord.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Algo/tp/Cpp/tp4/.idea/misc.xml b/Algo/tp/Cpp/tp4/.idea/misc.xml
new file mode 100644
index 0000000..53624c9
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/.idea/misc.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Algo/tp/Cpp/tp4/Makefile b/Algo/tp/Cpp/tp4/Makefile
new file mode 100644
index 0000000..e40974c
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/Makefile
@@ -0,0 +1,20 @@
+cc=g++ -std=c++17 -g -Wall -Werror -pedantic
+
+all: tp
+
+obj/Wagon.o: src/Wagon.cpp src/Wagon.h src/Passager.h
+ $(cc) -c src/Wagon.cpp -o obj/Wagon.o
+obj/Passager.o: src/Passager.cpp src/Passager.h
+ $(cc) -c src/Passager.cpp -o obj/Passager.o
+obj/main.o: src/main.cpp src/Train.h src/Wagon.h src/Passager.h \
+ src/TrainExceptions.h
+ $(cc) -c src/main.cpp -o obj/main.o
+obj/Train.o: src/Train.cpp src/Train.h src/Wagon.h src/Passager.h \
+ src/TrainExceptions.h
+ $(cc) -c src/Train.cpp -o obj/Train.o
+
+tp: obj/Wagon.o obj/Passager.o obj/main.o obj/Train.o
+ $(cc) obj/Wagon.o obj/Passager.o obj/main.o obj/Train.o -o tp
+
+clean:
+ rm -Rf obj/* tp
diff --git a/Algo/tp/Cpp/tp4/obj/Passager.o b/Algo/tp/Cpp/tp4/obj/Passager.o
new file mode 100644
index 0000000..aff165c
Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/Passager.o differ
diff --git a/Algo/tp/Cpp/tp4/obj/Train.o b/Algo/tp/Cpp/tp4/obj/Train.o
new file mode 100644
index 0000000..7456024
Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/Train.o differ
diff --git a/Algo/tp/Cpp/tp4/obj/Wagon.o b/Algo/tp/Cpp/tp4/obj/Wagon.o
new file mode 100644
index 0000000..97ecfda
Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/Wagon.o differ
diff --git a/Algo/tp/Cpp/tp4/obj/main.o b/Algo/tp/Cpp/tp4/obj/main.o
new file mode 100644
index 0000000..6ab5c92
Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/main.o differ
diff --git a/Algo/tp/Cpp/tp4/src/Passager.cpp b/Algo/tp/Cpp/tp4/src/Passager.cpp
new file mode 100644
index 0000000..80cf871
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/Passager.cpp
@@ -0,0 +1,17 @@
+#include "Passager.h"
+
+using namespace std;
+
+Passager::Passager(std::string nom, std::string prenom)
+ : nom{std::move(nom)}, prenom{std::move(prenom)} {}
+
+/*Passager& Passager::operator=(const Passager& o) {
+ if (o == *this) return *this;
+ nom = o.bom;
+ prenom = o.nom;
+ return *this;
+}*/
+
+std::ostream& operator<<(std::ostream& os, const Passager& passager) {
+ return os << passager.nom << " " << passager.prenom;
+}
diff --git a/Algo/tp/Cpp/tp4/src/Passager.h b/Algo/tp/Cpp/tp4/src/Passager.h
new file mode 100644
index 0000000..f73cba8
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/Passager.h
@@ -0,0 +1,16 @@
+#include
+#include
+
+class Passager {
+private:
+ std::string nom;
+ std::string prenom;
+public:
+ friend std::ostream& operator<<(std::ostream& os, const Passager& passagers);
+ Passager() = default;
+ Passager(std::string nom, std::string prenom);
+ Passager& operator=(const Passager& o) = default;
+};
+
+std::ostream& operator<<(std::ostream& os, const Passager& passager);
+
diff --git a/Algo/tp/Cpp/tp4/src/Train.cpp b/Algo/tp/Cpp/tp4/src/Train.cpp
new file mode 100644
index 0000000..c5fdf4b
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/Train.cpp
@@ -0,0 +1,138 @@
+#include "Train.h"
+
+#include "TrainExceptions.h"
+
+// Si des passagers peuvent être à deux endroits à la fois, il va potentiellement falloir le faire descendre deux fois du train.
+#define UBIQUITE
+
+using namespace std;
+
+Train::Train(int nbWagons)
+ : lesWagons{} {
+ //lesWagons.reserve(nbWagons);
+ for (int i = 1; i <= nbWagons; ++i) {
+ lesWagons.emplace_back(i);
+ }
+}
+
+Train::Train(std::initializer_list listeNumerosWagons)
+ : lesWagons{} {
+ //lesWagons.reserve(listeNumerosWagons.size());
+ for (int numWagon : listeNumerosWagons) {
+ //lesWagons.push_back(new Wagon{numWagon});
+ lesWagons.emplace_back(numWagon);
+ }
+}
+
+void Train::demarrer() {
+ roule = true;
+}
+
+void Train::arreter() {
+ roule = false;
+}
+
+bool Train::isRoule() const {
+ return roule;
+}
+
+void Train::monterDansLeTrain(int numeroWagon, const Passager& passager) {
+ if (roule) {
+ throw RouleException{};
+ }
+ // -> map
+ for (Wagon& wagon : lesWagons) {
+ if (wagon.getNumero() == numeroWagon) {
+ if (!wagon.ajouter(passager)) {
+ throw WagonPleinException{};
+ }
+ return;
+ }
+ }
+ throw WagonInexistantException{};
+}
+
+void Train::descendreDuTrain(const Passager& passager) {
+ if (roule) {
+ throw RouleException{};
+ }
+#ifdef UBIQUITE
+ bool descendu = false;
+ for (Wagon& wagon : lesWagons) {
+ descendu |= wagon.enlever(passager);
+ }
+ if (!descendu) {
+ throw PassagerException{};
+ }
+#else
+ for (Wagon& wagon : lesWagons) {
+ if (wagon.enlever(passager)) {
+ return;
+ }
+ }
+ throw PassagerException{};
+#endif
+}
+
+void Train::deplacerAuWagonSuivant(const Passager& passager) {
+ if (roule) {
+ throw RouleException{};
+ }
+ vector::iterator it = lesWagons.begin();
+ while (it != lesWagons.end() && !it->enlever(passager)) {
+ ++it;
+ }
+ if (it == lesWagons.end()) {
+ throw PassagerException{};
+ }
+ ++it;
+ if (it == lesWagons.end()) {
+ throw BoutDuTrainException{};
+ }
+ if (it->estPlein()) {
+ throw WagonPleinException{};
+ }
+ it->ajouter(passager);
+}
+
+void Train::deplacerAuWagonPrecedent(const Passager& passager) {
+ if (roule) {
+ throw RouleException{};
+ }
+ vector::reverse_iterator it = lesWagons.rbegin();
+ while (it != lesWagons.rend() && !it->enlever(passager)) {
+ ++it;
+ }
+ if (it == lesWagons.rend()) {
+ throw PassagerException{};
+ }
+ ++it;
+ if (it == lesWagons.rend()) {
+ throw BoutDuTrainException{};
+ }
+ if (it->estPlein()) {
+ throw WagonPleinException{};
+ }
+ it->ajouter(passager);
+}
+
+int Train::monterDansLeTrainAPartirDe(int numeroWagon, const Passager& passager) {
+ if (roule) {
+ throw RouleException{};
+ }
+ vector::iterator it = lesWagons.begin();
+ while (it != lesWagons.end() && it->getNumero() != numeroWagon) {
+ ++it;
+ }
+ if (it == lesWagons.end()) {
+ throw WagonInexistantException{};
+ }
+ while (it != lesWagons.end() && it->estPlein()) {
+ ++it;
+ }
+ if (it == lesWagons.end()) {
+ throw BoutDuTrainException{};
+ }
+ it->ajouter(passager);
+ return it->getNumero();
+}
diff --git a/Algo/tp/Cpp/tp4/src/Train.h b/Algo/tp/Cpp/tp4/src/Train.h
new file mode 100644
index 0000000..3a03bd9
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/Train.h
@@ -0,0 +1,22 @@
+#include
+#include
+
+#include "Wagon.h"
+
+class Train {
+private:
+ std::vector lesWagons;
+ bool roule{};
+public:
+ explicit Train(int nbWagons);
+ Train(std::initializer_list listeNumerosWagons);
+ void demarrer();
+ void arreter();
+ bool isRoule() const;
+ void monterDansLeTrain(int numeroWagon, const Passager& passager);
+ int monterDansLeTrainAPartirDe(int numeroWagon, const Passager& passager);
+ void descendreDuTrain(const Passager& passager);
+ void deplacerAuWagonPrecedent(const Passager& passager);
+ void deplacerAuWagonSuivant(const Passager& passager);
+};
+
diff --git a/Algo/tp/Cpp/tp4/src/TrainExceptions.h b/Algo/tp/Cpp/tp4/src/TrainExceptions.h
new file mode 100644
index 0000000..29f4413
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/TrainExceptions.h
@@ -0,0 +1,10 @@
+#ifndef TRAIN_EXCEPTIONS_HPP
+#define TRAIN_EXCEPTIONS_HPP
+
+class RouleException {};
+class WagonInexistantException {};
+class WagonPleinException {};
+class PassagerException {};
+class BoutDuTrainException {};
+
+#endif // TRAIN_EXCEPTIONS_HPP
diff --git a/Algo/tp/Cpp/tp4/src/Wagon.cpp b/Algo/tp/Cpp/tp4/src/Wagon.cpp
new file mode 100644
index 0000000..0f6d81b
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/Wagon.cpp
@@ -0,0 +1,48 @@
+#include "Wagon.h"
+
+Wagon::Wagon(int numero) : numero{numero}, lesPassagers{} {
+
+}
+
+int Wagon::getNumero() const {
+ return numero;
+}
+
+bool Wagon::estPlein() const {
+ return lesPassagers.size() >= capacite;
+}
+
+bool Wagon::ajouter(const Passager& passager) {
+ if (lesPassagers.size() >= capacite) {
+ return false;
+ }
+ lesPassagers.push_front(&passager);
+ return true;
+}
+
+bool Wagon::enlever(const Passager& passager) {
+ std::list::size_type previous = lesPassagers.size();
+ lesPassagers.remove(&passager);
+ return previous != lesPassagers.size();
+}
+
+int Wagon::debarquer(int nbPassager) {
+ int c = nbPassager;
+ while (!lesPassagers.empty() && c > 0) {
+ lesPassagers.pop_back();
+ --c;
+ }
+ return nbPassager - c;
+}
+
+std::ostream& operator<<(std::ostream& os, const Wagon& wagon) {
+ if (wagon.lesPassagers.empty()) {
+ return os;
+ }
+ std::list::const_iterator it = wagon.lesPassagers.cbegin();
+ os << **it;
+ while (++it != wagon.lesPassagers.cend()) {
+ os << ", " << **it;
+ }
+ return os;
+}
diff --git a/Algo/tp/Cpp/tp4/src/Wagon.h b/Algo/tp/Cpp/tp4/src/Wagon.h
new file mode 100644
index 0000000..746fa4a
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/Wagon.h
@@ -0,0 +1,22 @@
+#include
+#include
+
+#include "Passager.h"
+
+class Wagon {
+private:
+ constexpr static int capacite = 20;
+ int size;
+ int numero;
+ std::list lesPassagers;
+public:
+ friend std::ostream& operator<<(std::ostream& os, const Wagon& wagon);
+ explicit Wagon(int numero);
+ int getNumero() const;
+ bool estPlein() const;
+ bool ajouter(const Passager& passager);
+ bool enlever(const Passager& passager);
+ int debarquer(int nbPassager);
+};
+
+std::ostream& operator<<(std::ostream& os, const Wagon& wagon);
diff --git a/Algo/tp/Cpp/tp4/src/main.cpp b/Algo/tp/Cpp/tp4/src/main.cpp
new file mode 100644
index 0000000..b64e681
--- /dev/null
+++ b/Algo/tp/Cpp/tp4/src/main.cpp
@@ -0,0 +1,355 @@
+#include "Train.h"
+#include "TrainExceptions.h"
+
+#include
+#include
+
+using namespace std;
+using Gens = std::array;
+
+void testsWagon() {
+ Passager pierre("Dupont", "Pierre");
+ Passager paul("Durand", "Paul");
+
+ cout << "Vérif si wagon gère correctement son numero... ";
+ Wagon wagon{42};
+ cout << (wagon.getNumero() == 42 ? "OK\n" : "ERREUR\n");
+
+ cout << "Vérif si possible de faire monter 20 personnes dans un wagon... ";
+ Gens gens;
+ for (Gens::size_type i{0}; i < gens.size(); ++i)
+ gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"};
+
+ bool ajoutOK{true};
+ for (const Passager &personne : gens) {
+ ajoutOK = ajoutOK && wagon.ajouter(personne);
+ }
+ cout << (ajoutOK ? "OK\n" : "ERREUR\n");
+ //cout << wagon << "\n";
+
+ cout << "Vérif si impossible de faire monter 1 personne dans un wagon "
+ "plein... ";
+ cout << (wagon.ajouter(pierre) ? "ERREUR\n" : "OK\n");
+
+ cout << "Vérif si possible de faire debarquer 14 personnes sur 20... ";
+ cout << (wagon.debarquer(14) == 14 ? "OK\n" : "ERREUR\n");
+ // cout << wagon;
+
+ cout << "Vérif si possible de faire debarquer les 6 passagers restants... ";
+ cout << (wagon.debarquer(20) == 6 ? "OK\n" : "ERREUR\n");
+ // cout << wagon;
+
+ cout << "Vérif si possible de faire debarquer 1 passager donné... ";
+ wagon.ajouter(pierre);
+ cout << (wagon.enlever(pierre) ? "OK\n" : "ERREUR\n");
+
+ cout << "Vérif si impossible de faire debarquer 1 passager pas dans le "
+ "wagon... ";
+ cout << (wagon.enlever(paul) ? "ERREUR\n" : "OK\n");
+
+ cout << "Vérif si impossible de faire debarquer 1 passager d'un wagon "
+ "vide... ";
+ cout << (wagon.enlever(pierre) ? "ERREUR\n" : "OK\n");
+}
+
+void testMonterDansTrain() {
+ Passager pierre{"Dupont", "Pierre"};
+ Train train(3);
+
+ cout << "Vérif si impossible de monter dans un train qui roule... ";
+ train.demarrer();
+ try {
+ train.monterDansLeTrain(1, pierre);
+ cout << "ERREUR\n";
+ } catch (const RouleException &) {
+ cout << " OK\n";
+ }
+
+ cout << "Vérif si impossible de monter si numéro de wagon non existant... ";
+ train.arreter();
+ try {
+ train.monterDansLeTrain(4, pierre);
+ cout << "ERREUR\n";
+ } catch (const WagonInexistantException &) {
+ cout << "OK\n";
+ }
+
+ cout << "Vérif si possible de faire monter 20 personnes dans un wagon "
+ "existant, non complet et train arrêté... ";
+ Gens gens;
+ for (Gens::size_type i{0}; i < gens.size(); ++i)
+ gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"};
+
+ try {
+ for (const Passager &personne : gens) {
+ train.monterDansLeTrain(1, personne);
+ }
+ cout << "OK\n";
+ } catch (...) {
+ cout << "ERREUR\n";
+ }
+
+ cout << "Vérif si impossible de monter dans le wagon si déjà complet... ";
+ try {
+ train.monterDansLeTrain(1, pierre);
+ cout << "ERREUR\n";
+ } catch (const WagonPleinException &) {
+ cout << "OK\n";
+ }
+}
+
+void testDescendreDuTrain() {
+ Passager pierre("Dupont", "Pierre");
+ Passager paul("Durand", "Paul");
+ Train train(3);
+
+ // cout << "Pierre monte dans le wagon 1\n";
+ train.monterDansLeTrain(1, pierre);
+
+ cout << "Vérif si impossible de descendre du train qui roule... ";
+ train.demarrer();
+ try {
+ train.descendreDuTrain(pierre);
+ cout << "ERREUR\n";
+ } catch (const RouleException &) {
+ cout << " OK\n";
+ }
+
+ // cout << "Paul n'est pas dans le train\n";
+ cout << "Vérif si impossible de descendre du train sans s'y trouver... ";
+ train.arreter();
+ try {
+ train.descendreDuTrain(paul);
+ cout << "ERREUR\n";
+ } catch (const PassagerException &) {
+ cout << "OK\n";
+ }
+
+ cout << "Vérif si possible de descendre du wagon existant et train "
+ "arrêté... ";
+ try {
+ train.descendreDuTrain(pierre);
+ cout << " OK\n";
+ } catch (...) {
+ cout << "ERREUR\n";
+ }
+}
+
+void testDeplacerAuWagonSuivant() {
+ Passager alice("Dups", "Alice");
+ Passager pierre("Dupont", "Pierre");
+ Passager paul("Durand", "Paul");
+ Passager marie("Dumont", "Marie");
+ Train train(3);
+
+ // cout << "Pierre monte dans le premier wagon (1)\n";
+ train.monterDansLeTrain(1, pierre);
+ // cout << "Paul monte dans le wagon 2\n";
+ train.monterDansLeTrain(2, paul);
+ // cout << "Marie monte dans le dernier wagon (3)\n";
+ train.monterDansLeTrain(3, marie);
+ // cout << "Alice n'est pas dans le train\n";
+
+ cout << "Vérif si impossible de déplacer un passager qui n'est pas dans le "
+ "train... ";
+ try {
+ train.deplacerAuWagonSuivant(alice);
+ cout << "ERREUR\n";
+ } catch (const PassagerException &) {
+ cout << " OK\n";
+ }
+
+ cout << "Vérif si impossible de passer au wagon suivant car déjà dans le "
+ "dernier wagon... ";
+ try {
+ train.deplacerAuWagonSuivant(marie);
+ cout << "ERREUR\n";
+ } catch (const BoutDuTrainException &) {
+ cout << " OK\n";
+ }
+
+ Gens gens;
+ for (Gens::size_type i{0}; i < gens.size() - 1; ++i)
+ gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"};
+
+ try {
+ for (const Passager &personne : gens)
+ train.monterDansLeTrain(3, personne);
+ } catch (...) {
+ cout << "ERREUR le wagon 3 devrait pouvoir contenir 20 passagers !\n";
+ }
+
+ cout << "Vérif si impossible de passer au wagon suivant car wagon déjà "
+ "complet... ";
+ try {
+ train.deplacerAuWagonSuivant(paul);
+ cout << "ERREUR\n";
+ } catch (const WagonPleinException &) {
+ cout << "OK\n";
+ }
+
+ cout << "Vérif si possible de passer au wagon suivant (bonnes "
+ "conditions)... ";
+ try {
+ train.deplacerAuWagonSuivant(pierre);
+ cout << "OK\n";
+ } catch (...) {
+ cout << "ERREUR\n";
+ }
+}
+
+void testDeplacerAuWagonPrecedent() {
+ Passager alice("Dups", "Alice");
+ Passager pierre("Dupont", "Pierre");
+ Passager paul("Durand", "Paul");
+ Passager marie("Dumont", "Marie");
+ Train train(3);
+
+ // cout << "Pierre monte dans le premier wagon (1)\n";
+ train.monterDansLeTrain(1, pierre);
+ // cout << "Paul monte dans le wagon 2\n";
+ train.monterDansLeTrain(2, paul);
+ // cout << "Marie monte dans le dernier wagon (3)\n";
+ train.monterDansLeTrain(3, marie);
+ // cout << "Alice n'est pas dans le train\n";
+
+ cout << "Vérif si impossible de déplacer au wagon précédent un passager "
+ "qui n'est pas dans le train... ";
+ try {
+ train.deplacerAuWagonPrecedent(alice);
+ cout << "ERREUR\n";
+ } catch (const PassagerException &) {
+ cout << " OK\n";
+ }
+
+ cout << "Vérif si impossible de passer au wagon précédent car déjà dans le "
+ "premier wagon... ";
+ try {
+ train.deplacerAuWagonPrecedent(pierre);
+ cout << "ERREUR\n";
+ } catch (const BoutDuTrainException &) {
+ cout << " OK\n";
+ }
+
+ Gens gens;
+ for (Gens::size_type i{0}; i < gens.size() - 1; ++i)
+ gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"};
+
+ try {
+ for (const Passager &personne : gens)
+ train.monterDansLeTrain(1, personne);
+ } catch (...) {
+ cout << "ERREUR le wagon 1 devrait pouvoir contenir 20 passagers !\n";
+ }
+
+ cout << "Vérif si impossible de passer au wagon précédent car wagon déjà "
+ "complet... ";
+ try {
+ train.deplacerAuWagonPrecedent(paul);
+ cout << "ERREUR\n";
+ } catch (const WagonPleinException &) {
+ cout << "OK\n";
+ }
+
+ cout << "Vérif si possible de passer au wagon précédent (bonnes "
+ "conditions)... ";
+ try {
+ train.deplacerAuWagonPrecedent(marie);
+ cout << "OK\n";
+ } catch (...) {
+ cout << "ERREUR\n";
+ }
+}
+
+void testMonterDansLeTrainAPartirDe() {
+ Passager pierre("Dupont", "Pierre");
+ Train train(3);
+
+ cout << "Vérif si impossible de monter à partir d'un numero de wagon non "
+ "existant... ";
+ try {
+ train.monterDansLeTrainAPartirDe(4, pierre);
+ cout << "ERREUR\n";
+ } catch (const WagonInexistantException &) {
+ cout << "OK\n";
+ }
+
+ train.demarrer();
+ cout << "Vérif si impossible de monter dans un train qui roule... ";
+ try {
+ train.monterDansLeTrainAPartirDe(1, pierre);
+ cout << "ERREUR\n";
+ } catch (const RouleException &) {
+ cout << "OK\n";
+ }
+
+ train.arreter();
+ Gens gens;
+ for (Gens::size_type i{0}; i < gens.size() - 1; ++i)
+ gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"};
+
+ // On remplit tous les wagons (on triche un peu)
+ // Magie de l'informatique, on donne le don d'ubiquité aux gens
+ try {
+ for (const Passager &personne : gens) {
+ train.monterDansLeTrain(1, personne);
+ train.monterDansLeTrain(2, personne);
+ train.monterDansLeTrain(3, personne);
+ }
+ } catch (...) {
+ cout << "ERREUR on devrait pouvoir remplir le train !\n";
+ }
+
+ cout << "Vérif si impossible de monter dans un train complet... ";
+ try {
+ train.monterDansLeTrainAPartirDe(1, pierre);
+ cout << "ERREUR\n";
+ } catch (const BoutDuTrainException &) {
+ cout << "OK\n";
+ }
+
+ try {
+ for (const Passager &personne : gens) {
+ train.descendreDuTrain(personne);
+ }
+ } catch (...) {
+ cout << "ERREUR on devrait pouvoir vider le premier wagon !\n";
+ }
+
+ cout << "Vérif si on peut monter dans un train où il y a de la place... ";
+ try {
+ int pos = train.monterDansLeTrainAPartirDe(2, pierre);
+ cout << "OK, " << pierre << " est monté dans le wagon " << pos << "\n";
+ } catch (...) {
+ cout << "ERREUR\n";
+ }
+
+ cout << "Vérif si le passager peut descendre... ";
+ try {
+ train.descendreDuTrain(pierre);
+ cout << "OK\n";
+ } catch (...) {
+ cout << "ERREUR\n";
+ }
+}
+
+int main() {
+ cout << "---------- TESTS WAGONS ------------\n";
+ testsWagon();
+
+ cout << "---------- TEST MONTER DANS LE TRAIN ------------\n";
+ testMonterDansTrain();
+
+ cout << "---------- TEST DESCENDRE DU TRAIN ------------\n";
+ testDescendreDuTrain();
+
+ cout << "---------- TEST DEPLACER AU WAGON SUIVANT ------------\n";
+ testDeplacerAuWagonSuivant();
+
+ cout << "---------- TEST DEPLACER AU WAGON PRECEDENT ------------\n";
+ testDeplacerAuWagonPrecedent();
+
+ cout << "---------- TEST MONTER DANS LE TRAIN A PARTIR DE "
+ "------------\n";
+ testMonterDansLeTrainAPartirDe();
+}
diff --git a/Algo/tp/Cpp/tp4/tp b/Algo/tp/Cpp/tp4/tp
new file mode 100755
index 0000000..7fb2c7f
Binary files /dev/null and b/Algo/tp/Cpp/tp4/tp differ
diff --git a/Maths/tp/Bezier/tp3 - polices de caractères-20230210/TP3_polices.pdf b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/TP3_polices.pdf
new file mode 100644
index 0000000..0d7d04e
Binary files /dev/null and b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/TP3_polices.pdf differ
diff --git a/Maths/tp/Bezier/tp3 - polices de caractères-20230210/m.svg b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/m.svg
new file mode 100644
index 0000000..71ac257
--- /dev/null
+++ b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/m.svg
@@ -0,0 +1,208 @@
+
+
diff --git a/Maths/tp/Bezier/tp3 - polices de caractères-20230210/tp3_exo2.py b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/tp3_exo2.py
new file mode 100644
index 0000000..ae68fb7
--- /dev/null
+++ b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/tp3_exo2.py
@@ -0,0 +1,274 @@
+
+import numpy as np
+import matplotlib.pyplot as plt
+
+# k l m
+
+#################################################################################################
+###
+### EXERCICE 2 : Définir une nouvelle police de caractères sous Python
+###
+#################################################################################################
+
+
+# On active le "mode interactif" de pyplot. Ainsi, les plt.show() ne sont plus nécessaires.
+plt.ion()
+
+# --------------------------------------------------------------------------------------
+# Fonction de "fin temporaire" pendant l'avancée du TP. Attend une frappe Entrée, puis quitte le script.
+
+def stop_ici():
+ plt.pause(0.1) # nécessaire pour que matplotlib ait le temps d'afficher les figures
+ input()
+ exit()
+
+# --------------------------------------------------------------------------------------
+# Tous les passages indiqués "TODO()" sont à remplacer par vos soins
+
+def TODO():
+ print("à vous!")
+ stop_ici()
+
+
+######################################################################
+### Fonctions de tracé de courbes de Bézier : reprises du TP2
+######################################################################
+
+# --------------------------------------------------------------------------------------
+# Calcul d'un point d'une courbe de Bézier
+#
+# - t = paramètre du point de la courbe à calculer [nombre réel entre 0 et 1]
+# - P = points de contrôle [au même format qu'au TP2 : np.array de taille (N+1,2)]
+
+def bezierCasteljau(t,P):
+ while(P.shape[0]>1):
+ P = (1-t)*P[:-1] + t*P[1:]
+ return P[0]
+
+# --------------------------------------------------------------------------------------
+# Traçage d'une courbe dans sa totalité
+#
+# - P = points de contrôle [au même format qu'au TP2 : np.array de taille (N+1,2)]
+# - trace_controle = True pour tracer également le polygone de controle
+# - kwargs permet de passer tous les arguments habituels de la commande plt.plot (couleur, markers, etc.)
+
+def traceBezier(P, trace_controle=False, **kwargs):
+ if trace_controle:
+ plt.plot( P[:,0], P[:,1], linestyle='--', color='black')
+ Nt = 100
+ Ft = np.array( [ bezierCasteljau(t,P) for t in np.linspace(0,1,Nt) ] )
+ plt.plot( Ft[:,0], Ft[:,1], **kwargs)
+
+# --------------------------------------------------------------------------------------
+# Traçage d'un carré de coté 1
+#
+# - offset = coordonnées du coin en bas à gauche du carré ([0,0] par défaut)
+# - kwargs permet de passer tous les arguments habituels de la commande plt.plot (couleur, markers, etc.)
+
+def traceCarre(offset=[0,0], **kwargs):
+ Carre = np.array( [ [0,0], [1,0], [1,1], [0,1], [0,0] ] )
+ Carre = Carre + np.array(offset)
+ plt.plot( Carre[:,0], Carre[:,1], **kwargs)
+
+
+print("-"*80)
+print(''' QUESTION 1 : Prise en main des fonctions.
+
+Dans une première figure, tracez :
+- En VERT: un carré de coté 1 (et tel que son coin en bas à gauche soit aux coordonnées [0,0])
+- En BLEU: la courbe de Bézier associée aux points de contrôle
+P0=[0,0], P1=[2,2], P2=[2,-2], P3=[0,2], P4=[0,0]
+''')
+
+
+
+plt.figure()
+plt.title("Question 1")
+
+traceCarre(offset=[0,0], color='green')
+P = np.array( [ [0,0], [2,2], [2,-2], [0,2], [0,0] ] )
+traceBezier(P, color='blue')
+
+plt.axis('equal')
+
+# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+
+print("-"*80)
+print(''' QUESTION 2.
+Complétez le code de tracé de la fonction traceLettre ci-dessous [le TODO() à la fin de la fonction].
+
+Pour ce faire, réfléchissez bien aux points suivants :
+- Sous quel format la fonction traceBezier doit-elle recevoir les points de contrôle ?
+- Comment 'transmettre' à la fonction traceBezier le fait qu'on veut ou non tracer le polygone de contrôle ?
+- Comment 'transmettre' à la fonction traceBezier les options de traçage (couleur, etc.) passées à la fonction traceLettres ?
+
+Vérification : une fois le TODO() complété, le code de test suivant devra tracer la lettre "a" en bleu (et ses points de controle)
+''')
+
+
+###################################################################
+# Fonction de tracé d'une lettre quelconque.
+# C'est la fonction principale de cet exercice.
+# On vous donne un squelette, que vous allez compléter progressivement.
+###################################################################
+#
+# - char : caractère qu'on souhaite tracer ("a", "b", etc., ainsi que l'espace " ")
+# - offset = coordonnées du point auquel on souhaite tracer la lettre ([0,0] si on ne précise pas)
+# - trace_controle, kwargs : même signification que pour la fonction traceBezier
+
+def traceLettre(char, offset=[0,0], trace_controle=False, **kwargs):
+
+ # Définition de la liste des points de contrôle pour cette lettre
+ # ( strokes[0]=points de contrôle pour le 1er trait, strokes[1]=points de contrôle pour le 2è trait, etc. )
+ strokes = []
+
+ if char =="a":
+ strokes.append( [ [.8,.05], [.8,1] , [.75,1.1], [.1,.85] ] ) # premier trait du 'a'
+ strokes.append( [ [.78,.1], [-.25,-.3], [-.3,.7], [.8, .5] ] ) # deuxième trait du 'a'
+
+ elif char=="m":
+ strokes.append( [ [1.1,0], [1.1,1.1], [0,1.1], [0,0] ] )
+ strokes.append( [ [1.1,0], [1.1,1.1], [2.1,1.1], [2.1,0] ] )
+ # B = np.array([[4.3,1.4], [4.3,1.2]]) # Permet de faire un bout de sein si on inverse les appends de [A B C D] en [B A D C]
+ # plt.plot(B[:,0], B[:,1], linestyle='--', color='black')
+
+ elif char=="k":
+ strokes.append( [ [0,0], [0,1.1], [1.1,0], [0,0] ] )
+ strokes.append( [ [1.1,1.1], [1.1,0], [0,1.1], [1.1,1.1] ] )
+
+ elif char=="l":
+ strokes.append( [ [0,0], [0,1.1], [1.1,1.1], [0,0] ] )
+ strokes.append( [ [1.1,0], [1.1,1.1], [0,1.1], [1.1,0] ] )
+
+ elif char==" ":
+ pass # pour 'tracer' le caractère espace... on ne trace rien ! ^^
+
+ else:
+ raise("character '"+char+"' is not implemented yet")
+
+ ### Le tracé proprement dit
+ for lst in strokes:
+ print(lst) # pour que vous compreniez ce que contient la variable lst (vous pouvez ensuite supprimer cette ligne)
+ P = np.array(lst)
+ traceBezier(P) # Tracer la courbe de Bézier définie par la liste de points lst
+
+
+
+### Code de test:
+plt.figure()
+traceLettre("m", trace_controle=True, color="blue", linewidth=3)
+# traceCarre(color="green")
+plt.axis("equal")
+
+stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+
+print("-"*80)
+print(''' QUESTION 3 : trois nouvelles lettres.
+
+À ce stade, la fonction traceLettre sait uniquement tracer un "a". Rajoutez le code (=les 'strokes') permettant de tracer les lettres "g", "t" et "c".
+
+Méthode conseillée : construisez la lettre sous inkscape (exo 1), puis relevez la position des points de contrôle et rentrez-les sous Python.
+
+Attention : chaque lettre doit "tenir" dans un carré unité (le "g" pouvant dépasser un peu vers le bas, et le "t" un peu vers le haut)
+''')
+
+### Teste le "g":
+plt.figure()
+traceLettre("g", trace_controle=True, color="blue", linewidth=3)
+traceCarre(color="green")
+plt.axis("equal")
+
+stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+### Teste le "t":
+plt.figure()
+traceLettre("t", trace_controle=True, color="blue", linewidth=3)
+traceCarre(color="green")
+plt.axis("equal")
+
+stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+### Teste le "c":
+plt.figure()
+traceLettre("c", trace_controle=True, color="blue", linewidth=3)
+traceCarre(color="green")
+plt.axis("equal")
+
+stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+
+print("-"*80)
+print(''' QUESTION 4 : Gestion de l'offset.
+
+Modifiez votre fonction traceLettre afin de pouvoir passer en option l'OFFSET (=décalage) auquel on souhaite tracer la lettre.
+Inspirez-vous de la fonction traceCarre, pour laquelle cette fonctionnalité est déjà implémentée.
+
+Vérification : une fois votre code écrit, le code ci-dessous représentera les 4 lettres a,c,g,t dans la disposition suivante:
+ ac
+ gt
+''')
+
+### Vérification:
+plt.figure()
+traceLettre("a", offset = [0,0], color="blue", linewidth=3)
+traceCarre(color="green", offset=[0,0] )
+traceLettre("c", offset = [2,0], color="blue", linewidth=3)
+traceCarre(color="green", offset=[2,0] )
+traceLettre("g", offset = [0,-2], color="blue", linewidth=3)
+traceCarre(color="green", offset=[0,-2] )
+traceLettre("t", offset = [2,-2], color="blue", linewidth=3)
+traceCarre(color="green", offset=[2,-2] )
+plt.axis("equal")
+
+stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+
+print("-"*80)
+print(''' QUESTION 5.
+Répartissez-vous le travail dans le groupe TP afin de coder TOUTES les lettres de l'alphabet !
+(Il faudra donc vous "passer" le code de chaque lettre les uns aux autres, au fur et à mesure que vous les écrivez.)
+
+Attention : chaque lettre doit toujours tenir dans un carré unité (en dépassant un peu vers le haut ou le bas pour certaines lettres comme le "l", le "j", etc.).
+''')
+
+### Vérification (par exemple, pour vérifier le code du "b" une fois qu'il est défini):
+plt.figure()
+traceLettre("b", trace_controle=True, color="blue", linewidth=3)
+traceCarre(color="green")
+plt.axis("equal")
+
+stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
+
+
+print("-"*80)
+print(''' QUESTION 6 : tracé d'une phrase quelconque.
+
+Écrivez une fonction traceStr, avec le prototype défini ci-dessous, qui trace une chaîne de caractères quelconque (sans ponctuation) dans votre police.
+
+Consigne pour le OFFSET (décalage) : chaque caractère de la chaîne doit être tracé avec un décalage de +1 vers la droite par rapport au caractère précédent.
+''')
+
+# --------------------------------------------------------------------------------------
+# Fonction de tracé d'une chaîne de caractères quelconque (sans ponctuation)
+#
+# - chaine = chaîne de caractères qu'on souhaite tracer
+# - trace_controle et kwargs : même signification que pour la fonction traceBezier
+
+def traceStr(chaine, trace_controle=False, **kwargs):
+ TODO()
+
+
+### Vérification:
+
+phrase = "gattaca taca tagata" # version basique avec uniquement les lettre a,c,g,t
+# phrase = "portez ce vieux whisky au juge blond qui fume" # pangramme (phrase avec les 26 lettres de l'alphabet)
+
+plt.figure()
+traceStr(phrase, color="blue", linewidth=3)
+plt.axis("equal")
+
+
+
+stop_ici() # FINI !