diff --git a/README.md b/README.md
index 74f925a..fcbed10 100644
--- a/README.md
+++ b/README.md
@@ -53,11 +53,33 @@ Mesurez combien de temps prend python à générer un tableau composés de :
- ...
- 10 000 000 entrées
+*Time to generate array of 1000000 numbers: 0.7310469150543213*
+
+*Time to generate array of 2000000 numbers: 1.1986496448516846*
+
+*Time to generate array of 3000000 numbers: 1.6297695636749268*
+
+*Time to generate array of 4000000 numbers: 2.190520763397217*
+
+*Time to generate array of 5000000 numbers: 2.74592661857605*
+
+*Time to generate array of 6000000 numbers: 3.341700553894043*
+
+*Time to generate array of 7000000 numbers: 3.849144697189331*
+
+*Time to generate array of 8000000 numbers: 4.3899266719818115*
+
+*Time to generate array of 9000000 numbers: 4.8259007930755615*
+
+*Time to generate array of 10000000 numbers: 5.432266473770142*
+
**Astuce** : vous pouvez écrire les nombres avec des underscores pour mieux les lire : `1_000_000`
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 ? *La courbe semble évoluer de façon linéaire. La courbe la plus ressemblante est la courbe n log n.*
@@ -73,9 +95,8 @@ Comment vous semble évoluer la courbe ? Observez bien les différentes courbes
Observez attentivement l'animation de tri par sélection ci-dessous pour en comprendre le fonctionnement.
-
-
-É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 ?
+*On sélectionne la première valeur non triée du tableau, et on la marque comme étant la plus petite valeur du tableau. On parcourt les autres valeurs en sélectionannt une valeur plus petite s'il en existe une. Ensuite, on place la plus petite valeur au début du tableau et on répète toute l'opération avec la deuxième valeur du tableau jusqu'à ce qu'il soit trié.*
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 +109,11 @@ 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 sélection semble être de complexité O(n^2) et cela semble cohérent avec les deux boucles for imbriquées dans mon code.*
### 2. Tri par insertion
@@ -96,7 +121,7 @@ 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 ? *On prend la première valeur non traitée du tableau et on parcourt les valeurs vers la gauche jusqu'à temps d'insérer la valeur sélectionnée si elle est plus petite que la valeur parcourue.*
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 +134,9 @@ 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 semble avoir une complexité en O(n^2). Cela est logique par rapport au code implémenté (une boucle for et une boucle while).*
### 3. Tri par fusion
@@ -154,7 +181,7 @@ 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 tableau en entrée est séparé en deux jusqu'à ce que les tableaux ne soient que de taille 1, puis ils sont fusionnés deux à deux jusqu'à obtenir un tableau trié de la taille d'origine.*
Complétez la fonction `sort` du fichier `sort/fusion.py` en suivant les instructions suivantes.
@@ -174,9 +201,11 @@ 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 fusion semble avoir une complexité en O(n log n). Cela semble logique par rapport à monde code.*
-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 ? *Le tri par fusion est en général plus rapide que l'insertion et la sélection sur les tableaux de très grandes tailles. Sur les petits tableaux, il est moins rapide.*
### 4. sort()
@@ -184,6 +213,10 @@ 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 ;)
+*Il est en effet bien plus rapide : *
+
+
+
## Pour rendre ce TP
Merci de faire une Pull Request vers ce repository.
diff --git a/__main__.py b/__main__.py
index 98a585e..0b69240 100644
--- a/__main__.py
+++ b/__main__.py
@@ -1,5 +1,73 @@
+import sort.range
+import sort.selection as selection
+import matplotlib.pyplot as plt
+import sort.insertion as insertion
+import time
+import sort.fusion as fusion
+
+
+def get_1k_10k_arrays_execution_times(sorting_method) -> tuple[list[float],
+ list[int]]:
+ """Returns the execution times and array sizes of
+ generated arrays of 1k to 10k numbers with a step of 1k."""
+
+ times: list[float] = []
+ sizes: list[int] = []
+
+ for i in range(1, 11):
+ array_size: int = 1000*i
+ array: list[int] = sort.range.generate_array_of_number(array_size)
+ execution_time: float = get_execution_time(array, sorting_method)
+ print(f"Execution time for {array_size} numbers: {execution_time} s")
+ sizes.append(array_size)
+ times.append(execution_time)
+
+ return times, sizes
+
+
+def get_execution_time(array: list[int], sorting_method) -> float:
+ """Returns the execution time for sorting the given array
+ with given sorting method."""
+
+ start: float = time.time()
+ sorting_method(array)
+ end: float = time.time()
+ return end - start
+
+
+def draw_graph(sizes: list[int], times: list[float], title: str):
+ """Draws a graph with the given input sizes and execution times."""
+
+ plt.plot(sizes, times, 'ro-')
+ plt.xlabel('Input size')
+ plt.ylabel('Execution time (s)')
+ plt.title(title)
+ plt.show()
+
+
def main():
- print("Hello world")
+ """Main function."""
+
+ sort.range.execution_time_for_array_of_numbers()
+
+ sizes: list[int] = []
+ times: list[float] = []
+
+ # Selection sort
+ times, sizes = get_1k_10k_arrays_execution_times(selection.sort)
+ draw_graph(sizes, times, "Selection sort")
+
+ # Insertion sort
+ times, sizes = get_1k_10k_arrays_execution_times(insertion.sort)
+ draw_graph(sizes, times, "Insertion sort")
+
+ # Fusion sort
+ times, sizes = get_1k_10k_arrays_execution_times(fusion.sort)
+ draw_graph(sizes, times, "Fusion sort")
+
+ # Python built-in sort
+ times, sizes = get_1k_10k_arrays_execution_times(sorted)
+ draw_graph(sizes, times, "Python built-in sort")
main()
diff --git a/graphs-sorts.xlsx b/graphs-sorts.xlsx
new file mode 100644
index 0000000..bca18e0
Binary files /dev/null and b/graphs-sorts.xlsx differ
diff --git a/graphs/Generation-times.png b/graphs/Generation-times.png
new file mode 100644
index 0000000..27491f9
Binary files /dev/null and b/graphs/Generation-times.png differ
diff --git a/graphs/fusion-sort.png b/graphs/fusion-sort.png
new file mode 100644
index 0000000..a84c028
Binary files /dev/null and b/graphs/fusion-sort.png differ
diff --git a/graphs/insertion-sort.png b/graphs/insertion-sort.png
new file mode 100644
index 0000000..8bde718
Binary files /dev/null and b/graphs/insertion-sort.png differ
diff --git a/graphs/python-built-in-sort.png b/graphs/python-built-in-sort.png
new file mode 100644
index 0000000..9fe8e61
Binary files /dev/null and b/graphs/python-built-in-sort.png differ
diff --git a/graphs/selection-sort.png b/graphs/selection-sort.png
new file mode 100644
index 0000000..1a07178
Binary files /dev/null and b/graphs/selection-sort.png differ
diff --git a/sort/fusion.py b/sort/fusion.py
index 73a21d3..a60e922 100644
--- a/sort/fusion.py
+++ b/sort/fusion.py
@@ -1,2 +1,32 @@
+def merge(left: list[int], right: list[int]) -> list[int]:
+ """Merges two sorted arrays into one sorted array."""
+
+ result: list[int] = []
+ left_index: int = 0
+ right_index: int = 0
+
+ while left_index < len(left) and right_index < len(right):
+ if left[left_index] < right[right_index]:
+ result.append(left[left_index])
+ left_index += 1
+ else:
+ result.append(right[right_index])
+ right_index += 1
+
+ result.extend(left[left_index:])
+ result.extend(right[right_index:])
+
+ return result
+
+
def sort(array: list[int]) -> list[int]:
- return array
+ """Sorts the given array using fusion sort."""
+
+ if len(array) <= 1:
+ return array
+
+ mid = len(array) // 2
+ left_half = sort(array[:mid])
+ right_half = sort(array[mid:])
+
+ return merge(left_half, right_half)
diff --git a/sort/insertion.py b/sort/insertion.py
index 73a21d3..87de189 100644
--- a/sort/insertion.py
+++ b/sort/insertion.py
@@ -1,2 +1,11 @@
def sort(array: list[int]) -> list[int]:
+ """Sorts the given array using insertion sort."""
+
+ for index in range(1, len(array)):
+ key: int = array[index]
+ index_2 = index - 1
+ while index_2 >= 0 and key < array[index_2]:
+ array[index_2 + 1] = array[index_2]
+ index_2 -= 1
+ array[index_2 + 1] = key
return array
diff --git a/sort/range.py b/sort/range.py
index fc252ab..201f44c 100644
--- a/sort/range.py
+++ b/sort/range.py
@@ -1,2 +1,23 @@
+import time
+import random
+
+
def generate_array_of_number(array_size: int) -> list[int]:
- return []
+ """Returns an array of the given size with random
+ numbers between 0 and 100."""
+
+ array: list[int] = []
+ for i in range(array_size):
+ array.append(random.randint(0, 100))
+ return array
+
+
+def execution_time_for_array_of_numbers():
+ """Prints the execution time for generating
+ an array of numbers."""
+
+ for i in range(1, 11):
+ start: float = time.time()
+ generate_array_of_number(1000000*i)
+ end: float = time.time()
+ print(f"Time to generate array of {1000000*i} numbers: {end - start}")
diff --git a/sort/recursion.py b/sort/recursion.py
index e7f4320..15db9e7 100644
--- a/sort/recursion.py
+++ b/sort/recursion.py
@@ -1,2 +1,7 @@
def get_factorial(number: int) -> int:
- return number
+ """Returns the factorial of the given number."""
+
+ if number == 0:
+ return 1
+ else:
+ return number * get_factorial(number - 1)
diff --git a/sort/selection.py b/sort/selection.py
index 73a21d3..5432396 100644
--- a/sort/selection.py
+++ b/sort/selection.py
@@ -1,2 +1,11 @@
-def sort(array: list[int]) -> list[int]:
- return array
+# Selection sort
+def sort(arr) -> list[int]:
+ """Sorts the given array using selection sort."""
+
+ for i in range(len(arr)):
+ min_idx: int = i
+ for j in range(i + 1, len(arr)):
+ if arr[min_idx] > arr[j]:
+ min_idx = j
+ arr[i], arr[min_idx] = arr[min_idx], arr[i]
+ return arr