diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..15309787ada476c0907431c9af91acf70a3c95bd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.o
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..a2c02db40ee2de14191962dea6ca10e823c0cc93
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+    "files.associations": {
+        "stdlib.h": "c",
+        "threads.h": "c",
+        "unistd.h": "c"
+    }
+}
\ No newline at end of file
diff --git a/G17_bykes/.vscode/settings.json b/G17_bykes/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..5a51a28efb30dd3f77571eb8dcfac4718a8b4d89
--- /dev/null
+++ b/G17_bykes/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "threads.h": "c"
+    }
+}
\ No newline at end of file
diff --git a/G17_bykes/Makefile b/G17_bykes/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a12c3ef709e7e6ae77a4b17a9350827397a2acdc
--- /dev/null
+++ b/G17_bykes/Makefile
@@ -0,0 +1,14 @@
+CC:=gcc
+CFLAGS:=-Wall -Wextra -pedantic -g -fsanitize=address,undefined -fsanitize-recover=address
+LDFLAGS:=-lpthread -lm
+EXEC:=bykes
+ARGS:=10 100 10 10
+
+$(EXEC): main.c
+	$(CC) $(CFLAGS) $^ -o $(EXEC) $(LDFLAGS)
+
+clean:
+	rm -rf *.o $(EXEC)
+
+run: $(EXEC)
+	./$< $(ARGS)
diff --git a/G17_bykes/bykes b/G17_bykes/bykes
new file mode 100755
index 0000000000000000000000000000000000000000..1fafd7cc7285dadb5a8a7f53b320f9d91b29224a
Binary files /dev/null and b/G17_bykes/bykes differ
diff --git a/G17_bykes/main.c b/G17_bykes/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..72610caf0d9895c3c307a139440ab0e7417e4fdf
--- /dev/null
+++ b/G17_bykes/main.c
@@ -0,0 +1,329 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <time.h>
+#include <semaphore.h>
+
+#define CAMION_CAPACITE_MAX 4
+#define CAMION_CAPACITE_TYP 2
+#define SITE_CAPACITE_MIN 2
+
+//#define NUM_THREAD 5
+
+#define DEPOT  0
+
+sem_t *sem_BorneFree;
+sem_t *sem_BikeFree;
+pthread_mutex_t *mutex;
+pthread_barrier_t b;
+
+bool end = false;
+
+struct habitant{
+    int num_thread;
+    int nb_trajet;
+    int max_trajets;
+    int i_site;
+    int nbSites;
+    int nbornes;
+};
+
+struct camionette{
+    int num_thread;
+    int n_Velo;
+    int i_site;
+    int nbSites;
+    int nbornes;
+};
+
+struct site{
+    int nb_bikesParked;
+    int nb_P_waiting;
+};
+
+int rand_Dc();
+int rand_D();
+//void habitants_PassiveMode(void *arg);
+void *Camion(void *arg);
+void *habitants(void *arg);
+struct site *sites; //this table is the size of the number of sites, each sites has NParkinglot and each numbers represents a free parkinglot
+
+
+int main(int argc, char **argv){
+    if (argc < 5 || argc > 5){
+        perror("erreur d'arguments d'entrée\n");
+        return EXIT_FAILURE;
+    }
+    int nbSites = atoi(argv[1]);    //S 10 
+    int nbHabs = atoi(argv[2]);     //H 100
+    int nbTrajets = atoi(argv[3]);  //M 10
+    int nbBorne = atoi(argv[4]);    //N 10
+    srand(0);
+
+    
+    pthread_t *threadHabs = malloc(sizeof(pthread_t)*nbHabs);
+    pthread_t *threadCam = malloc(sizeof(pthread_t));
+    sites = calloc(nbSites, sizeof(struct site));
+    struct habitant *habs = calloc(nbHabs, sizeof(struct habitant));
+    struct camionette *camion = malloc(sizeof(struct camionette));
+
+    for(int j = 0; j<nbSites; j++){
+        sites[j].nb_bikesParked = nbBorne-2;
+        sites[j].nb_P_waiting = 0;
+    }
+    sites[0].nb_bikesParked = 0; //depot avec 0 velos au depart
+
+    camion->i_site = 0;
+    camion->n_Velo = CAMION_CAPACITE_TYP;
+    camion->nbornes = nbBorne;
+    camion->num_thread = nbHabs;
+    camion->nbSites = nbSites;
+
+
+    sem_BikeFree = malloc(sizeof(sem_t)*nbSites);
+    sem_BorneFree = malloc(sizeof(sem_t)*nbSites);
+    //mutex = malloc(sizeof(pthread_mutex_t)*(nbHabs+1));
+    mutex = malloc(sizeof(pthread_mutex_t)*nbSites);
+
+    for(int x =0; x<nbSites; x++){
+        sem_init(&sem_BikeFree[x], 0, 8);
+        sem_init(&sem_BorneFree[x], 0, 2);
+        pthread_mutex_init(&mutex[x], NULL); //mutex du camion
+    }
+
+    pthread_barrier_init(&b, NULL, nbHabs);
+
+    if(pthread_create(threadCam, NULL, Camion, (void*)camion)!=0){
+        perror("thread creation error");
+        return EXIT_FAILURE;
+    }
+    for(int i=0; i<nbHabs; i++){
+        habs[i].max_trajets = nbTrajets;
+        habs[i].nbornes = nbBorne;
+        habs[i].nbSites = nbSites;
+        habs[i].num_thread = i;
+        habs[i].nb_trajet = 0;
+        habs[i].i_site = (rand()%(habs[i].nbSites - 1))+1;
+        pthread_mutex_init(&mutex[i], NULL); //mutex par habitants
+        if(pthread_create(&threadHabs[i], NULL, habitants, (void*)&habs[i])!=0){
+            perror("thread creation error");
+            return EXIT_FAILURE;
+        }
+    }
+
+    //pthread_barrier_wait(&b);
+    if(pthread_join(*threadCam, NULL)){ // va retourner un truc après
+        perror("thread join error");
+        return EXIT_FAILURE;
+    }
+    //thread join
+    for(int i=0; i<nbHabs; i++){
+        if(pthread_join(threadHabs[i], NULL)){ //va retourner un truc après
+            perror("thread join error");
+            return EXIT_FAILURE;
+        }
+    }
+
+    //free the memory
+    for(int i=0; i<nbSites; i++){
+        sem_destroy(&sem_BikeFree[i]);
+        sem_destroy(&sem_BorneFree[i]);
+    }
+    for(int i=0; i<nbHabs+1; i++){
+        pthread_mutex_destroy(&mutex[i]);
+    }
+    pthread_barrier_destroy(&b);
+    free(threadHabs);
+    free(threadCam);
+    free(sem_BikeFree);
+    free(sem_BorneFree);
+    free(mutex);
+    int sum=0;
+    for(int i=0; i<nbSites; i++){
+        sum+=sites[i].nb_bikesParked;
+    }
+    printf("nb de velos en fin de programme %d\n", sum);
+
+    free(habs);
+    free(camion);
+    free(sites);
+
+    //srand(time(NULL));
+    //nb sites, nb habs, nb de voyaegs par habitants, nb de bornes par sites
+    return EXIT_SUCCESS;
+}
+
+void *habitants(void *arg){
+    struct habitant *hab = (struct habitant*)arg;
+    int j=0;
+    int val;
+    // inside a Mtrajets loop for each habitants
+    while(hab->nb_trajet < hab->max_trajets){
+        //waits for a bike in site i
+        //if(hab->i_site==4){
+        pthread_mutex_lock(&mutex[hab->i_site]);
+        printf("(GET) person %d starts from terminal %d (%d bykes, %d persons waiting, semVal : %d)\n", hab->num_thread, hab->i_site, sites[hab->i_site].nb_bikesParked, sites[j].nb_P_waiting, val);//sites[hab->i_site].nb_P_waiting);
+        pthread_mutex_unlock(&mutex[hab->i_site]);
+        //}
+
+        sem_getvalue(&sem_BorneFree[hab->i_site],&val);
+        if(sites[hab->i_site].nb_bikesParked<=0){// && hab->i_site == 4){
+            printf("person %d is STUCK at terminal %d: rack empty with : %d bikes\n", hab->num_thread, hab->i_site, sites[hab->i_site].nb_bikesParked);
+        }
+
+        pthread_mutex_lock(&mutex[hab->i_site]);
+        sites[hab->i_site].nb_P_waiting += 1;
+        pthread_mutex_unlock(&mutex[hab->i_site]);
+
+
+        sem_wait(&sem_BikeFree[hab->i_site]);
+        pthread_mutex_lock(&mutex[hab->i_site]);
+        sites[hab->i_site].nb_P_waiting -= 1;
+        sites[hab->i_site].nb_bikesParked -= 1; //critical section
+        //if(hab->i_site==4){
+        //printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_site);
+        //}
+        pthread_mutex_unlock(&mutex[hab->i_site]);
+        sem_post(&sem_BorneFree[hab->i_site]);
+        //if(hab->i_site==4){
+        printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_site);
+        //}
+
+
+        //go to place j = rand()%nsites and j != i
+        do{
+            j = (rand()%(hab->nbSites - 1))+1;
+        }while(j==hab->i_site);
+        usleep(rand_D());
+
+
+        //waits for a parkinglot to be freed and deposit his bycycle
+        //if(j==4){
+        pthread_mutex_lock(&mutex[j]);
+        printf("(PUT) person %d arrives at terminal %d (%d bykes, %d persons waiting, semVal : %d)\n", hab->num_thread, j, sites[j].nb_bikesParked, sites[j].nb_P_waiting, val);//sites[j].nb_P_waiting);
+        pthread_mutex_unlock(&mutex[j]);
+        //}
+        
+        sem_getvalue(&sem_BikeFree[j],&val);
+        if(sites[j].nb_bikesParked>=hab->nbornes){//} && j == 4){
+            printf("person %d is STUCK at terminal %d: rack full : %d bikes\n", hab->num_thread, j, sites[j].nb_bikesParked);
+        }
+
+        pthread_mutex_lock(&mutex[j]);
+        sites[j].nb_P_waiting += 1;
+        pthread_mutex_unlock(&mutex[j]);
+
+
+        sem_wait(&sem_BorneFree[j]);
+        pthread_mutex_lock(&mutex[j]);
+        //deposit his bycycle
+        sites[j].nb_P_waiting -= 1;
+        sites[j].nb_bikesParked += 1; //critical section 
+        pthread_mutex_unlock(&mutex[j]);
+        sem_post(&sem_BikeFree[j]);
+        //if(j==4){
+        printf("person %d leaves terminal %d by foot\n", hab->num_thread, j);
+        //}
+
+        //does whatever he has to do for a D delay time (waits for rand() 1000->1999us)
+        usleep(rand_D());
+        //changes his position from site i = j (j is the new site)
+        hab->i_site = j;
+        hab->nb_trajet += 1;
+    }
+    //printf("machin bidule finished : %d, tot_trajets = %d\n", hab->num_thread, hab->nb_trajet);
+
+    pthread_barrier_wait(&b);
+    //printf("machin bidule a passé la barriere !!!! : %d, tot_trajets = %d\n", hab->num_thread, hab->nb_trajet);
+
+    pthread_mutex_lock(&mutex[hab->i_site]);
+    end = true;
+    pthread_mutex_unlock(&mutex[hab->i_site]);
+    return NULL;
+}
+
+void *Camion(void *arg){
+    struct camionette *camion = (struct camionette*)arg;
+    int tmp_nbBikes;
+    
+    while(!end){
+        //1 : for each sites from 1 to S (0 is the depot)
+        for(int i=1; i<camion->nbSites; i++){
+            //spreads the bikes evenly
+            //too many bikes in this site
+            tmp_nbBikes = camion->n_Velo;
+            if(sites[i].nb_bikesParked > (camion->nbornes-2) && camion->n_Velo < CAMION_CAPACITE_MAX){
+                while(sites[i].nb_bikesParked > (camion->nbornes-2) && camion->n_Velo < CAMION_CAPACITE_MAX){
+                    sem_wait(&sem_BikeFree[i]);
+                    pthread_mutex_lock(&mutex[i]);
+                    camion->n_Velo += 1;
+                    sites[i].nb_bikesParked -= 1;
+                    pthread_mutex_unlock(&mutex[i]);
+                    sem_post(&sem_BorneFree[i]);
+                }
+
+                pthread_mutex_lock(&mutex[i]);
+                printf("truck removes %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", camion->n_Velo-tmp_nbBikes, i, sites[i].nb_bikesParked, sites[i].nb_P_waiting, camion->n_Velo);
+                pthread_mutex_unlock(&mutex[i]);
+            }
+            // not enough bikes in this site
+            // until he gets at least 2 bikes (or the camion is empty)
+            else if(sites[i].nb_bikesParked < SITE_CAPACITE_MIN && camion->n_Velo > 0){
+                tmp_nbBikes = camion->n_Velo;
+                while(sites[i].nb_bikesParked < SITE_CAPACITE_MIN && camion->n_Velo > 0){
+                    sem_wait(&sem_BorneFree[i]);
+                    pthread_mutex_lock(&mutex[i]);
+                    camion->n_Velo -= 1;
+                    sites[i].nb_bikesParked += 1;
+                    pthread_mutex_unlock(&mutex[i]);
+                    sem_post(&sem_BikeFree[i]);
+                }
+
+                pthread_mutex_lock(&mutex[i]);
+                printf("truck adds %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", tmp_nbBikes-camion->n_Velo, i, sites[i].nb_bikesParked, sites[i].nb_P_waiting, camion->n_Velo);
+                pthread_mutex_unlock(&mutex[i]);
+            }
+        }
+        //2: goes to the depot to rebalance the truck's content to 2 bycycles
+        tmp_nbBikes = camion->n_Velo;
+        if(camion->n_Velo < CAMION_CAPACITE_TYP){
+            if(sites[DEPOT].nb_bikesParked > 0){
+                while(camion->n_Velo < CAMION_CAPACITE_TYP && sites[DEPOT].nb_bikesParked > 0){
+                    camion->n_Velo += 1;
+                    pthread_mutex_lock(&mutex[DEPOT]);
+                    sites[DEPOT].nb_bikesParked -= 1;
+                    pthread_mutex_unlock(&mutex[DEPOT]);
+                }
+                pthread_mutex_lock(&mutex[DEPOT]);
+                printf("(DEPOT) truck gets %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", camion->n_Velo-tmp_nbBikes, DEPOT, sites[DEPOT].nb_bikesParked, sites[DEPOT].nb_P_waiting, camion->n_Velo);
+                pthread_mutex_unlock(&mutex[DEPOT]);
+            }
+        }
+        else if (camion->n_Velo > CAMION_CAPACITE_TYP){
+            while(camion->n_Velo > CAMION_CAPACITE_TYP){
+                camion->n_Velo -= 1;
+                pthread_mutex_lock(&mutex[DEPOT]);
+                sites[DEPOT].nb_bikesParked += 1;
+                pthread_mutex_unlock(&mutex[DEPOT]);
+            }
+            pthread_mutex_lock(&mutex[DEPOT]);
+            printf("(DEPOT) truck deposit %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", tmp_nbBikes-camion->n_Velo, DEPOT, sites[DEPOT].nb_bikesParked, sites[DEPOT].nb_P_waiting, camion->n_Velo);
+            pthread_mutex_unlock(&mutex[DEPOT]);
+        }
+        //3: pause betweem 100us up to 199us
+        usleep(rand_Dc());
+    }
+    printf("end camion\n");
+    return NULL;
+}
+
+int rand_D(){
+    return (rand()%999)+1000;
+}
+
+int rand_Dc(){
+    return (rand()%99)+100;
+}
\ No newline at end of file