diff --git a/.gitignore b/.gitignore
index ed8ebf5..341e31e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-__pycache__
\ No newline at end of file
+__pycache__
+.idea
\ No newline at end of file
diff --git a/README.md b/README.md
index 74f925a..cbbbd0c 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +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*
+* La courbe semble évoluer de manière linéaire. La plus ressemblante à notre situation est la courbe O(n).
@@ -77,6 +80,8 @@ 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*
+* Le tri par sélection consiste à parcourir le tableau pour trouver le plus petit élément, puis à le placer en première position. On recommence ensuite avec le deuxième plus petit élément, et ainsi de suite jusqu'à ce que le tableau 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.
Mesurez le temps d'éxécution pour un tableau de :
@@ -88,8 +93,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*
+* La complexité de notre fonction de tri est O(n²). C'est logique par rapport au code que nous avons implémenté car nous avons deux boucles imbriquées.
+
### 2. Tri par insertion
Observez attentivement l'animation de tri par insertion ci-dessous pour en comprendre le fonctionnement.
@@ -98,6 +107,8 @@ 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*
+* Le tri par insertion consiste à parcourir le tableau en plaçant au fur et à mesure chaque élément à sa place dans le tableau trié. Pour cela, on compare l'élément avec les éléments précédents, et on les décale vers la droite tant que l'élément est plus petit.
+
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,8 +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*
+* La complexité de notre fonction de tri est O(n²). C'est logique par rapport au code que nous avons implémenté car nous avons deux boucles imbriquées.
+
### 3. Tri par fusion
Le tri par fusion est plus complexe : il utilise en effet la récursion, c'est à dire une fonction qui s'appelle elle-même.
@@ -156,6 +171,8 @@ 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*
+* Le tri par fusion consiste à diviser le tableau en deux, puis de diviser chaque moitié jusqu'à ce qu'il ne reste plus que 1 ou 2 éléments. On trie ces éléments, puis on fusionne les tableaux, on les tries etc... jusqu'à ce qu'il ne reste plus qu'un seul tableau trié.
+
Complétez la fonction `sort` du fichier `sort/fusion.py` en suivant les instructions suivantes.
Il vous faudra deux fonctions :
@@ -174,16 +191,26 @@ 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é ?
+* La complexité de notre fonction de tri est O(n log n).
+ça peut s'expliquer par le fait que nous divisons le tableau en deux à chaque fois, et que nous fusionnons les tableaux en les triant.
+la division du tableau en deux se fait en O(log n) et la fusion se fait en O(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*
+* Le tri par fusion est plus rapide que les autres tris abordés pour toutes les tailles de tableaux.
+
### 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 ;)
+* après avoir fait plusieurs tests, il s'avère que la fonction sort() de python est plus rapide que le tri fusion qui était pourtant le plus rapide des tris que nous avons implémentés.
+
## Pour rendre ce TP
Merci de faire une Pull Request vers ce repository.
diff --git a/__main__.py b/__main__.py
index 98a585e..bcf08a2 100644
--- a/__main__.py
+++ b/__main__.py
@@ -1,5 +1,46 @@
-def main():
- print("Hello world")
+import time
+from typing import Callable
+
+from sort import selection, insertion, fusion
+from sort.range import generate_array_of_number
+
+
+def measure_time(sort_function: Callable[[list[int]], list[int]],
+ array: list[int]) -> float:
+ """
+ Measure the time it takes to run a sorting function on an array.
+
+ :param sort_function: The sorting function to be measured.
+ :param array: The array to be sorted.
+ :return: The time taken to run the sorting function on the array.
+ """
+ start: float = time.time()
+ sort_function(array)
+ end: float = time.time()
+ return end - start
+
+
+def main() -> None:
+ sizes: list[int] = [1000 * i for i in
+ range(1, 11)] # 1000, 2000, ..., 10000
+
+ algorithms: list[Callable[[list[int]], list[int]]] = [
+ selection.sort,
+ insertion.sort,
+ fusion.sort,
+ sorted
+ ]
+ algorithms_names: list[str] = ["Selection", "Insertion", "Fusion",
+ "Python's sorted"]
+
+ # Loop to measure and print the time taken by each sorting algorithm for
+ # different array sizes
+ for algorithm, name in zip(algorithms, algorithms_names):
+ print(f"\nTime measurements for {name} sort:")
+ for size in sizes:
+ array: list[int] = generate_array_of_number(size)
+ elapsed_time: float = measure_time(algorithm, array)
+ print(f"Size: {size}, Time: {elapsed_time} seconds")
main()
diff --git a/img/fusion graph.png b/img/fusion graph.png
new file mode 100644
index 0000000..05e2f4f
Binary files /dev/null and b/img/fusion graph.png differ
diff --git a/img/insertion graph.png b/img/insertion graph.png
new file mode 100644
index 0000000..196d2f5
Binary files /dev/null and b/img/insertion graph.png differ
diff --git a/img/selection graph.png b/img/selection graph.png
new file mode 100644
index 0000000..4b2602a
Binary files /dev/null and b/img/selection graph.png differ
diff --git a/img/tableau random list.png b/img/tableau random list.png
new file mode 100644
index 0000000..1a78b15
Binary files /dev/null and b/img/tableau random list.png differ
diff --git a/sort/fusion.py b/sort/fusion.py
index 73a21d3..bd608b9 100644
--- a/sort/fusion.py
+++ b/sort/fusion.py
@@ -1,2 +1,44 @@
def sort(array: list[int]) -> list[int]:
- return array
+ """
+ Sorts an array in ascending order using the merge sort algorithm.
+
+ :param array: The array to be sorted.
+ :return: The sorted array.
+ """
+ if len(array) <= 1:
+ return array
+
+ # Divide the array into two halves and sort each half.
+ mid: int = len(array) // 2
+ left: list[int] = sort(array[:mid])
+ right: list[int] = sort(array[mid:])
+
+ return merge(left, right)
+
+
+def merge(left_array: list[int], right_array: list[int]) -> list[int]:
+ """
+ Merge two lists in a sorted order.
+
+ :param left_array: The first list to be merged.
+ :param right_array: The second list to be merged.
+ :return: A new list that is a sorted merge of the two input lists.
+ """
+ result: list[int] = []
+ left_index: int = 0
+ right_index: int = 0
+
+ while left_index < len(left_array) and right_index < len(right_array):
+ # Append the smaller element between
+ # left_array[left_index] and right_array[right_index] to the result
+ if left_array[left_index] < right_array[right_index]:
+ result.append(left_array[left_index])
+ left_index += 1
+ else:
+ result.append(right_array[right_index])
+ right_index += 1
+
+ # Append any remaining elements in left and right to the result
+ result.extend(left_array[left_index:])
+ result.extend(right_array[right_index:])
+ return result
diff --git a/sort/insertion.py b/sort/insertion.py
index 73a21d3..b5dafc9 100644
--- a/sort/insertion.py
+++ b/sort/insertion.py
@@ -1,2 +1,14 @@
def sort(array: list[int]) -> list[int]:
+ """
+ Sort the given array in ascending order using the insertion sort algorithm.
+
+ :param array: The array to be sorted.
+ :return: The sorted array.
+ """
+ for i in range(1, len(array)):
+ value_to_insert: int = array[i]
+ j: int = i - 1
+ while j >= 0 and value_to_insert < array[j]:
+ j -= 1
+ array.insert(j + 1, array.pop(i))
return array
diff --git a/sort/range.py b/sort/range.py
index fc252ab..bb4b7c7 100644
--- a/sort/range.py
+++ b/sort/range.py
@@ -1,2 +1,11 @@
-def generate_array_of_number(array_size: int) -> list[int]:
- return []
+import random
+
+
+def generate_array_of_number(n: int) -> list:
+ """
+ Generate a list of random integers.
+ :param n: The number of elements to generate in the array.
+ :return: A list of random integers with 'n' elements.
+ """
+ array: list[int] = [random.randint(0, 100) for _ in range(n)]
+ return array
diff --git a/sort/recursion.py b/sort/recursion.py
index e7f4320..acc2bab 100644
--- a/sort/recursion.py
+++ b/sort/recursion.py
@@ -1,2 +1,8 @@
def get_factorial(number: int) -> int:
- return number
+ """
+ Calculate the factorial of a given number.
+
+ :param number: The number for which the factorial needs to be calculated.
+ :return: The factorial of the given number.
+ """
+ return 1 if number == 0 else number * get_factorial(number - 1)
diff --git a/sort/selection.py b/sort/selection.py
index 73a21d3..adc8c2b 100644
--- a/sort/selection.py
+++ b/sort/selection.py
@@ -1,2 +1,19 @@
def sort(array: list[int]) -> list[int]:
+ """
+ Sorts an array in ascending order using the selection sort algorithm.
+
+ :param array: A list of integers to be sorted.
+ :return: The sorted list.
+ """
+ for i in range(len(array)):
+ min_index: int = i
+
+ # Find the index of the smallest element
+ # in the unsorted part of the array
+ for j in range(i + 1, len(array)):
+ if array[j] < array[min_index]:
+ min_index = j
+
+ # Swap the smallest element with the first element of the unsorted part
+ array[i], array[min_index] = array[min_index], array[i]
return array