diff --git a/slides/exemples/dll_solution.c b/slides/exemples/dll_solution.c
new file mode 100644
index 0000000000000000000000000000000000000000..ff072956a36c05ece52211203319107cac434db5
--- /dev/null
+++ b/slides/exemples/dll_solution.c
@@ -0,0 +1,201 @@
+#include "dll.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static element_t *create_element(int data, element_t *prev, element_t *next) {
+    element_t *elem = (element_t *)malloc(sizeof(*elem));
+    if (NULL == elem) {
+        return NULL;
+    }
+    elem->data = data;
+    elem->prev = prev;
+    elem->next = next;
+    return elem;
+}
+
+void dll_init(dll *list) {
+    list->pos = NULL;
+    list->head = NULL;
+}
+
+bool dll_is_empty(dll list) {
+    return (NULL == list.head && NULL == list.pos);
+}
+
+bool dll_value(dll list, int *val) {
+    if (dll_is_empty(list)) {
+        return false;
+    }
+    *val = list.pos->data;
+    return true;
+}
+
+bool dll_is_head(dll list) {
+    return (!dll_is_empty(list) && list.pos == list.head);
+}
+
+bool dll_is_tail(dll list) {
+    return (!dll_is_empty(list) && NULL == list.pos->next);
+}
+
+bool dll_is_present(dll list, int data) {
+    dll_move_to_head(&list);
+    int l_data = 0;
+    while (dll_value(list, &l_data)) {
+        if (data == l_data) {
+            return true;
+        } else if (dll_is_tail(list)) {
+            return false;
+        }
+        dll_next(&list);
+    }
+    return false;
+}
+
+static char *robust_realloc(char *str, size_t num) {
+    char *new_str = (char *)realloc(str, num * sizeof(*new_str));
+    if (NULL == new_str) {
+        free(str);
+        return NULL;
+    }
+    return new_str;
+}
+
+char *dll_to_str(dll list) {
+    char *str = (char *)malloc(sizeof(*str));
+    str[0] = 0;
+    if (dll_is_empty(list)) {
+        return str;
+    }
+    dll_move_to_head(&list);
+
+    int data = 0;
+    while (dll_value(list, &data)) {
+        char buffer[12];  // normally largest posible string is -2e9 (11 digits
+                          // and space and 0)
+        if (dll_is_tail(list)) {
+            sprintf(buffer, "%d", data);
+            str = robust_realloc(str, strlen(str) + strlen(buffer) + 1);
+            if (NULL == str) {
+                return NULL;
+            }
+            strncat(str, buffer, strlen(str) + strlen(buffer) + 1);
+            break;
+        } else {
+            sprintf(buffer, "%d ", data);
+            str = robust_realloc(str, strlen(str) + strlen(buffer) + 1);
+            if (NULL == str) {
+                return NULL;
+            }
+            strncat(str, buffer, strlen(str) + strlen(buffer) + 1);
+        }
+        dll_next(&list);
+    }
+    return str;
+}
+
+void dll_move_to_head(dll *list) {
+    list->pos = list->head;
+}
+
+void dll_next(dll *list) {
+    if (!dll_is_tail(*list) && !dll_is_empty(*list)) {
+        list->pos = list->pos->next;
+    }
+}
+
+void dll_prev(dll *list) {
+    if (!dll_is_head(*list) && !dll_is_empty(*list)) {
+        list->pos = list->pos->prev;
+    }
+}
+
+bool dll_insert_after(dll *list, int data) {
+    if (dll_is_empty(*list)) {
+        element_t *elem = create_element(data, NULL, NULL);
+        if (NULL == elem) {
+            return false;
+        }
+        list->head = list->pos = elem;
+    } else {
+        element_t *new_elem = create_element(data, list->pos, list->pos->next);
+        if (NULL == new_elem) {
+            return false;
+        }
+        if (!dll_is_tail(*list)) {
+            list->pos->next->prev = new_elem;
+        }
+        list->pos->next = new_elem;
+        list->pos = new_elem;
+    }
+    return true;
+}
+
+bool dll_push(dll *list, int data) {
+    if (dll_is_empty(*list)) {
+        element_t *elem = create_element(data, NULL, NULL);
+        if (NULL == elem) {
+            return false;
+        }
+        list->head = list->pos = elem;
+    } else {
+        element_t *new_elem = create_element(data, NULL, list->head);
+        if (NULL == new_elem) {
+            return false;
+        }
+        list->head->prev = new_elem;
+        list->head = new_elem;
+        list->pos = new_elem;
+    }
+    return true;
+}
+
+bool dll_extract(dll *list, int *val) {
+    bool ret = dll_value(*list, val);
+    if (!ret) {
+        return false;
+    }
+    element_t *elem = list->pos;
+    if (dll_is_tail(*list) && dll_is_head(*list)) {
+        list->head = list->pos = NULL;
+    } else if (dll_is_tail(*list)) {
+        list->pos = list->pos->prev;
+        list->pos->next = NULL;
+    } else if (dll_is_head(*list)) {
+        list->pos = list->pos->next;
+        list->pos->prev = NULL;
+        list->head = list->pos;
+    } else {
+        elem->prev->next = list->pos->next;
+        elem->next->prev = list->pos->prev;
+        list->pos = elem->next;
+    }
+    free(elem);
+    return true;
+}
+bool dll_pop(dll *list, int *val) {
+    dll_move_to_head(list);
+    bool ret = dll_value(*list, val);
+    if (!ret) {
+        return false;
+    }
+    element_t *elem = list->head;
+    if (dll_is_tail(*list) && dll_is_head(*list)) {
+        list->head = list->pos = NULL;
+    } else {
+        list->head->next->prev = NULL;
+        list->pos = list->head = list->head->next;
+    }
+    free(elem);
+    return true;
+}
+
+void dll_clear(dll *list) {
+    dll_move_to_head(list);
+    int val = 0;
+    while (dll_pop(list, &val)) {
+        // we do nothing
+    }
+}