diff --git a/README.md b/README.md
index 74f925a..6f53492 100644
--- a/README.md
+++ b/README.md
@@ -57,8 +57,10 @@ Mesurez combien de temps prend python à générer un tableau composés de :
Sur un tableur, générez un tableau permettant de visualiser le temps d'éxécution en fonction de la taille de l'entrée.
-Comment vous semble évoluer la courbe ? Observez bien les différentes courbes du graphique ci-dessous. Quelle est la plus ressemblante à notre situation ? *Écrivez votre réponse ici*
-
+Comment vous semble évoluer la courbe ? Observez bien les différentes courbes du graphique ci-dessous. Quelle est la plus ressemblante à notre situation ?
+```diff
+@@ La courbe a une allure linéaire. On peut en déduire que complexité de la fonction est O(n). @@
+```
#### Quelques exemples de complexités courante :
@@ -75,8 +77,15 @@ Observez attentivement l'animation de tri par sélection ci-dessous pour en comp
-Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Écrivez votre réponse ici*
-
+Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ?
+```diff
+@@ On observe un parcours du tableau progressif. @@
+@@ A chaque nouveau parcours du tableau, on identifie l'élément à trier et on @@
+@@ parcours le reste du tableau à la recherche d'un autre plus petit. @@
+@@ Arrivé à la fin du parcours, on échange l'élément comparé avec le plus petit @@
+@@ trouvé dans le reste du tableau, sinon on ne fait rien. @@
+@@ On passe à l'élément suivant. @@
+```
Puis implémentez l'algorithme en python dans la fonction `sort` du fichier `sort/selection.py`. Vérifiez son bon fonctionnement en éxécutant le fichier `python3 -m unittest`. Le test correspondant au tri par sélection doit passer.
Mesurez le temps d'éxécution pour un tableau de :
@@ -88,7 +97,14 @@ Mesurez le temps d'éxécution pour un tableau de :
Tracez le graphique correspondant.
-Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Écrivez votre réponse ici*
+Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ?
+```diff
+@@ La courbe obtenue a une allure carrée. On en déduit une complexité proche @@
+@@ de O(n^2). Ce n'est pas étonnant dans la mesure où le tableau est en bonne @@
+@@ partie reparcouru pour chaque élément comparé, cela décuple au carré le nombre @@
+@@ d'opération nécessaires au pire cas. @@
+```
+
### 2. Tri par insertion
@@ -96,8 +112,13 @@ Observez attentivement l'animation de tri par insertion ci-dessous pour en compr
-Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Écrivez votre réponse ici*
-
+Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ?
+```diff
+@@ On observe un parcours de tableau progressif. @@
+@@ A chaque élément comparé, on parcours la portion de tableau le précedent. @@
+@@ On insère celui-ci entre un élément plus petit et un élément plus grand. @@
+@@ Puis on passe à l'élément suivant. @@
+```
Puis implémentez l'algorithme en python dans la fonction `sort` du fichier `sort/insertion.py`. Utilisez les tests automatiques pour vérifier votre implémentation.
Mesurez le temps d'éxécution pour un tableau de :
@@ -109,7 +130,12 @@ Mesurez le temps d'éxécution pour un tableau de :
Tracez le graphique correspondant.
-Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Écrivez votre réponse ici*
+Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ?
+```diff
+@@ Pour les même raison que citée précédemment, la complexité au pire cas est de @@
+@@ O(n^2). L'imbrication de deux boucles justifie cette exponentialité. @@
+```
+
### 3. Tri par fusion
@@ -154,8 +180,15 @@ Observez bien le schéma suivant : il représente le concept du tri par fusion.
Cet algorithme est de type "diviser pour régner".
-Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Écrivez votre réponse ici*
-
+Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ?
+```diff
+@@ On oberve un parcours de tableau dichotomique. @@
+@@ A chaque nouvelle itération de la fonction, le tableau est séparé en deux @@
+@@ puis réitéré jusqu'à ce qu'on obtienne un série de tableaux de taille 1. @@
+@@ Les tableaux sont alors rassemblés à nouveaux avec un traitement de tri @@
+@@ à chaque nouveau rassemblement, ce qui rédui considérablement la charge @@
+@@ de l'algorithme de tri, au détriment de la pile. @@
+```
Complétez la fonction `sort` du fichier `sort/fusion.py` en suivant les instructions suivantes.
Il vous faudra deux fonctions :
@@ -174,15 +207,34 @@ Mesurez le temps d'éxécution pour un tableau de :
Tracez le graphique correspondant.
-Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Écrivez votre réponse ici*
+Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ?
+```diff
+@@ En observant la courbe de la fusion, on remarque une fonction linéaire. Ce qui @@
+@@ n'est pas absurde lorsqu'on sait qu'une boucle est appelée lors du tri, @@
+@@ assoçié à une recherche dichotomique. On peut donc en déduire que la @@
+@@ complexité est de O(nlog(n)). @@
+```
+
-Question bonus : Y a-t-il des tailles de tableaux pour lesquelles le tri par fusion n'est pas aussi rapide que les précédents tris abordés ? *Écrivez votre réponse ici*
+
+Question bonus : Y a-t-il des tailles de tableaux pour lesquelles le tri par fusion n'est pas aussi rapide que les précédents tris abordés ?
+```diff
+@@ Le tri par fusion risque d'être plus lent pour des tableaux de très @@
+@@ petite taille, engendré par le calcul supplémentaire du à la séparation @@
+@@ dichotomique. On peut s'en douter en obesrvant la courbe d'un logarithme, qui @@
+@@ croit très rapidement au départ avant d'avoir un comportement asymptotique à @@
+@@ l'infini. @@
+```
### 4. sort()
Bien que tout cela soit fascinant, Python possède sa propre méthode de tri : `sort()`.
Une dernière fois, analysez le temps d'exécution et découvrez si python fait mieux que nos implémentations rudimentaires ;)
+```diff
+@@ Je n'ai plus les mots : @@
+```
+
## Pour rendre ce TP
@@ -193,3 +245,5 @@ Le nom de la PR doit contenir votre nom.
Vérifiez que votre code est conforme aux normes pep8 et aux autres critères de qualité dont nous avons parlé.
La PR doit également contenir un ou plusieurs graphiques présentant vos résultats sur la complexité des fonctions de tri.
+
+
diff --git a/__main__.py b/__main__.py
index 98a585e..3c12dd1 100644
--- a/__main__.py
+++ b/__main__.py
@@ -1,5 +1,83 @@
+import time
+import matplotlib.pyplot as plt
+from sort.range import generate_array_of_number
+import sort.selection as selection
+import sort.insertion as insertion
+import sort.fusion as fusion
+
+
def main():
- print("Hello world")
+
+ tests: list[list[int]] = []
+
+ plt.figure()
+ plt.xlabel("Array Size")
+ plt.ylabel("Compute Time")
+ plt.title("Faisons le tri - Hugo JEUDY")
+
+ array_sizes: list[int] = []
+ generation_times: list[float] = []
+ selection_times: list[float] = []
+ insertion_times: list[float] = []
+ fusion_times: list[float] = []
+ sort_times: list[float] = []
+
+ for i in range(1000, 20001, 500):
+
+ print(f"Doing it with {i}")
+
+ array_sizes.append(i)
+
+ # compute array completion
+
+ timer_start: float = time.time()
+ rand_numbers_array: list[int] = generate_array_of_number(i)
+ timer_end: float = time.time()
+ generation_times.append(timer_end - timer_start)
+
+ # compute array selection sort
+
+ selection_array = rand_numbers_array.copy()
+ timer_start = time.time()
+ selection.sort(selection_array)
+ timer_end: float = time.time()
+ selection_times.append(timer_end - timer_start)
+
+ # compute array insertion sort
+
+ insertion_array = rand_numbers_array.copy()
+ timer_start = time.time()
+ insertion.sort(insertion_array)
+ timer_end: float = time.time()
+ insertion_times.append(timer_end - timer_start)
+
+ # compute array fusion sort
+
+ fusion_array = rand_numbers_array.copy()
+ timer_start = time.time()
+ fusion.sort(fusion_array)
+ timer_end: float = time.time()
+ fusion_times.append(timer_end - timer_start)
+
+ # compute array sort from python
+
+ sort_array = rand_numbers_array.copy()
+ timer_start = time.time()
+ sort_array.sort()
+ timer_end: float = time.time()
+ sort_times.append(timer_end - timer_start)
+
+ plt.plot(array_sizes, generation_times, "-",
+ color='lightgrey', label='Array Generation')
+ plt.plot(array_sizes, selection_times, "-",
+ color='darkolivegreen', label='Selection')
+ plt.plot(array_sizes, insertion_times, "-",
+ color='mediumslateblue', label='Insertion')
+ plt.plot(array_sizes, fusion_times, "-", color='peru', label='Fusion')
+ plt.plot(array_sizes, sort_times, "-", color='coral', label="Sort")
+
+ plt.legend()
+ plt.show()
main()
diff --git a/img/results/Figure_2.png b/img/results/Figure_2.png
new file mode 100644
index 0000000..c2e2837
Binary files /dev/null and b/img/results/Figure_2.png differ
diff --git a/img/results/all.png b/img/results/all.png
new file mode 100644
index 0000000..eb37f58
Binary files /dev/null and b/img/results/all.png differ
diff --git a/img/results/fusion.png b/img/results/fusion.png
new file mode 100644
index 0000000..316c2f2
Binary files /dev/null and b/img/results/fusion.png differ
diff --git a/img/results/insertion.png b/img/results/insertion.png
new file mode 100644
index 0000000..2d783b0
Binary files /dev/null and b/img/results/insertion.png differ
diff --git a/img/results/selection.png b/img/results/selection.png
new file mode 100644
index 0000000..91abc66
Binary files /dev/null and b/img/results/selection.png differ
diff --git a/img/results/wtf.png b/img/results/wtf.png
new file mode 100644
index 0000000..1cc7360
Binary files /dev/null and b/img/results/wtf.png differ
diff --git a/sort/fusion.py b/sort/fusion.py
index 73a21d3..550571c 100644
--- a/sort/fusion.py
+++ b/sort/fusion.py
@@ -1,2 +1,52 @@
+import sort.insertion as insertion
+import time
+
+
def sort(array: list[int]) -> list[int]:
- return array
+ '''
+ Return the array by using fusion sort
+ '''
+
+ if len(array) <= 1:
+ return array
+ else:
+ half = len(array) // 2
+ return merge(sort(array[:half]), sort(array[half:]))
+
+
+def merge(array: list[int], array2: list[int]) -> list[int]:
+ '''
+ Merge two arrays by sorting them
+ '''
+
+ sorted_array = []
+
+ array_index = 0
+ array2_index = 0
+
+ while len(sorted_array) != len(array) + len(array2):
+
+ # Avoid list out of range
+ if array_index >= len(array):
+
+ sorted_array.append(array2[array2_index])
+ array2_index += 1
+
+ elif array2_index >= len(array2):
+
+ sorted_array.append(array[array_index])
+ array_index += 1
+
+ # or check wich value is the smallest
+
+ elif array2[array2_index] < array[array_index]:
+
+ sorted_array.append(array2[array2_index])
+ array2_index += 1
+
+ elif array[array_index] <= array2[array2_index]:
+
+ sorted_array.append(array[array_index])
+ array_index += 1
+
+ return sorted_array
diff --git a/sort/insertion.py b/sort/insertion.py
index 73a21d3..e04f032 100644
--- a/sort/insertion.py
+++ b/sort/insertion.py
@@ -1,2 +1,23 @@
def sort(array: list[int]) -> list[int]:
+ '''
+ Sort an array using insertion sort.
+ '''
+
+ for i in range(len(array)):
+ # checking every elements of the array
+
+ compared_element: int = array[i]
+
+ j: int = i - 1
+
+ while array[j] > compared_element and j >= 0:
+ # reverse the course of the array to place the currently selected
+ # element after another one if it is smaller
+
+ array[j + 1] = array[j]
+
+ j -= 1
+
+ array[j + 1] = compared_element
+
return array
diff --git a/sort/range.py b/sort/range.py
index fc252ab..911b6fb 100644
--- a/sort/range.py
+++ b/sort/range.py
@@ -1,2 +1,9 @@
+import random
+
+
def generate_array_of_number(array_size: int) -> list[int]:
- return []
+ '''
+ Return a random numbers (0 to 100 both included) array
+ with the given size
+ '''
+ return [random.randint(0, 100) for i in range(array_size)]
diff --git a/sort/recursion.py b/sort/recursion.py
index e7f4320..16667a3 100644
--- a/sort/recursion.py
+++ b/sort/recursion.py
@@ -1,2 +1,12 @@
-def get_factorial(number: int) -> int:
- return number
+def get_factorial(number: int, max: int = 100) -> int:
+ '''
+ Return the factorial of the number
+ '''
+
+ if (max == 0):
+ return 0
+
+ if number == 1:
+ return number
+ else:
+ return number * get_factorial(number - 1, max - 1)
diff --git a/sort/selection.py b/sort/selection.py
index 73a21d3..0b41f0c 100644
--- a/sort/selection.py
+++ b/sort/selection.py
@@ -1,2 +1,26 @@
def sort(array: list[int]) -> list[int]:
+ '''
+ Sort an array using selection sort.
+ '''
+ for i in range(len(array)):
+ # Checking all element of the array
+
+ compared_element: int = array[i]
+
+ temp_element: int = compared_element
+ switch_index: int = i
+
+ for j in range(i + 1, len(array)):
+ # checking the rest of the array in search for smaller elements
+
+ if (array[j] < temp_element):
+
+ temp_element = array[j]
+ switch_index = j
+
+ if compared_element != temp_element:
+ # switching the two elements if a smaller one has been found
+ array[i] = temp_element
+ array[switch_index] = compared_element
+
return array