diff --git a/README.md b/README.md
index 57ff576e635f004b698d22d80afa3081c680153e..f374d038428e936acf58897df06ab0726ee97dbf 100644
--- a/README.md
+++ b/README.md
@@ -15,72 +15,3 @@ Use this command to compile the project.
 > `make clean`
 
 Use this command to clean the project.
-
-## Visual Studio Code configuration
-
-You will find below the base configuration for the launch.json and tasks.json files in Visual Studio Code. Depending on your environment you will need to modify those files.
-
-### launch.json
-
-```json
-{
-    "version": "0.2.0",
-    "configurations": [
-        {
-            "name": "gcc-9 - Build and debug active file",
-            "type": "cppdbg",
-            "request": "launch",
-            "program": "${fileDirname}/histo",
-            "args": [],
-            "stopAtEntry": false,
-            "cwd": "${fileDirname}",
-            "environment": [],
-            "externalConsole": false,
-            "MIMode": "gdb",
-            "setupCommands": [
-                {
-                    "description": "Enable pretty-printing for gdb",
-                    "text": "-enable-pretty-printing",
-                    "ignoreFailures": true
-                }
-            ],
-            "preLaunchTask": "C/C++: gcc-9 build active file",
-            "miDebuggerPath": "/usr/bin/gdb"
-        }
-    ]
-}
-```
-
-### tasks.json
-
-```json
-{
-    "tasks": [
-        {
-            "type": "cppbuild",
-            "label": "C/C++: gcc-9 build active file",
-            "command": "/usr/bin/gcc-9",
-            "args": [
-                "-fdiagnostics-color=always",
-                "-g",
-                "${file}",
-                "-o",
-                "${fileDirname}/${fileBasenameNoExtension}",
-                "-lm"
-            ],
-            "options": {
-                "cwd": "${fileDirname}"
-            },
-            "problemMatcher": [
-                "$gcc"
-            ],
-            "group": {
-                "kind": "build",
-                "isDefault": true
-            },
-            "detail": "Task generated by Debugger."
-        }
-    ],
-    "version": "2.0.0"
-}
-```
diff --git a/histo.c b/histo.c
index f9dcfb540f391961574807aef818043bf5941835..fc8716333f28dd912f4fd241d63ebd4dca5a2a5d 100644
--- a/histo.c
+++ b/histo.c
@@ -1,39 +1,106 @@
-
+/* Author : Dario GENGA
+ * Date : 15.11.2021
+ * Description : Manipulate an unidimensional array with dynamic memory allocation
+ */
 #include "unidimensional_array.h"
+#include "time.h"
+#define USER_MODE 0
+#define COMPUTER_MODE 1
+#define MAX_RANDOM_VALUE 10
 
-int main() {
-    // Ask the user the size of the array
-    size_t array_size = ask_array_size();
-    int array[array_size];
+void execute(int mode) {
+    size_t cycle_number = 3;
+    size_t value = 0;
+    size_t multiply_value = 0;
+    size_t array_size;
+
+    if (mode == USER_MODE) {
+        // Ask the user the size of the array
+       array_size = ask_array_size();
+    } else if (mode == COMPUTER_MODE){
+        array_size = rand() % MAX_RANDOM_VALUE + 1;
+    }
+    int *array = malloc(array_size * sizeof(int));
 
     // Fill the array with random values
     fill_array_with_random_values(array, array_size);
 
-    // Find the lowest value in the array
-    int lowest_value = find_lowest_value_in_array(array, array_size);
-    printf("Lowest value : %d\n", lowest_value);
-    
-    // Swap the highest value of the array with the last element of the array
-    size_t index_highest_value = find_index_highest_value_in_array(array, array_size);
-    swap(&array[index_highest_value], &array[array_size - 1]);
+    // Print the array
+    printf("Original array :\n");
+    print_array(array, array_size);
+
+    // Shuffle the array
+    shuffle_array(array, array_size);
+    printf("Array after shuffle :\n");
+    print_array(array, array_size);
+
+    // Perform a cyclic permutation
+    perform_cyclic_permutation(array, array_size, cycle_number);
+    printf("Array after cyclic permutation :\n");
+    print_array(array, array_size);
 
-    // Calculate the average value of the array
-    int average = get_average_in_array(array, array_size);
-    printf("Average : %d\n", average);
+    // Permute smallest value with the last value
+    permute_lowest_value_with_last_value(array, array_size);
+    printf("Array after swapping the smallest value with the last one :\n");
+    print_array(array, array_size);
 
-    // Calculate the variances of the elemenst in the array
-    int variance = get_variance_in_array(array, array_size);
-    printf("Variance : %d\n", variance);
+    // Descending sort the array by using the insertion algorithm
+    sort_by_insertion_desc(array, array_size);
+    printf("Array after insertion desc sort :\n");
+    print_array(array, array_size);
 
-    // Asc sort the array
-    sort_array_asc(array, array_size);
+    if (mode == USER_MODE) {
+        // Ask the user a value and then return the total of elements that are smaller
+        printf("Type a value : \n");
+        scanf("%ld", &value);
+    } else if (mode == COMPUTER_MODE) {
+        value = rand() % MAX_RANDOM_VALUE + 1;
+    }
+    size_t elements_with_lower_value = count_elements_in_array_lower_than_value(array, array_size, value);
+    printf("Number of elements with lower value : %ld\n", elements_with_lower_value);
 
-    // Find the median value
-    int median = get_median_value(array, array_size);
-    printf("Median : %d\n", median);
+    // Create a second array and compute it with the first one to a third array
+    int *second_array = malloc(array_size * sizeof(int));
+    int *result_sum_array = malloc(array_size * sizeof(int));
+    fill_array_with_random_values(second_array, array_size);
+    printf("Second array :\n");
+    print_array(second_array, array_size);
+    compute_two_array(array, second_array, result_sum_array, array_size);
+    printf("Result array :\n");
+    print_array(result_sum_array, array_size);
 
-    // Check the equitability of the random number generator
-    create_histo(array, array_size);
+    // Create a fourth array that will stock the multiplication between the first array and a value from the user
+    int *result_mul_array = malloc(array_size * sizeof(int));
+    if (mode == USER_MODE) {
+        printf("Multiply the first array with the following value : \n");
+        scanf("%ld", &multiply_value);
+    } else if (mode == COMPUTER_MODE) {
+        multiply_value = rand() % MAX_RANDOM_VALUE + 1;
+    }
+    multiply_array_with_value(array, array_size, result_mul_array, multiply_value);
+    printf("Result array after multiplication :\n");
+    print_array(result_mul_array, array_size);
+
+    // Convert the first array to an array of double
+    double *converted_array = convert_int_array_to_double(array, array_size);
+    printf("Array converted to double :\n");
+    print_array_of_double(converted_array, array_size);
+
+    // Free the memory
+    free(array);
+    free(second_array);
+    free(result_sum_array);
+    free(result_mul_array);
+}
+
+int main() {
+    srand(time(NULL));
+    printf("Starting user mode...\n");
+    execute(USER_MODE);
+    printf("Starting computer mode...\n");
+    for (size_t i = 0; i < 100; i++) {
+        execute(COMPUTER_MODE);
+    }
 
     return 0;
 }
\ No newline at end of file
diff --git a/makefile b/makefile
index 30b672d01c22a17ceb50bbacd9d401fb283b78c8..8f33e37e904deb9abfb58a44736eb6e0b4ef013f 100644
--- a/makefile
+++ b/makefile
@@ -1,8 +1,8 @@
 LIB=-lm
-CC=gcc -Wall -Wextra
+CC=gcc -Wall -Wextra -g
 
 histo:unidimensional_array.o histo.o
-	gcc $^ -o $@ $(LIB)
+	gcc $^ -fsanitize=address -o $@ $(LIB)
 
 unidimensional_array.o: unidimensional_array.c unidimensional_array.h
 	$(CC) -c $< $(LIB)
diff --git a/unidimensional_array.c b/unidimensional_array.c
index a6739ee7a8fb7ba3b252af4a18cab1278e861663..f56e61a25a7023dd737372a0a45430f04e8d6928 100644
--- a/unidimensional_array.c
+++ b/unidimensional_array.c
@@ -1,14 +1,10 @@
 /* Author : Dario GENGA
- * Date : 12.10.2021
- * Description : Manipulate an unidimensional array
+ * Date : 15.11.2021
+ * Description : Manipulate an unidimensional array with dynamic memory allocation
  */
 
 #include "unidimensional_array.h"
 #include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-#define PERCENT_OF_MAX_ARRAY_VALUE 10
 
 size_t ask_array_size() {
     size_t array_size = 0;
@@ -17,159 +13,139 @@ size_t ask_array_size() {
     return array_size;
 }
 
-void fill_array_with_random_values(int array[], size_t array_size) {
-    size_t max_value = array_size / PERCENT_OF_MAX_ARRAY_VALUE;
-
-    srand(time(0));
+void shuffle_array(int *array, size_t array_size) {
+    for (size_t i = 0; i < array_size; i++)
+    {
+        int index1 = rand() % (int)array_size;
+        int index2 = rand() % (int)array_size;
+        swap(&array[index1], &array[index2]);
+    }
+}
 
+void fill_array_with_random_values(int *array, size_t array_size) {
+    // Fill the array with all values from 0 to its size - 1
     for (size_t i = 0; i < array_size; i++)
     {
-        int random_value = (rand() % (max_value + 1));
-        array[i] = random_value;
+        array[i] = i;
     }
+
+    // Then shuffle the array
+    shuffle_array(array, array_size);
 }
 
-int find_lowest_value_in_array(int array[], size_t array_size) {
-    int lowest_value;
+
+void perform_cyclic_permutation(int *array, size_t array_size, size_t cycle_number) {
+    int *array_tmp = malloc(array_size * sizeof(int));
 
     for (size_t i = 0; i < array_size; i++) {
-        if (i == 0) {
-            lowest_value = array[i];
-        } else if (array[i] < lowest_value) {
-            lowest_value = array[i];
-        }
+        size_t tmp_index = (i + cycle_number) % array_size;
+        array_tmp[tmp_index] = array[i];
     }
-    return lowest_value;
-}
-
-int find_index_highest_value_in_array(int array[], size_t array_size) {
-    int highest_value;
-    size_t index_highest_value = 0;
 
     for (size_t i = 0; i < array_size; i++) {
-        if (i == 0) {
-            highest_value = array[i];
-        } else if (array[i] > highest_value) {
-            highest_value = array[i];
-            index_highest_value = i;
+        array[i] = array_tmp[i];
+    }
+
+    free(array_tmp);
+}
+
+void print_array(int* array, size_t array_size) {
+    printf("[");
+    for (size_t i = 0; i < array_size; i++)
+    {
+        printf("%d", array[i]);
+        if (i + 1 < array_size) {
+            printf(" , ");
         }
     }
-    return index_highest_value;
+    printf("]\n");
 }
 
-void swap(int *x, int *y)
-{
-    int tmp = *x;
-    *x = *y;
-    *y = tmp;
+void print_array_of_double(double *array, size_t array_size) {
+    printf("[");
+    for (size_t i = 0; i < array_size; i++)
+    {
+        printf("%f", array[i]);
+        if (i + 1 < array_size) {
+            printf(" , ");
+        }
+    }
+    printf("]\n");
 }
 
-int get_average_in_array(int array[], size_t array_size) {
-    int sum = 0, average = 0;
+int find_lowest_value_index_in_array(int *array, size_t array_size) {
+    int lowest_value;
+    size_t lowest_index;
 
     for (size_t i = 0; i < array_size; i++) {
-        sum += array[i];
+        if (i == 0) {
+            lowest_value = array[i];
+            lowest_index = i;
+        } else if (array[i] < lowest_value) {
+            lowest_value = array[i];
+            lowest_index = i;
+        }
     }
-    average = sum / (int)array_size;
+    return lowest_index;
+}
 
-    return average;
+void permute_lowest_value_with_last_value(int *array, size_t array_size) {
+    int lowest_index = (int)find_lowest_value_index_in_array(array, array_size);
+    int last_index = array_size - 1;
+    swap(&array[lowest_index], &array[last_index]);
 }
 
-int get_variance_in_array(int array[], size_t array_size) {
-    int average = get_average_in_array(array, array_size);
-    int variance = 0;
-    
-    for (size_t i = 0; i < array_size; i++) {
-        int x = array[i] - average;
-        variance += pow(x, 2);
-    }
+void sort_by_insertion_desc(int *array, size_t array_size) {
+    size_t i = 1;
 
-    variance = variance / (int)array_size;
-    return variance;
+    while (i < array_size) {
+        size_t k = i;
+        while (k > 0 && array[k - 1] < array[k]) {
+            swap(&array[k], &array[k - 1]);
+            k -= 1;
+        }
+        i++;
+    }
 }
 
-void sort_array_asc(int array[], size_t array_size)
-{
-    int is_array_sorted = 0;
+size_t count_elements_in_array_lower_than_value(int *array, size_t array_size, int value) {
+    size_t total = 0;
 
-    while (is_array_sorted == 0)
+    for (size_t i = 0; i < array_size; i++)
     {
-        is_array_sorted = 1;
-
-        for (size_t i = 0; i < array_size; i++)
-        {
-            int previous_index = i - 1;
-            int current_value = array[i];
-
-            if (previous_index >= 0 && current_value < array[previous_index])
-            {
-                // Swap the current value with the previous one
-                is_array_sorted = 0;
-                swap(&array[i], &array[previous_index]);
-            }
+        if (array[i] < value) {
+            total++;
         }
     }
+
+    return total;
 }
 
-int get_median_value(int array[], size_t array_size) {
-    int median = 0;
-    size_t index1 = (array_size - 1) / 2;
-
-    if (array_size % 2 == 0) {
-        size_t index2 = (array_size / 2);
-        int val1 = array[index1];
-        int val2 = array[index2];
-        median = (val1 + val2) / 2;
-    } else {
-        median = array[index1];
+void compute_two_array(int *first_array, int *second_array, int *result_array, size_t array_size) {
+    for (size_t i = 0; i < array_size; i++) {
+        result_array[i] = first_array[i] + second_array[i];
     }
-    return median;
 }
 
-void create_histo(int array[], size_t array_size) {
-    size_t histo_size = array_size / PERCENT_OF_MAX_ARRAY_VALUE + 1; // +1 because we didn't exclude the maximal value with the random
-    int histo[histo_size];
-
-    // Initialize the element of the histo
-    for (size_t i = 0; i < histo_size; i++)
-    {
-        histo[i] = 0;
-    }
-    
-    // Create the histo
+void multiply_array_with_value(int *array, size_t array_size, int *result_array, int value) {
     for (size_t i = 0; i < array_size; i++) {
-        int value = array[i];
-        histo[value] += 1;
-    }
-    
-    // Print horizontally the histo
-    printf("\nHorizontal histo :\n");
-    for (size_t i = 0; i < histo_size; i++)
-    {
-        printf("%ld : %d\n", i, histo[i]);
+        result_array[i] = array[i] * value;
     }
+}
 
-    // Print vertically the histo
-    printf("\nVertical histo :\n");
-    for (size_t i = 0; i < histo_size; i++)
-    {
-        printf("%ld", i);
+double *convert_int_array_to_double(int* array, size_t array_size) {
+    double *converted_array = malloc(array_size * sizeof(double));
+
+    for (size_t i = 0; i < array_size; i++) {
+        converted_array[i] = (double)array[i];
     }
-    printf("\n");
 
-    int index_highest_value = find_index_highest_value_in_array(histo, (size_t)histo_size);
-    int highest_value = histo[index_highest_value];
+    return converted_array;
+}
 
-    for (size_t i = 0; i < highest_value; i++)
-    {
-        for (size_t x = 0; x < histo_size; x++)
-        {
-            if (histo[x] <= i) {
-                printf(" ");
-            } else {
-                printf("*");
-            }
-        }
-        printf("\n");
-    }
-}
\ No newline at end of file
+void swap(int *x, int *y)
+{
+    int tmp = *x;
+    *x = *y;
+    *y = tmp;
+}
diff --git a/unidimensional_array.h b/unidimensional_array.h
index b0fb4ff8ef3e97a4ad3630b5d2508a7738305cb4..5ef786b8c39333f506810199699242c436074867 100644
--- a/unidimensional_array.h
+++ b/unidimensional_array.h
@@ -1,29 +1,38 @@
 /* Author : Dario GENGA
- * Date : 02.11.2021
- * Description : Manipulate an unidimensional array
+ * Date : 15.11.2021
+ * Description : Manipulate an unidimensional array with dynamic memory allocation
  */
 #ifndef _UNIDIMENSIONAL_ARRAY_H
 #define _UNIDIMENSIONAL_ARRAY_H
 #include <stdio.h>
-#define PERCENT_OF_MAX_ARRAY_VALUE 10
+#include <stdlib.h>
 
 size_t ask_array_size();
 
-void fill_array_with_random_values(int array[], size_t array_size);
+void fill_array_with_random_values(int *array, size_t array_size);
 
-int find_lowest_value_in_array(int array[], size_t array_size);
+int find_lowest_value_index_in_array(int *array, size_t array_size);
 
-int find_index_highest_value_in_array(int array[], size_t array_size);
+void permute_lowest_value_with_last_value(int *array, size_t array_size);
 
-void swap(int *x, int *y);
+void shuffle_array(int *array, size_t array_size);
+
+void perform_cyclic_permutation(int *array, size_t array_size, size_t cycle_number);
+
+void sort_by_insertion_desc(int *array, size_t array_size);
+
+size_t count_elements_in_array_lower_than_value(int *array, size_t array_size, int value);
 
-int get_average_in_array(int array[], size_t array_size);
+void compute_two_array(int *first_array, int *second_array, int *result_array,  size_t array_size);
 
-int get_variance_in_array(int array[], size_t array_size);
+void multiply_array_with_value(int *array, size_t array_size, int *result_array, int value);
 
-void sort_array_asc(int array[], size_t array_size);
+double *convert_int_array_to_double(int *array, size_t array_size);
 
-int get_median_value(int array[], size_t array_size);
+void print_array(int *array, size_t array_size);
+
+void print_array_of_double(double *array, size_t array_size);
+
+void swap(int *x, int *y);
 
-void create_histo(int array[], size_t array_size);
 #endif
\ No newline at end of file