diff --git a/TP3_rapport_bykes.txt b/TP3_rapport_bykes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..07531e4b451fb5647b28b4d7d4d50e8ad64c5d62
--- /dev/null
+++ b/TP3_rapport_bykes.txt
@@ -0,0 +1,99 @@
+TP3 : Gestion d’un parc de vélos
+
+Nom : El Ajeri				     Nom : Davila Prado 
+Prénom : Khalil Mokhtar    Prénom : Lou
+		
+Groupe : 14
+
+--------------------------------------------------
+Statut du projet
+--------------------------------------------------
+Projet fonctionnel.
+
+- Le programme gère correctement la concurrence entre threads à l’aide de mutex et sémaphores.
+- Tous les trajets sont effectués sans blocage (tests répétés).
+- Le nombre total de vélos reste constant à la fin de la simulation : S * (N - 2) + 2.
+- Chaque site possède entre 0 et N vélos à la fin.
+- Les affichages reflètent bien les prises, dépôts, attentes et les actions du camion.
+- La logique du dépôt et du rééquilibrage est bien gérée.
+- Les délais usleep ont été désactivés pour les tests de performance/stabilité.
+- On a eu un bug avec un grand nombre d'habitants donc à cause de la concurrence au niveau de la gestion des vélos
+  qu'on a pu régler par la suite.
+
+--------------------------------------------------
+Algorithme de gestion des habitants
+--------------------------------------------------
+Chaque habitant est un thread. Il effectue M trajets :
+
+1. Il attend passivement qu’un vélo soit disponible sur son site actuel (sémaphore velos), en incrémentant personnes_attente.
+2. Une fois le vélo obtenu, il décrémente le compteur local velos_dispo du site, puis libère une borne (bornes).
+3. Il choisit un autre site (aléatoirement) et attend passivement qu’une borne soit libre (sémaphore bornes) pour y déposer le vélo.
+4. Il incrémente alors velos_dispo de ce site, poste sur le sémaphore velos, et libère ainsi le vélo pour un autre utilisateur.
+
+Toutes les modifications des variables critiques (velos_dispo, personnes_attente) sont protégées par un mutex par site.
+
+Un mutex global (mutex_trajets) est utilisé pour suivre le nombre total de trajets réalisés par tous les habitants.
+
+
+--------------------------------------------------
+Gestion de la concurrence
+--------------------------------------------------
+- Les accès partagés (velos_dispo, bornes, velos, personnes_attente, variables utilisées dans les printf) sont protégés par des mutex individuels.
+- Les accès globaux (trajets_effectues, velos_depot) sont protégés par des mutex globaux.
+- Les sémaphores assurent des attentes passives :
+  - velos pour prendre un vélo.
+  - bornes pour déposer un vélo.
+- Les sections critiques sont réduites au strict minimum.
+- Chaque affichage est fait après la section critique pour limiter la contention.
+
+--------------------------------------------------
+Fonctions codées:
+--------------------------------------------------
+
+void *habitant(void *arg)
+---------------------------------
+Cette fonction représente le comportement d’un habitant modélisé par un thread.
+- Chaque habitant commence à un site choisi aléatoirement.
+- Il effectue TRAJETS fois la séquence de prise et dépôt de vélo entre deux sites différents.
+- Il utilise les sémaphores pour attendre passivement la disponibilité d’un vélo ou d’une borne.
+- Les compteurs internes (velos_dispo, personnes_attente) sont mis à jour dans des sections critiques protégées par mutex.
+- Le compteur global trajets_effectues est également protégé par un mutex.
+- À chaque dépôt de vélo, le site actuel est mis à jour.
+- Les affichages indiquent les actions de l’habitant et les situations d’attente.
+
+void *gestion_camion(void *arg)
+---------------------------------
+Cette fonction modélise la camionnette de maintenance qui équilibre les vélos entre les sites.
+- Elle tourne tant que tous les trajets ne sont pas effectués (condition vérifiée avec mutex_trajets).
+- Pour chaque site :
+    a. Si trop de vélos : enlève jusqu’à CAMION_CAPACITE - velos_camion vélos pour atteindre N - 2.
+    b. Si trop peu de vélos : ajoute jusqu’à 2 vélos selon disponibilité du camion et bornes.
+- Après la boucle des sites :
+    a. Dépôt des vélos excédentaires si velos_camion > 2.
+    b. Recharge depuis le dépôt si velos_camion < 2.
+- L’accès au dépôt est protégé par mutex_velos_depot.
+- Le comportement respecte la capacité max du camion (4 vélos).
+
+int main(int argc, char *argv[])
+---------------------------------
+Fonction principale qui :
+- Récupère les paramètres SITES, HABITANTS, TRAJETS et BORNES depuis la ligne de commande.
+- Initialise les sémaphores et mutex de chaque site.
+- Lance les threads pour chaque habitant et un thread pour le camion.
+- Attend la fin de tous les threads avec pthread_join.
+- Affiche les vélos par site et la vérification du total global à la fin de l’exécution.
+- Détruit les sémaphores et mutex à la fin.
+
+--------------------------------------------------
+Bugs résiduels
+--------------------------------------------------
+
+Lorsqu'un trop grand nombre d'habitants est spécifié au lancement du programme, le programme finit par se bloquer après un certain temps d'exécution.
+Nous pensons que ceci est dû à un trop grand nombre de threads concurrents crées par rapport à la capacité de la machine.
+Il faudrait probablement limiter le nombre de threads créés simultanement pour éviter ce genre de problème.
+
+--------------------------------------------------
+Conclusion
+--------------------------------------------------
+
+Le programme respecte toutes les exigences du TP : cohérence des vélos, absence de blocage, affichages pertinents, gestion propre de la concurrence.
\ No newline at end of file
diff --git a/byke_simulation b/byke_simulation
new file mode 100755
index 0000000000000000000000000000000000000000..d298e633a2e0004481d7f67a985035fc5c59da0c
Binary files /dev/null and b/byke_simulation differ
diff --git a/tp b/tp
deleted file mode 100755
index 11586c6855566ccba201f878ee9431e295a73610..0000000000000000000000000000000000000000
Binary files a/tp and /dev/null differ
diff --git a/tp.c b/tp.c
index b37678fe2e3f4cc517124f9ab91ac389c7f7aebc..70e4f8f2755b0c859760836c03bdadb8fb845a0c 100644
--- a/tp.c
+++ b/tp.c
@@ -1,3 +1,6 @@
+/*Authors: Lou Davila Prado, Khalil El Ajeri
+  Groupe: 14*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
@@ -14,7 +17,7 @@ typedef struct
     int velos_dispo;
     int personnes_attente;
     pthread_mutex_t mutex;
-} Site;
+}Site;
 
 int SITES,HABITANTS,TRAJETS,BORNES;
 Site *sites;
@@ -36,38 +39,46 @@ void *habitant(void *arg)
         {
             site_suivant = rand()%SITES;
         } 
-        while (site_suivant == site_actuel);
+        while (site_actuel == site_suivant);
 
         pthread_mutex_lock(&sites[site_actuel].mutex);
         sites[site_actuel].personnes_attente++;
+        int velos = sites[site_actuel].velos_dispo;
+        int attente = sites[site_actuel].personnes_attente;
         pthread_mutex_unlock(&sites[site_actuel].mutex);
         
-        printf("(GET) Habitant %d attend un vélo au site %d\n",habitant_id,site_actuel);
+        printf("(GET) Habitant %d attend un vélo au site %d (%d vélos, %d personnes en attente)\n", habitant_id, site_actuel, velos, attente);
         sem_wait(&sites[site_actuel].velos);
         
         pthread_mutex_lock(&sites[site_actuel].mutex);
         sites[site_actuel].velos_dispo--;
         sites[site_actuel].personnes_attente--;
+        velos = sites[site_actuel].velos_dispo;
+        attente = sites[site_actuel].personnes_attente;
         pthread_mutex_unlock(&sites[site_actuel].mutex);
         
-        printf("(GET) Habitant %d prend un vélo au site %d\n",habitant_id,site_actuel);
+        printf("(GET) Habitant %d prend un vélo au site %d (%d vélos, %d personnes en attente)\n", habitant_id, site_actuel, velos, attente);
         sem_post(&sites[site_actuel].bornes);
         //usleep((rand()%1000+1000));
     
         pthread_mutex_lock(&sites[site_suivant].mutex);
         sites[site_suivant].personnes_attente++;
+        velos = sites[site_suivant].velos_dispo;
+        attente = sites[site_suivant].personnes_attente;
         pthread_mutex_unlock(&sites[site_suivant].mutex);
         
-        printf("(PUT) Habitant %d attend d'avoir accès à une borne du site %d\n",habitant_id,site_suivant);
+        printf("(PUT) Habitant %d attend d'avoir accès à une borne du site %d (%d vélos, %d personnes en attente)\n", habitant_id, site_suivant, velos, attente);
         sem_wait(&sites[site_suivant].bornes);
         
         pthread_mutex_lock(&sites[site_suivant].mutex);
         sites[site_suivant].velos_dispo++;
         sites[site_suivant].personnes_attente--;
+        velos = sites[site_suivant].velos_dispo;
+        attente = sites[site_suivant].personnes_attente;
         pthread_mutex_unlock(&sites[site_suivant].mutex);
         
         sem_post(&sites[site_suivant].velos);
-        printf("(PUT) Habitant %d dépose un vélo au site %d\n",habitant_id,site_suivant);
+        printf("(PUT) Habitant %d dépose un vélo au site %d (%d vélos, %d personnes en attente)\n", habitant_id, site_suivant, velos, attente);
         //usleep((rand()%1000+1000));
         
         site_actuel = site_suivant;
@@ -96,6 +107,8 @@ void *gestion_camion(void *arg)
         for (int i = 0; i < SITES; i++) 
         {
             pthread_mutex_lock(&sites[i].mutex);
+            int velos = sites[i].velos_dispo;
+            int attente = sites[i].personnes_attente;
             
             if (CAMION_CAPACITE > velos_camion && sites[i].velos_dispo > BORNES-2) 
             {
@@ -110,15 +123,23 @@ void *gestion_camion(void *arg)
                     aRetirer = sites[i].velos_dispo-1;
                 }
                 
+                pthread_mutex_unlock(&sites[i].mutex);
+                
                 for (int j = 0; j < aRetirer; j++) 
                 {
                     sem_wait(&sites[i].velos);
+                    
+                    pthread_mutex_lock(&sites[i].mutex);
                     sites[i].velos_dispo--;
+                    velos = sites[i].velos_dispo;
+                    attente = sites[i].personnes_attente;
+                    pthread_mutex_unlock(&sites[i].mutex);
+                    
                     velos_camion++;
                     sem_post(&sites[i].bornes);
                 }
                 
-                printf("Camion prend des vélos au site %d (Vélos dans camion: %d)\n",i,velos_camion);
+                printf("Camion prend %d vélos au site %d (%d vélos, %d personnes en attente) (Vélos dans le camion: %d)\n", aRetirer, i, velos, attente, velos_camion);
             } 
             else if (sites[i].velos_dispo < 2 && velos_camion > 0) 
             {
@@ -134,18 +155,29 @@ void *gestion_camion(void *arg)
                     aAjouter = spotsDisponibles;
                 }
                 
+                pthread_mutex_unlock(&sites[i].mutex);
+                
                 for (int j = 0; j < aAjouter; j++) 
                 {
                     sem_wait(&sites[i].bornes);
+                    
+                    pthread_mutex_lock(&sites[i].mutex);
                     sites[i].velos_dispo++;
+                    velos = sites[i].velos_dispo;
+                    attente = sites[i].personnes_attente;
+                    pthread_mutex_unlock(&sites[i].mutex);
+                    
                     velos_camion--;
                     sem_post(&sites[i].velos);
                 }
                 
-                printf("Camion dépose des vélos au site %d (Vélos dans camion: %d)\n",i,velos_camion);
+                printf("Camion dépose %d vélos au site %d (%d vélos, %d personnes en attente) (Vélos dans le camion: %d)\n", aAjouter, i, velos, attente, velos_camion);
+            }
+            else 
+            {
+                pthread_mutex_unlock(&sites[i].mutex);
             }
             
-            pthread_mutex_unlock(&sites[i].mutex);
             //usleep((rand()%100+100));
         }
         
@@ -154,7 +186,7 @@ void *gestion_camion(void *arg)
         {
             velos_depot+= (velos_camion-2);
             velos_camion = 2;
-            printf("Camion vide les vélos au dépôt (Vélos en dépôt: %d)\n",velos_depot);
+            printf("Camion vide les vélos au dépôt (Vélos en dépôt: %d)\n", velos_depot);
         } 
         else if (velos_depot > 0 && velos_camion < 2) 
         {
@@ -165,11 +197,11 @@ void *gestion_camion(void *arg)
             }
             velos_depot-= requis;
             velos_camion+= requis;
-            printf("Camion prend des vélos du dépôt (Vélos en dépôt: %d)\n",velos_depot);
+            printf("Camion prend des vélos au dépôt (Vélos en dépôt: %d)\n", velos_depot);
         }
         pthread_mutex_unlock(&mutex_velos_depot);
         
-        printf("Camion fait un tour, vélos restants: %d, vélos en dépôt: %d\n",velos_camion,velos_depot);
+        printf("Camion fait un tour, Vélos restants: %d, vélos en dépôt: %d\n", velos_camion, velos_depot);
         //usleep((rand()%100+100));
     }
     return NULL;
@@ -179,23 +211,31 @@ int main(int argc, char *argv[])
 {
     if (argc != 5) 
     {
-        fprintf(stderr, "Usage: %s <SITES> <HABITANTS> <TRAJETS> <BORNES>\n",argv[0]);
+        fprintf(stderr, "Usage: %s <SITES> <HABITANTS> <TRAJETS> <BORNES>\n", argv[0]);
         return 1;
     }
     SITES = atoi(argv[1]);
     HABITANTS = atoi(argv[2]);
     TRAJETS = atoi(argv[3]);
     BORNES = atoi(argv[4]);
+
+    if (SITES <= 2 || HABITANTS <= 2 || TRAJETS <= 0 || BORNES <= 4)
+    {
+        printf("Les contraintes suivantes doivent être respectées:\n");
+        printf("SITES > 2, HABITANTS > 2, TRAJETS > 0, BORNES > 4\n");
+        exit(EXIT_FAILURE);
+    }
+    
     
     srand(time(NULL));
     sites = malloc(SITES * sizeof(Site));
     
-    pthread_t habitants[HABITANTS],camion;
+    pthread_t habitants[HABITANTS], camion;
     
     for (int i = 0; i < SITES; i++) 
     {
-        sem_init(&sites[i].velos,0,BORNES-2);
-        sem_init(&sites[i].bornes,0,2);
+        sem_init(&sites[i].velos, 0, BORNES-2);
+        sem_init(&sites[i].bornes, 0, 2);
         pthread_mutex_init(&sites[i].mutex, NULL);
         sites[i].velos_dispo = BORNES-2;
         sites[i].personnes_attente = 0;
@@ -204,24 +244,24 @@ int main(int argc, char *argv[])
     {
         int *habitant_id = malloc(sizeof(int));
         *habitant_id = i;
-        pthread_create(&habitants[i],NULL,habitant,habitant_id);
+        pthread_create(&habitants[i], NULL, habitant, habitant_id);
     }
-    pthread_create(&camion,NULL,gestion_camion,NULL);
+    pthread_create(&camion, NULL, gestion_camion, NULL);
     
     for (int i = 0; i < HABITANTS; i++) 
     {
-        pthread_join(habitants[i],NULL);
+        pthread_join(habitants[i], NULL);
     }
-    pthread_join(camion,NULL);
+    pthread_join(camion, NULL);
     
     int total_velos = velos_depot;
     for (int i = 0; i < SITES; i++) 
     {
-        total_velos+= sites[i].velos_dispo;
-        printf("Site %d contains %d bykes\n",i,sites[i].velos_dispo);
+        total_velos += sites[i].velos_dispo;
+        printf("Site %d contient %d vélos\n", i, sites[i].velos_dispo);
     }
-    total_velos+= 2;
-    printf("Nombre total de vélos à la fin : %d (doit être %d)\n",total_velos,SITES*(BORNES-2)+2);
+    total_velos += 2;
+    printf("Nombre total de vélos à la fin : %d (doit être %d)\n", total_velos, SITES*(BORNES-2)+2);
     printf("Simulation terminée.\n");
     
     for (int i = 0; i < SITES; i++)