diff --git a/bykes_V1/.vscode/settings.json b/bykes_V1/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..5a51a28efb30dd3f77571eb8dcfac4718a8b4d89
--- /dev/null
+++ b/bykes_V1/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "threads.h": "c"
+    }
+}
\ No newline at end of file
diff --git a/bykes_V1/Makefile b/bykes_V1/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a12c3ef709e7e6ae77a4b17a9350827397a2acdc
--- /dev/null
+++ b/bykes_V1/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/bykes_V1/bykes b/bykes_V1/bykes
new file mode 100755
index 0000000000000000000000000000000000000000..9f035935639bf51f30aa1418f357398ca1239910
Binary files /dev/null and b/bykes_V1/bykes differ
diff --git a/bykes_V1/main.c b/bykes_V1/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..359d1c6b791e3642962b6bc03bd7e5ed887e32c1
--- /dev/null
+++ b/bykes_V1/main.c
@@ -0,0 +1,334 @@
+#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 TRUCK_CAPACITE_MAX 4
+#define TRUCK_CAPACITE_TYP 2
+#define CITY_CAPACITY_MIN 2
+
+#define DEPOT  0
+
+#define USLEEP 1
+
+sem_t *sem_FreeSlot;
+sem_t *sem_BikeFree;
+pthread_mutex_t *mutex;
+pthread_barrier_t b;
+
+int personsFinished=0;
+
+struct person{
+    int num_thread;
+    int nb_travels;
+    int max_travels;
+    int i_terminals;
+    int nbterminals;
+    int nslots;
+};
+
+struct Truck{
+    int num_thread;
+    int n_bike;
+    int i_terminals;
+    int nbterminals;
+    int nslots;
+    int nbpersons;
+};
+
+struct city{
+    int nb_bikesParked;
+    int nb_P_waiting;
+};
+
+int rand_Dc();
+int rand_D();
+//void persons_PassiveMode(void *arg);
+void *trucks(void *arg);
+void *Persons(void *arg);
+struct city *terminals; //this table is the size of the number of terminals, each terminals 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 nbterminals = atoi(argv[1]);      //S 10 
+    int nbpersons = atoi(argv[2]);    //H 100
+    int nbtravels = atoi(argv[3]);      //M 10
+    int nbslots = atoi(argv[4]);        //N 10
+    nbterminals += 1;
+    srand(0);
+
+    
+    pthread_t *threadpersons = malloc(sizeof(pthread_t)*nbpersons);
+    pthread_t *threadTruck = malloc(sizeof(pthread_t));
+    terminals = calloc(nbterminals, sizeof(struct city));
+    struct person *persons = calloc(nbpersons, sizeof(struct person));
+    struct Truck *truck = malloc(sizeof(struct Truck));
+
+    for(int j = 0; j<nbterminals; j++){
+        terminals[j].nb_bikesParked = nbslots-2;
+        terminals[j].nb_P_waiting = 0;
+    }
+    terminals[DEPOT].nb_bikesParked = 0;
+
+    truck->i_terminals = 0;
+    truck->n_bike = TRUCK_CAPACITE_TYP;
+    truck->nslots = nbslots;
+    truck->num_thread = nbpersons;
+    truck->nbterminals = nbterminals;
+    truck->nbpersons = nbpersons;
+
+    sem_BikeFree = malloc(sizeof(sem_t)*nbterminals);
+    sem_FreeSlot = malloc(sizeof(sem_t)*nbterminals);
+    mutex = malloc(sizeof(pthread_mutex_t)*nbterminals);
+
+    for(int x =0; x<nbterminals; x++){
+        sem_init(&sem_BikeFree[x], 0, nbslots-2);//8);
+        sem_init(&sem_FreeSlot[x], 0, nbslots-(nbslots-2));//2);
+        pthread_mutex_init(&mutex[x], NULL); //mutex du truck
+    }
+
+    pthread_barrier_init(&b, NULL, nbpersons);
+
+    if(pthread_create(threadTruck, NULL, trucks, (void*)truck)!=0){
+        perror("thread creation error");
+        return EXIT_FAILURE;
+    }
+    for(int i=0; i<nbpersons; i++){
+        persons[i].max_travels = nbtravels;
+        persons[i].nslots = nbslots;
+        persons[i].nbterminals = nbterminals;
+        persons[i].num_thread = i;
+        persons[i].nb_travels = 0;
+        persons[i].i_terminals = (rand()%(persons[i].nbterminals - 1))+1;
+        if(pthread_create(&threadpersons[i], NULL, Persons, (void*)&persons[i])!=0){
+            perror("thread creation error");
+            return EXIT_FAILURE;
+        }
+    }
+
+    //pthread_barrier_wait(&b);
+    if(pthread_join(*threadTruck, NULL)){
+        perror("thread join error");
+        return EXIT_FAILURE;
+    }
+    //thread join
+    for(int i=0; i<nbpersons; i++){
+        if(pthread_join(threadpersons[i], NULL)){
+            perror("thread join error");
+            return EXIT_FAILURE;
+        }
+    }
+
+
+    printf("***************** CYCLING TERMINATED ***************\n");
+    int sum=0;
+    for(int i=1; i<nbterminals; i++){
+        printf("Terminal %d contains %d bikes\n", i, terminals[i].nb_bikesParked);
+        sum+=terminals[i].nb_bikesParked;
+    }
+    printf("total number of bikes in town: %d, in depot: %d, in truck: %d, total: %d\n", sum, terminals[DEPOT].nb_bikesParked, truck->n_bike, truck->n_bike+terminals[DEPOT].nb_bikesParked+sum);
+
+
+    //free the memory
+    for(int i=0; i<nbterminals; i++){
+        sem_destroy(&sem_BikeFree[i]);
+        sem_destroy(&sem_FreeSlot[i]);
+        pthread_mutex_destroy(&mutex[i]);
+    }
+    pthread_barrier_destroy(&b);
+    free(threadpersons);
+    free(threadTruck);
+    free(sem_BikeFree);
+    free(sem_FreeSlot);
+    free(mutex);
+    free(persons);
+    free(truck);
+    free(terminals);
+    return EXIT_SUCCESS;
+}
+
+void *Persons(void *arg){
+    struct person *hab = (struct person*)arg;
+    int j=0;
+    int val;
+    // inside a Mtravels loop for each persons
+    while(hab->nb_travels < hab->max_travels){
+        //waits for a bike in terminals i
+        //if(hab->i_terminals==4){
+        sem_getvalue(&sem_FreeSlot[hab->i_terminals],&val);
+        pthread_mutex_lock(&mutex[hab->i_terminals]);
+        printf("(GET) person %d starts from terminal %d (%d bykes, %d persons waiting, semslotsFree_val : %d)\n", hab->num_thread, hab->i_terminals, terminals[hab->i_terminals].nb_bikesParked, terminals[hab->i_terminals].nb_P_waiting, val);//terminals[hab->i_terminals].nb_P_waiting);
+        pthread_mutex_unlock(&mutex[hab->i_terminals]);
+        //}
+
+        if(terminals[hab->i_terminals].nb_bikesParked<=0){// && hab->i_terminals == 4){
+            printf("person %d is STUCK at terminal %d: rack empty : %d bikes\n", hab->num_thread, hab->i_terminals, terminals[hab->i_terminals].nb_bikesParked);
+        }
+
+        pthread_mutex_lock(&mutex[hab->i_terminals]);
+        terminals[hab->i_terminals].nb_P_waiting += 1;
+        pthread_mutex_unlock(&mutex[hab->i_terminals]);
+
+
+        sem_wait(&sem_BikeFree[hab->i_terminals]);
+        pthread_mutex_lock(&mutex[hab->i_terminals]);
+        terminals[hab->i_terminals].nb_P_waiting -= 1;
+        terminals[hab->i_terminals].nb_bikesParked -= 1; //critical section
+        //if(hab->i_terminals==4){
+        //printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_terminals);
+        //}
+        pthread_mutex_unlock(&mutex[hab->i_terminals]);
+        sem_post(&sem_FreeSlot[hab->i_terminals]);
+        //if(hab->i_terminals==4){
+        printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_terminals);
+        //}
+
+
+        //go to place j = rand()%nterminals and j != i
+        do{
+            j = (rand()%(hab->nbterminals - 1))+1;
+        }while(j==hab->i_terminals);
+#if USLEEP
+        usleep(rand_D());
+#endif
+
+        //waits for a parkinglot to be freed and deposit his bycycle
+        //if(j==4){
+        sem_getvalue(&sem_BikeFree[j],&val);
+        pthread_mutex_lock(&mutex[j]);
+        printf("(PUT) person %d arrives at terminal %d (%d bykes, %d persons waiting, semBikeFree_val : %d)\n", hab->num_thread, j, terminals[j].nb_bikesParked, terminals[j].nb_P_waiting, val);//terminals[j].nb_P_waiting);
+        pthread_mutex_unlock(&mutex[j]);
+        //}
+        
+
+        if(terminals[j].nb_bikesParked>=hab->nslots){//} && j == 4){
+            printf("person %d is STUCK at terminal %d: rack full : %d bikes\n", hab->num_thread, j, terminals[j].nb_bikesParked);
+        }
+
+        pthread_mutex_lock(&mutex[j]);
+        terminals[j].nb_P_waiting += 1;
+        pthread_mutex_unlock(&mutex[j]);
+
+
+        sem_wait(&sem_FreeSlot[j]);
+        pthread_mutex_lock(&mutex[j]);
+        //deposit his bycycle
+        terminals[j].nb_P_waiting -= 1;
+        terminals[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)
+#if USLEEP
+        usleep(rand_D());
+#endif
+        //changes his position from terminals i = j (j is the new terminals)
+        hab->i_terminals = j;
+        hab->nb_travels += 1;
+    }
+    printf("person %d stops\n", hab->num_thread);
+    pthread_mutex_lock(&mutex[hab->i_terminals]);
+    personsFinished += 1;
+    pthread_mutex_unlock(&mutex[hab->i_terminals]);
+    pthread_barrier_wait(&b);
+    //printf("machin bidule a passé la barriere !!!! : %d, tot_travels = %d\n", hab->num_thread, hab->nb_travels);
+
+    return NULL;
+}
+
+void *trucks(void *arg){
+    struct Truck *truck = (struct Truck*)arg;
+    int tmp_nbBikes;
+    
+    while(personsFinished < truck->nbpersons){
+        //1 : for each terminals from 1 to S (0 is the depot)
+        for(int i=1; i<truck->nbterminals; i++){
+            //spreads the bikes evenly
+            //too many bikes in this terminals
+            tmp_nbBikes = truck->n_bike;
+            if(terminals[i].nb_bikesParked > (truck->nslots-2) && truck->n_bike < TRUCK_CAPACITE_MAX){
+                while(terminals[i].nb_bikesParked > (truck->nslots-2) && truck->n_bike < TRUCK_CAPACITE_MAX){
+                    sem_wait(&sem_BikeFree[i]);
+                    pthread_mutex_lock(&mutex[i]);
+                    truck->n_bike += 1;
+                    terminals[i].nb_bikesParked -= 1;
+                    pthread_mutex_unlock(&mutex[i]);
+                    sem_post(&sem_FreeSlot[i]);
+                }
+
+                pthread_mutex_lock(&mutex[i]);
+                printf("truck removes %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", truck->n_bike-tmp_nbBikes, i, terminals[i].nb_bikesParked, terminals[i].nb_P_waiting, truck->n_bike);
+                pthread_mutex_unlock(&mutex[i]);
+            }
+            // not enough bikes in this terminals
+            // until he gets at least 2 bikes (or the truck is empty)
+            else if(terminals[i].nb_bikesParked < CITY_CAPACITY_MIN && truck->n_bike > 0){
+                tmp_nbBikes = truck->n_bike;
+                while(terminals[i].nb_bikesParked < CITY_CAPACITY_MIN && truck->n_bike > 0){
+                    sem_wait(&sem_FreeSlot[i]);
+                    pthread_mutex_lock(&mutex[i]);
+                    truck->n_bike -= 1;
+                    terminals[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-truck->n_bike, i, terminals[i].nb_bikesParked, terminals[i].nb_P_waiting, truck->n_bike);
+                pthread_mutex_unlock(&mutex[i]);
+            }
+        }
+        //2: goes to the depot to rebalance the truck's content to 2 bycycles
+        tmp_nbBikes = truck->n_bike;
+        if(truck->n_bike < TRUCK_CAPACITE_TYP){
+            if(terminals[DEPOT].nb_bikesParked > 0){
+                while(truck->n_bike < TRUCK_CAPACITE_TYP && terminals[DEPOT].nb_bikesParked > 0){
+                    truck->n_bike += 1;
+                    pthread_mutex_lock(&mutex[DEPOT]);
+                    terminals[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", truck->n_bike-tmp_nbBikes, DEPOT, terminals[DEPOT].nb_bikesParked, terminals[DEPOT].nb_P_waiting, truck->n_bike);
+                pthread_mutex_unlock(&mutex[DEPOT]);
+            }
+        }
+        else if (truck->n_bike > TRUCK_CAPACITE_TYP){
+            while(truck->n_bike > TRUCK_CAPACITE_TYP){
+                truck->n_bike -= 1;
+                pthread_mutex_lock(&mutex[DEPOT]);
+                terminals[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-truck->n_bike, DEPOT, terminals[DEPOT].nb_bikesParked, terminals[DEPOT].nb_P_waiting, truck->n_bike);
+            pthread_mutex_unlock(&mutex[DEPOT]);
+        }
+        //3: pause betweem 100us up to 199us
+#if USLEEP
+        usleep(rand_Dc());
+#endif
+        //printf("TRUCK new loop, person's threads finished: %d\n", personsFinished);
+    }
+    printf("TRUCK end loop\n");
+    return NULL;
+}
+
+int rand_D(){
+    return (rand()%999)+1000;
+}
+
+int rand_Dc(){
+    return (rand()%99)+100;
+}
\ No newline at end of file