diff --git a/README.md b/README.md
index 74f925a..c326b78 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,10 @@ 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 ?
+Selon moi le tri par selection va regarder toute la liste,
+il va selectionner l'element le plus petit et le placer au début de la liste.
+Ensuite, il recommence avec le reste de la liste tant qu'elle n'est pas vide.
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.
@@ -88,7 +91,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é ?
+Le tri par selection est de complexité O(N**2)
+Car entre la première et la dernière valeur les entrées sont multiplé par 10
+alors que les temps sont multipliés par 100.
+De plus on a directement une double boucle dans le programme
+qui regarde tout les éléments, ce qui fait N*N donc N**2
### 2. Tri par insertion
@@ -96,7 +104,10 @@ 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 ?
+Selon moi, Le tri par insertion va regarder le deuxieme element de la liste
+et le placer avant ou après le premier si il est plus petit ou non. Puis faire
+pareil avec les autres éléments en les comparant avec tous ceux avant
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.
@@ -109,7 +120,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é ?
+Le tri par insertion est de complexité O(N**2)
+Car entre la première et la dernière valeur les entrées sont multiplé par 10
+alors que les temps sont multipliés par 100.
+De plus on a directement une double boucle dans le programme
+qui regarde tout les éléments, ce qui fait N*N donc N**2
### 3. Tri par fusion
@@ -154,7 +170,14 @@ 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 ?
+Le tri fusion prend un tableau.
+Si le tableau n'est pas vide ou n'est pas composé d'un seul élément,
+Python vas le divisé en deux en rappelant la meme fonction puis le merger.
+A chaque fois avant de merger les différents tableaux vont se réduire,
+jusqu'à ce que chaque tableau n'ait qu'un élément.
+Ensuite les tableaux vont se merger petit à petit en restant croissant et
+en formant au final un seul tableau
Complétez la fonction `sort` du fichier `sort/fusion.py` en suivant les instructions suivantes.
@@ -174,9 +197,20 @@ 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*
-
-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*
+Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ?
+Le tri fusion a l'air d'etre de complexité N*log(N)
+car on subdivise le tri en plusieurs tri de 1 élément.
+Puis on les recombine ensemble en les lisant.
+Le nombre d'étape ou on lit chaque valeur est
+a chaque fois que l'on merge des élements (2**(k))>=n>(2**(k-1))+1.
+Il a donc k étapes ou on lit tout n. k est plus petit que N
+car on prend le k supérieur ou égal à 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 ?
+Si on considère que le tri par fusion a une complexité inférieur aux autres tri
+alors plus le nombre de valeur va augmenté
+plus l'écart entre les différentes complexités va augmenté également.
+Le tri sera toujours plus rapide qu'un tri avec une complexité supérieur
### 4. sort()
@@ -184,6 +218,9 @@ Bien que tout cela soit fascinant, Python possède sa propre méthode de tri : `
Une dernière fois, analysez le temps d'exécution et découvrez si python fait mieux que nos implémentations rudimentaires ;)
+Le tri sort de python est environ 100 fois plus rapide que notre tri fusion.
+Sa complexité semble etre N
+
## Pour rendre ce TP
Merci de faire une Pull Request vers ce repository.
diff --git a/__main__.py b/__main__.py
index 98a585e..a626ee7 100644
--- a/__main__.py
+++ b/__main__.py
@@ -1,5 +1,135 @@
-def main():
- print("Hello world")
+import time
+from enum import Enum, unique, auto
+from sort.range import generate_array_of_number
+from sort.selection import sort as selection_sort
+from sort.insertion import sort as insertion_sort
+from sort.recursion import get_factorial
+from sort.fusion import sort as fusion_sort
-main()
+@unique
+class Function(Enum):
+ GENERATE_ARRAY = auto()
+ SELECTION_SORT = auto()
+ INSERTION_SORT = auto()
+ FACTORIAL = auto()
+ FUSION_SORT = auto()
+ PYTHON_SORT = auto()
+
+
+# We create a loop where there are all the element we need for test our sort
+LOOP_REQUIRED = list[int](((element % 10)+1) * 10 if element < 10
+ else
+ ((element % 10)+1) * 1_000 if 10 <= element < 20
+ else
+ ((element % 10)+1) * 10_000 if 20 <= element < 30
+ else
+ ((element % 10)+1) * 1_000_000
+ for element in range(0, 40))
+
+TEN_PART: int = 0
+THOUSAND_PART: int = 10
+TEN_THOUSAND_PART: int = 20
+MILLION_PART: int = 30
+
+
+def main(use_tri: Function):
+ """main function call two other fonction
+ and take on parameter the sort we want use"""
+ write_result(do_function(use_tri), use_tri)
+
+
+def do_function(use_tri: Function) -> list[float]:
+ """do_function make ten time the right sort
+ and return a tab of time different for the number of element"""
+ timer_tab: list[float] = []
+ for element in range(len(LOOP_REQUIRED)//4):
+ tab_generate = generate_array_of_number(
+ generate_index_tab_with_sort(use_tri, element))
+
+ start: float = time.time()
+ # Generate a tab from 1_000_000 to 10_000_000
+ if (use_tri == Function.GENERATE_ARRAY):
+ generate_array_of_number(LOOP_REQUIRED[element + MILLION_PART])
+
+ # Use factorial on number from 10 to 100
+ if (use_tri == Function.FACTORIAL):
+ get_factorial(LOOP_REQUIRED[element//3] // 100)
+
+ # Use selection sort on tab from 1_000 to 10_000
+ if (use_tri == Function.SELECTION_SORT):
+ selection_sort(tab_generate)
+
+ # Use insertion sort on tab from 1_000 to 10_000
+ if (use_tri == Function.INSERTION_SORT):
+ insertion_sort(tab_generate)
+
+ # Use fusion sort on tab from 10_000 to 100_000
+ if (use_tri == Function.FUSION_SORT):
+ fusion_sort(tab_generate)
+
+ # Use python sort on tab from 1_000_000 to 10_000_000
+ if (use_tri == Function.PYTHON_SORT):
+ tab_generate.sort()
+
+ end: float = time.time()
+ timer_tab.append(end-start)
+
+ return timer_tab
+
+
+def generate_index_tab_with_sort(use_tri: Function, element: int) -> int:
+ """Generate a tab with different length for different sort"""
+
+ # Generate a tab from 10 to 100
+ if (use_tri == Function.FACTORIAL):
+ return LOOP_REQUIRED[element + TEN_PART]
+
+ # Generate a tab from 10_000 to 100_000
+ elif (use_tri == Function.FUSION_SORT):
+ return LOOP_REQUIRED[element + TEN_THOUSAND_PART]
+
+ # Generate a tab from 1_000_000 to 10_000_000
+ elif (use_tri == Function.PYTHON_SORT):
+ return LOOP_REQUIRED[element + MILLION_PART]
+
+ # Generate a tab from 1_000 to 10_000
+ else:
+ return LOOP_REQUIRED[element + THOUSAND_PART]
+
+
+def write_result(timer_tab: list[float], use_tri: Function) -> None:
+ """write_result take tab of time and the sort for write them to user"""
+
+ for element in range(len(timer_tab)):
+ tab_generate = generate_index_tab_with_sort(use_tri, element)
+ # print time for function use
+ print("Le résultat pour " + str(tab_generate) +
+ " entrées est " + str(timer_tab[element]))
+
+
+# A décommenter
+# main(Function.GENERATE_ARRAY)
+# main(Function.SELECTION_SORT)
+# main(Function.INSERTION_SORT)
+# main(Function.FACTORIAL)
+# main(Function.FUSION_SORT)
+# main(Function.PYTHON_SORT)
+
+
+"""
+Le tri sort de python est environ 100 fois plus rapide que notre tri fusion.
+Sa complexité semble etre N
+
+Résultat du python sort :
+Le résultat pour 1000000 entrées est 0.10117459297180176
+Le résultat pour 2000000 entrées est 0.24679017066955566
+Le résultat pour 3000000 entrées est 0.31505799293518066
+Le résultat pour 4000000 entrées est 0.42998576164245605
+Le résultat pour 5000000 entrées est 0.537330150604248
+Le résultat pour 6000000 entrées est 0.6411576271057129
+Le résultat pour 7000000 entrées est 0.7325379848480225
+Le résultat pour 8000000 entrées est 0.9010059833526611
+Le résultat pour 9000000 entrées est 0.9867992401123047
+Le résultat pour 10000000 entrées est 1.0364351272583008
+"""
diff --git a/graphique courbes.xlsx b/graphique courbes.xlsx
new file mode 100644
index 0000000..840f936
Binary files /dev/null and b/graphique courbes.xlsx differ
diff --git a/sort/fusion.py b/sort/fusion.py
index 73a21d3..ba67867 100644
--- a/sort/fusion.py
+++ b/sort/fusion.py
@@ -1,2 +1,73 @@
+"""
+Le tri fusion prend un tableau.
+Si le tableau n'est pas vide ou n'est pas composé d'un seul élément,
+Python vas le divisé en deux en rappelant la meme fonction puis le merger.
+A chaque fois avant de merger les différents tableaux vont se réduire,
+jusqu'à ce que chaque tableau n'ait qu'un élément.
+Ensuite les tableaux vont se merger petit à petit en restant croissant et
+en formant au final un seul tableau
+"""
+
+
def sort(array: list[int]) -> list[int]:
- return array
+ """if length of array <=1 return array,
+ else return the merge of the left part and the right part of the array"""
+ if len(array) <= 1:
+ return array
+ return merge(sort(array[:len(array) // 2]), sort(array[len(array) // 2:]))
+
+
+def merge(array_left: list[int], array_right: list[int]) -> list[int]:
+ """We can erge two array together by forming a new array"""
+ """merge take two array and create one new array we both of them,
+ at every loop it takes the smallest number between two arrays
+ and remove from the array. Then we return new array created"""
+ new_array: list[int] = []
+
+ # We loop until the new array have all left and right values
+ while (True):
+
+ # if left or right list is empty then we can had the other
+ # at our new array and return it because it is sorted
+ if (array_left == []):
+ return new_array + array_right
+ elif (array_right == []):
+ return new_array + array_left
+
+ # if we suppose that the right and the left list is sorted then for
+ # have a new sort we just need to compare the first element of each
+ # list. We don't forget to add it at the new array and remove it
+ # because we add this value
+ if array_right[0] < array_left[0]:
+ new_array.append(array_right.pop(0))
+ else:
+ new_array.append(array_left.pop(0))
+
+
+"""
+Résultat :
+Le résultat pour 10000 entrées est 0.14179372787475586
+Le résultat pour 20000 entrées est 0.11987948417663574
+Le résultat pour 30000 entrées est 0.18050265312194824
+Le résultat pour 40000 entrées est 0.32453370094299316
+Le résultat pour 50000 entrées est 0.38787841796875
+Le résultat pour 60000 entrées est 0.49108314514160156
+Le résultat pour 70000 entrées est 0.6442813873291016
+Le résultat pour 80000 entrées est 0.9117996692657471
+Le résultat pour 90000 entrées est 0.9976096153259277
+Le résultat pour 100000 entrées est 1.2517235279083252
+
+Le tri fusion a l'air d'etre de complexité N*log(N)
+car on subdivise le tri en plusieurs tri de 1 élément.
+Puis on les recombine ensemble en les lisant.
+Le nombre d'étape ou on lit chaque valeur est
+a chaque fois que l'on merge des élements (2**k)>=n>(2**(k-1))+1.
+Il a donc k étapes ou on lit tout n. k est plus petit que N
+car on prend le k supérieur ou égal à N
+
+Si on considère que le tri par fusion a une complexité inférieur aux autres tri
+alors plus le nombre de valeur va augmenté
+plus l'écart entre les différentes complexités va augmenté également.
+Le tri sera toujours plus rapide qu'un tri avec une complexité supérieur
+
+"""
diff --git a/sort/insertion.py b/sort/insertion.py
index 73a21d3..f6f7d85 100644
--- a/sort/insertion.py
+++ b/sort/insertion.py
@@ -1,2 +1,52 @@
+"""
+Selon moi, Le tri par insertion va regarder chaque élément de la liste,
+les uns après les autres. A chaque fois, l'élément sera inséré
+entre deux autres éléments dans la liste déja trié,
+à la fin ou au début de la liste. On décalera tous les éléments triés
+après la nouvelle position, de cette nouvelle position
+vers l'ancienne position de l'élément
+"""
+
+
def sort(array: list[int]) -> list[int]:
+ """we sort a list of int by insert each number at their position"""
+
+ # The first loop represent element who search to sort
+ # and who will be insert between other number
+ for increment in range(len(array)):
+
+ # The secund loop go from the element who want to sort
+ # to the begin of the list
+ for number in range(increment, -1, -1):
+
+ # if the element size is between two element or
+ # if we reach the top of the list we insert it on list
+ if (array[increment] < array[number]
+ and (array[increment] >= array[number-1]
+ or number == 0)):
+
+ # We remove the element at increment
+ # position and we insert it at number position
+ array.insert(number, array.pop(increment))
return array
+
+
+"""
+Résultat :
+Le résultat pour 1000 entrées est 0.028821706771850586
+Le résultat pour 2000 entrées est 0.16448330879211426
+Le résultat pour 3000 entrées est 0.3654301166534424
+Le résultat pour 4000 entrées est 0.691014289855957
+Le résultat pour 5000 entrées est 1.0119526386260986
+Le résultat pour 6000 entrées est 1.4506659507751465
+Le résultat pour 7000 entrées est 2.0582830905914307
+Le résultat pour 8000 entrées est 2.850092887878418
+Le résultat pour 9000 entrées est 3.4401211738586426
+Le résultat pour 10000 entrées est 4.12743878364563
+
+Le tri par insertion est de complexité O(N**2)
+Car entre la première et la dernière valeur les entrées sont multiplé par 10
+alors que les temps sont multipliés par 100.
+De plus on a directement une double boucle dans le programme
+qui regarde tout les éléments, ce qui fait N*N donc N**2
+"""
diff --git a/sort/range.py b/sort/range.py
index fc252ab..34633da 100644
--- a/sort/range.py
+++ b/sort/range.py
@@ -1,2 +1,21 @@
+import random
+
+
def generate_array_of_number(array_size: int) -> list[int]:
- return []
+ """ return an array generate number randomly between 1 and 100"""
+ return [random.randint(0, 100) for i in range(array_size)]
+
+
+"""
+Résultat :
+Le résultat pour 1000000 entrées est 0.4899604320526123
+Le résultat pour 2000000 entrées est 0.9306461811065674
+Le résultat pour 3000000 entrées est 1.527371883392334
+Le résultat pour 4000000 entrées est 1.882685899734497
+Le résultat pour 5000000 entrées est 2.3193047046661377
+Le résultat pour 6000000 entrées est 3.0640199184417725
+Le résultat pour 7000000 entrées est 3.450831651687622
+Le résultat pour 8000000 entrées est 3.9937903881073
+Le résultat pour 9000000 entrées est 4.156933307647705
+Le résultat pour 10000000 entrées est 4.718446493148804
+"""
diff --git a/sort/recursion.py b/sort/recursion.py
index e7f4320..714f21a 100644
--- a/sort/recursion.py
+++ b/sort/recursion.py
@@ -1,2 +1,18 @@
def get_factorial(number: int) -> int:
- return number
+ """ return the factorial of the number"""
+ return number * get_factorial(number - 1) if number >= 1 else 1
+
+
+"""
+Résultat :
+Le résultat pour 10 entrées est 0.0
+Le résultat pour 20 entrées est 0.0
+Le résultat pour 30 entrées est 0.0
+Le résultat pour 40 entrées est 0.0
+Le résultat pour 50 entrées est 0.0
+Le résultat pour 60 entrées est 0.0
+Le résultat pour 70 entrées est 0.0
+Le résultat pour 80 entrées est 0.0
+Le résultat pour 90 entrées est 0.0
+Le résultat pour 100 entrées est 0.0
+"""
diff --git a/sort/selection.py b/sort/selection.py
index 73a21d3..b6a5b23 100644
--- a/sort/selection.py
+++ b/sort/selection.py
@@ -1,2 +1,53 @@
+"""
+Selon moi le tri par selection va regarder toute la liste,
+il va selectionner l'element le plus petit et le placer au début de la liste.
+Ensuite, il recommence avec le reste de la liste tant qu'elle n'est pas vide.
+"""
+
+
def sort(array: list[int]) -> list[int]:
+ """We sort a list of int by select the minimum number
+ each time for build the list"""
+
+ # The first loop can permit us to search the minimum of the list then
+ # we sort it and we search again the minimum until we reach end of list
+ for increment in range(len(array)):
+
+ # We define the minimum at the increment index
+ index_min: int = increment
+
+ # The second loop check all number between the index "increment" and
+ # the end of the list. Number before increment index are already sorted
+ for number in range(increment, len(array)):
+
+ # We modify index of the minimum if we find a number smaller.
+ # Each turn we search the minimum of rest of the list
+ # that we weren't sort
+ if array[index_min] > array[number]:
+ index_min = number
+
+ # We permut the minimum we find with the increment who represent
+ # the begin of the list we already search
+ array[increment], array[index_min] = array[index_min], array[increment]
return array
+
+
+"""
+Résultat :
+Le résultat pour 1000 entrées est 0.027270793914794922
+Le résultat pour 2000 entrées est 0.10175871849060059
+Le résultat pour 3000 entrées est 0.2276897430419922
+Le résultat pour 4000 entrées est 0.41335439682006836
+Le résultat pour 5000 entrées est 0.7159967422485352
+Le résultat pour 6000 entrées est 0.9541590213775635
+Le résultat pour 7000 entrées est 1.2389578819274902
+Le résultat pour 8000 entrées est 1.6056084632873535
+Le résultat pour 9000 entrées est 2.092197895050049
+Le résultat pour 10000 entrées est 2.540802001953125
+
+Le tri par selection est de complexité O(N**2)
+Car entre la première et la dernière valeur les entrées sont multiplé par 10
+alors que les temps sont multipliés par 100.
+De plus on a directement une double boucle dans le programme
+qui regarde tout les éléments, ce qui fait N*N donc N**2
+"""