diff --git a/README.md b/README.md
index 74f925a..acafc04 100644
--- a/README.md
+++ b/README.md
@@ -48,16 +48,24 @@ Complétez la fonction `generate_array_of_number` du fichier `sort/range.py` pou
Mesurez combien de temps prend python à générer un tableau composés de :
- 1 000 000 entrées
+= Temps écoulé : 0.5889501571655273
- 2 000 000 entrées
+= Temps écoulé : 1.1459660530090332
- 3 000 000 entrées
+= Temps écoulé : 1.7308893203735352
- ...
- 10 000 000 entrées
+= Temps écoulé : 5.838363170623779
+
+
**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 ?
+
+==> Un algorithme de complexité O(n)
@@ -75,20 +83,32 @@ 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 ?
+
+On a deux valeurs qui se comparent entre elles dans le tableau. Les deux le parcourent progressivement, une case à la fois. Quand la première valeur (en bleu) est plus grande que la seconde (en rouge) on stoppe la progression de la valeur rouge. Elle reprend et saute à la position derrière la valeur bleue dès que cette dernière devient plus petite. Quand la première valeur (en bleu) atteint la fin du tableau, on inverse la deuxième valeur en rouge avec la dernière valeur triée. On répète ce processus jusqu'à la fin du tableau.
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 :
-- 1000 entrées
-- 2000 entrées
-- ...
-- 10000 entrées
+Temps écoulé : 0.04999995231628418
+Temps écoulé : 0.2057938575744629
+Temps écoulé : 0.46288228034973145
+Temps écoulé : 0.8257730007171631
+Temps écoulé : 1.2953431606292725
+Temps écoulé : 1.8596084117889404
+Temps écoulé : 2.533503532409668
+Temps écoulé : 3.2937428951263428
+Temps écoulé : 4.1926844120025635
+Temps écoulé : 5.192129850387573
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é ?
+
+==> complexité O(n²), la durée du processus (et la complexité) est décuplée du fait de la boucle imbriquée
### 2. Tri par insertion
@@ -96,7 +116,9 @@ 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 ?
+
+Dans un tableau à entiers mélangés, on va progressivement le parcourir en placant chaque entier plus ou moins en arrière ou pas en fonction de sa grandeur par rapport aux précédents entiers parcourus. On commence à l'index 1 et on continue jusqu'à la fin du tableau. On compare le dernier élément de la portion déjà triée/parcourue avec le suivant, si le suivant est plus petit, on va le placer dans la bonne position dans la portion déjà 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.
@@ -106,10 +128,24 @@ Mesurez le temps d'éxécution pour un tableau de :
- 2000 entrées
- ...
- 10000 entrées
+Temps écoulé : 0.037030696868896484
+Temps écoulé : 0.1215670108795166
+Temps écoulé : 0.2595536708831787
+Temps écoulé : 0.4952089786529541
+Temps écoulé : 0.7450480461120605
+Temps écoulé : 1.0163190364837646
+Temps écoulé : 1.4117050170898438
+Temps écoulé : 1.8339478969573975
+Temps écoulé : 2.30259108543396
+Temps écoulé : 2.8572349548339844
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é ?
+
+==> complexité O(n²), la durée du processus (et la complexité) est décuplée du fait de la boucle imbriquée
### 3. Tri par fusion
@@ -154,7 +190,9 @@ 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 ?
+
+Dans un tableau à entiers mélangés, on va le diviser par deux plusieurs fois de manière à avoir plusieurs groupes jusqu'à ce qu'il ne reste que plusieurs petits morceaux de 1 entier. On va ensuite prendre par groupe de deux chaque petit morceau et trier, puis regrouper les groupes de deux en quatre, et re-trier, puis regrouper en huit, et ainsi de suite. À la fin, on se retrouve avec le tableau d'origine reconstitué et trié.
Complétez la fonction `sort` du fichier `sort/fusion.py` en suivant les instructions suivantes.
@@ -172,11 +210,26 @@ Mesurez le temps d'éxécution pour un tableau de :
- ...
- 10000 entrées
+Temps écoulé : 0.010993719100952148
+Temps écoulé : 0.020018577575683594
+Temps écoulé : 0.032997846603393555
+Temps écoulé : 0.019037485122680664
+Temps écoulé : 0.023550033569335938
+Temps écoulé : 0.02600574493408203
+Temps écoulé : 0.031022071838378906
+Temps écoulé : 0.03447532653808594
+Temps écoulé : 0.04099726676940918
+Temps écoulé : 0.0455470085144043
+
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é ?
-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*
+==> complexité O(n*log 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 ?
### 4. sort()
@@ -184,6 +237,19 @@ 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 ;)
+Temps écoulé : 0.0010001659393310547
+Temps écoulé : 0.001971006393432617
+Temps écoulé : 0.0030002593994140625
+Temps écoulé : 0.0030336380004882812
+Temps écoulé : 0.003978252410888672
+Temps écoulé : 0.0049991607666015625
+Temps écoulé : 0.00602269172668457
+Temps écoulé : 0.005975008010864258
+Temps écoulé : 0.007005453109741211
+Temps écoulé : 0.007962942123413086
+
+La durée du processus est en effet inférieure à 0.01 seconde dans la plupart des cas.
+
## Pour rendre ce TP
Merci de faire une Pull Request vers ce repository.
diff --git a/__main__.py b/__main__.py
index 98a585e..ab7cad9 100644
--- a/__main__.py
+++ b/__main__.py
@@ -1,5 +1,9 @@
-def main():
- print("Hello world")
+from sort.range import generate_array_of_number
+from sort.selection import sort
+def main():
+ arr = generate_array_of_number(100)
+ sortarr = sort(arr)
+ print(sortarr)
main()
diff --git a/img/g1.png b/img/g1.png
new file mode 100644
index 0000000..423acdb
Binary files /dev/null and b/img/g1.png differ
diff --git a/img/g2.png b/img/g2.png
new file mode 100644
index 0000000..0f15bdb
Binary files /dev/null and b/img/g2.png differ
diff --git a/img/g3.png b/img/g3.png
new file mode 100644
index 0000000..28388a6
Binary files /dev/null and b/img/g3.png differ
diff --git a/img/g4.png b/img/g4.png
new file mode 100644
index 0000000..77eb9a6
Binary files /dev/null and b/img/g4.png differ
diff --git a/sort/count.py b/sort/count.py
new file mode 100644
index 0000000..277ab69
--- /dev/null
+++ b/sort/count.py
@@ -0,0 +1,9 @@
+import time
+
+def count_time():
+ """Count time:
+ Simple method to count time between the start and end of an operation"""
+ start: float = time.time()
+ # do something
+ end: float = time.time()
+ print("Temps écoulé :", end - start)
diff --git a/sort/fusion.py b/sort/fusion.py
index 73a21d3..a393226 100644
--- a/sort/fusion.py
+++ b/sort/fusion.py
@@ -1,2 +1,42 @@
def sort(array: list[int]) -> list[int]:
- return array
+ """Merge Sort Part 1:
+ Continuously (recursively) split the given array in two,
+ the result is merged and returned"""
+ length = len(array)
+
+ if length <= 1:
+ return array
+
+ # Split the array in two and sort each
+ middle = length // 2
+ left = sort(array[:middle])
+ right = sort(array[middle:])
+
+ # Merge the two sorted halves
+ return merge(left, right)
+
+
+def merge(left, right):
+ """Merge Sort Part 2:
+ Sort and merge two given halveds of an array"""
+ merged_list = []
+ left_i = 0
+ right_i = 0
+
+ # Merge the two lists while there are elements in both
+ while left_i < len(left) and right_i < len(right):
+ if left[left_i] < right[right_i]:
+ # Place left element first as it's less than right element
+ merged_list.append(left[left_i])
+ left_i += 1
+ else:
+ # Place right element first as it's less than left element
+ merged_list.append(right[right_i])
+ right_i += 1
+
+ # Takes the remaining elements in the slice
+ # and appends them to the end of merged_list (they're already sorted)
+ merged_list.extend(left[left_i:])
+ merged_list.extend(right[right_i:])
+
+ return merged_list
diff --git a/sort/graph.py b/sort/graph.py
new file mode 100644
index 0000000..b1f7a2d
--- /dev/null
+++ b/sort/graph.py
@@ -0,0 +1,24 @@
+import matplotlib.pyplot as plt
+
+x_values = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]
+y_values = [
+ 0.010993719100952148,
+ 0.020018577575683594,
+ 0.032997846603393555,
+ 0.019037485122680664,
+ 0.023550033569335938,
+ 0.02600574493408203,
+ 0.031022071838378906,
+ 0.03447532653808594,
+ 0.04099726676940918,
+ 0.0455470085144043,
+]
+
+plt.plot(x_values, y_values, marker='o', linestyle='-', color='r')
+
+
+plt.xlabel('Array Entries')
+plt.ylabel('Time of execution (seconds)')
+plt.title('Y Execution Time of X elements in Array')
+
+plt.show()
\ No newline at end of file
diff --git a/sort/insertion.py b/sort/insertion.py
index 73a21d3..a2db4fb 100644
--- a/sort/insertion.py
+++ b/sort/insertion.py
@@ -1,2 +1,27 @@
def sort(array: list[int]) -> list[int]:
+ """
+ Insertion Sort:
+ Sort an array one element at a time by iteratively shift elements to their correct positions
+ in the array
+ """
+
+ # Determine the length of the array
+ length = len(array)
+
+ # The loop is starting from the second element, index 1
+ for i in range(1, length):
+ # The current element we're comparing against the last sorted element
+ current_element = array[i]
+
+ # Last sorted item idx needed to find the position where we need to put current element
+ last_sorted_index = i-1
+
+ # Shift elements of the sorted portion to the right if they are larger than current element
+ while last_sorted_index >= 0 and array[last_sorted_index] > current_element:
+ array[last_sorted_index+1] = array[last_sorted_index]
+ last_sorted_index -= 1
+
+ # Place current element into its correct position
+ array[last_sorted_index + 1] = current_element
+
return array
diff --git a/sort/range.py b/sort/range.py
index fc252ab..2827a2a 100644
--- a/sort/range.py
+++ b/sort/range.py
@@ -1,2 +1,7 @@
+import random
+
def generate_array_of_number(array_size: int) -> list[int]:
- return []
+ """Generate a random list of numbers
+ """
+ array = [random.randint(0, 100) for i in range(array_size)]
+ return array
diff --git a/sort/recursion.py b/sort/recursion.py
index e7f4320..5668e7e 100644
--- a/sort/recursion.py
+++ b/sort/recursion.py
@@ -1,2 +1,3 @@
def get_factorial(number: int) -> int:
- return number
+ """Get the factorial of a number using recursion"""
+ return get_factorial(number-1) * number if number > 1 else 1
diff --git a/sort/selection.py b/sort/selection.py
index 73a21d3..0d4eadc 100644
--- a/sort/selection.py
+++ b/sort/selection.py
@@ -1,2 +1,32 @@
def sort(array: list[int]) -> list[int]:
+ """Selection Sort:
+ Continuously explore a given list, compare adjacent elements and swaps them
+ if they are in the wrong order
+ """
+
+ # Determine the length of the array
+ length = len(array)
+
+ # Do length-1 turns through the array (breaks if finished = False)
+ for turn in range(length - 1):
+ # Flag to check if any swap has been made in this turn
+ # (=> Iteration with no swap means that every element has been checked
+ # and thus the array has every number in order)
+ swap = False
+
+ # Traverse the array from 0 to length-turn-1
+ for i in range(length - turn - 1):
+ i1 = i
+ i2 = i + 1
+ # Compare the current element with the next one
+ if array[i1] > array[i2]:
+ # Swap them if the current element is greater than the next one
+ array[i1], array[i2] = array[i2], array[i1]
+ # A swap was made
+ swap = True
+
+ # If no swaps were made, the array is sorted
+ if not swap:
+ break
+
return array