diff --git a/ex01/ex01.c b/ex01/ex01.c
index 899e4dbb27b1b82dbd3c23506b0fa4df0a61c9cf..e06c6246fefb8e0c415e15515c106afb458a4571 100644
--- a/ex01/ex01.c
+++ b/ex01/ex01.c
@@ -6,8 +6,192 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include <stdbool.h>
+#include <assert.h>
+
+/// @brief Element of a sorted list, contains data and the next element (linked list)
+typedef struct _element
+{
+    int data;              // data of element
+    struct _element *next; // the next element
+} element;
+
+typedef element *sorted_list; // alias for the sorted_list
+
+// --- functions ---
+
+/// @brief Check if a sorted_list is empty
+/// @param li sorted_list checked
+/// @return True if the sorted_list is empty, otherwise False
+bool sorted_list_is_empty(sorted_list li)
+{
+    return li == NULL;
+}
+
+/// @brief Create a new sorted list
+/// @return the new sorted_list
+sorted_list sorted_list_create()
+{
+    return NULL;
+}
+
+/// @brief Destroy and free a sorted_list
+/// @param li sorted_list destroyed
+void sorted_list_destroy(sorted_list *li)
+{
+    while (!sorted_list_is_empty(*li))
+    {
+        element *tmp = *li;
+        *li = (*li)->next;
+        free(tmp);
+    }
+}
+
+/// @brief Push a value in the sorted_list
+/// @param li   sorted_list used
+/// @param val  value pushed
+/// @return The sorted_list with the new value
+sorted_list sorted_list_push(sorted_list li, int val)
+{
+    element *tmp = malloc(sizeof(element));
+    tmp->data = val;
+    tmp->next = NULL;
+
+    if (sorted_list_is_empty(li))
+    {
+        return tmp;
+    }
+
+    if (li->data > val)
+    {
+        tmp->next = li;
+        return tmp;
+    }
+
+    element *current = li;
+    while (current->next != NULL && val > current->next->data)
+    {
+        current = current->next;
+    }
+
+    tmp->next = current->next;
+    current->next = tmp;
+
+    return li;
+}
+
+sorted_list sorted_list_merge_list(sorted_list dest, sorted_list src_1, sorted_list src_2)
+{
+    if (src_1 != NULL)
+    {
+        element *pos = src_1;
+        dest = sorted_list_push(dest, pos->data);
+
+        while (pos->next != NULL)
+        {
+            pos = pos->next;
+            dest = sorted_list_push(dest, pos->data);
+        }
+    }
+
+    if (src_2 != NULL)
+    {
+        element *pos = src_2;
+        dest = sorted_list_push(dest, pos->data);
+
+        while (pos->next != NULL)
+        {
+            pos = pos->next;
+            dest = sorted_list_push(dest, pos->data);
+        }
+    }
+
+    return dest;
+}
+
+sorted_list sorted_list_remove_duplicates(sorted_list li)
+{
+    element *prec = li;
+    element *crt = li;
+    while (crt != NULL)
+    {
+        prec = crt;
+        crt = crt->next;
+
+        if (crt != NULL && prec->data == crt->data)
+        {
+            crt = crt->next;
+            prec->next = crt;
+        }
+    }
+
+    return li;
+}
+
+void sorted_list_print(sorted_list li)
+{
+    element *pos = li;
+    if (pos != NULL)
+    {
+        while (pos->next != NULL)
+        {
+            printf("%d ", pos->data);
+            pos = pos->next;
+        }
+
+        printf("%d\n", pos->data);
+    }
+}
+
 int main()
 {
+    int length_1;
+    int length_2;
+    sorted_list li = sorted_list_create();
+    sorted_list li_1 = sorted_list_create();
+    sorted_list li_2 = sorted_list_create();
+
+    printf("Entrez la liste 1: ");
+    if (scanf("%d", &length_1) != 1)
+    {
+        return -1;
+    }
+
+    for (int i = 0; i < length_1; i++)
+    {
+        int val;
+        if (scanf("%d", &val) != 1)
+        {
+            return -1;
+        }
+        li_1 = sorted_list_push(li_1, val);
+    }
+
+    printf("Entrez la liste 2: ");
+    if (scanf("%d", &length_2) != 1)
+    {
+        return -1;
+    }
+
+    for (int i = 0; i < length_2; i++)
+    {
+        int val;
+        if (scanf("%d", &val) != 1)
+        {
+            return -1;
+        }
+        li_2 = sorted_list_push(li_2, val);
+    }
+
+    li = sorted_list_merge_list(li, li_1, li_2);
+    li = sorted_list_remove_duplicates(li);
+
+    printf("L'intersection vaut: ");
+    sorted_list_print(li);
+
+    sorted_list_destroy(&li);
+    sorted_list_destroy(&li_1);
+    sorted_list_destroy(&li_2);
 
     return 0;
 }
diff --git a/ex02/ex02.c b/ex02/ex02.c
index 310abba9bd6efb57c1c76a2bd75391154d22a92f..6c792deee94d6c11de5e1b86a6bc127aaaf54fa3 100644
--- a/ex02/ex02.c
+++ b/ex02/ex02.c
@@ -5,9 +5,68 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <assert.h>
+
+#define SIZE_DEFAULT 200
+
+int string_len(char *s)
+{
+    int i = 0;
+    while (s[i] != '\0')
+    {
+        i++;
+    }
+
+    return i;
+}
+
+void string_fusion(char *dest, int size, char *src_1, char *src_2)
+{
+    int src_len_1 = string_len(src_1);
+    int src_len_2 = string_len(src_2);
+
+    assert(size > src_len_1 + src_len_2 && "The size of dest is to small");
+
+    while (*src_1 != '\0' || *src_2 != '\0')
+    {
+        if (*src_1 != '\0')
+        {
+            *dest++ = *src_1++;
+        }
+
+        if (*src_2 != '\0')
+        {
+            *dest++ = *src_2++;
+        }
+    }
+
+    *dest = '\0';
+}
 
 int main()
 {
+    char *str_1 = malloc(sizeof(char) * SIZE_DEFAULT);
+    char *str_2 = malloc(sizeof(char) * SIZE_DEFAULT);
+    char *str = malloc(sizeof(char) * SIZE_DEFAULT * 2);
+
+    printf("Chaine 1: ");
+    if (scanf("%s", str_1) != 1)
+    {
+        return -1;
+    }
 
+    printf("Chaine 2: ");
+    if (scanf("%s", str_2) != 1)
+    {
+        return -1;
+    }
+
+    string_fusion(str, SIZE_DEFAULT * 2, str_1, str_2);
+
+    printf("Chaine de sortie: %s\n", str);
+
+    free(str_1);
+    free(str_2);
+    free(str);
     return 0;
-}
+}
\ No newline at end of file
diff --git a/ex03/ex03.c b/ex03/ex03.c
index 6ee547b6377c16f332d221416e8b6b5ae92a7346..7926689efb78990cd5e51fcbbd295349cb004478 100644
--- a/ex03/ex03.c
+++ b/ex03/ex03.c
@@ -4,10 +4,147 @@
  */
 
 #include <stdlib.h>
+#include <stdbool.h>
 #include <stdio.h>
+#include <assert.h>
+
+typedef struct _element
+{
+    int data;
+    struct _element *next;
+    struct _element *prev;
+} element;
+
+typedef struct _dll
+{
+    element *head;
+    element *pos;
+} dll;
+
+dll dll_create()
+{
+    dll li;
+    li.head = NULL;
+    li.pos = NULL;
+
+    return li;
+}
+
+bool dll_is_empty(dll li)
+{
+    return li.head == NULL;
+}
+
+int dll_value(dll li)
+{
+    assert(!dll_is_empty(li) && li.pos != NULL);
+    return li.pos->data;
+}
+
+bool dll_is_head(dll li)
+{
+    assert(li.pos != NULL);
+    return (li.pos->prev == NULL);
+}
+
+bool dll_is_tail(dll li)
+{
+    assert(li.pos != NULL);
+    return (li.pos->next == NULL);
+}
+
+dll dll_move_to_head(dll li)
+{
+    li.pos = li.head;
+    return li;
+}
+
+dll dll_next(dll li)
+{
+    if (!dll_is_tail(li))
+    {
+        li.pos = li.pos->next;
+    }
+
+    return li;
+}
+
+void dll_print(dll li)
+{
+    li = dll_move_to_head(li);
+    printf("%d ", li.pos->data);
+    while (!dll_is_tail(li))
+    {
+        li = dll_next(li);
+        printf("%d ", li.pos->data);
+    }
+    printf("\n");
+}
+
+void dll_destroy(dll *li)
+{
+    *li = dll_move_to_head(*li);
+    while (!dll_is_tail(*li))
+    {
+        *li = dll_next(*li);
+        if (!dll_is_tail(*li))
+        {
+            free(li->pos->prev);
+        }
+    }
+    free(li->pos);
+
+    li->head = NULL;
+    li->pos = NULL;
+    free(li);
+}
+
+dll dll_push(dll li, int val)
+{
+    element *tmp = malloc(sizeof(element));
+    tmp->data = val;
+    tmp->prev = NULL;
+
+    if (dll_is_empty(li))
+    {
+        tmp->next = NULL;
+        li.head = tmp;
+        li.pos = tmp;
+    }
+    else
+    {
+        tmp->next = li.head;
+        li.head->prev = tmp;
+        li.head = tmp;
+    }
+
+    return li;
+}
 
 int main()
 {
+    int length;
+    dll li = dll_create();
+
+    printf("Liste d'entiers: ");
+    if (scanf("%d", &length) != 1)
+    {
+        return -1;
+    }
+
+    for (int i = 0; i < length; i++)
+    {
+        int val;
+        if (scanf("%d", &val) != 1)
+        {
+            return -1;
+        }
+        li = dll_push(li, val);
+    }
+
+    printf("Affichage: ");
+    dll_print(li);
+    dll_destroy(&li);
 
     return 0;
 }