diff --git a/src/appr/algo1/algo-progs.md b/src/appr/algo1/algo-progs.md index 24a1ee71..d4cab1b1 100644 --- a/src/appr/algo1/algo-progs.md +++ b/src/appr/algo1/algo-progs.md @@ -159,7 +159,7 @@ Mais est-ce que derrière chaque programme se cache un algorithme ? ## Exercices -````{admonition} Exercice 3.1.1. Jeu de la devinette 🔌 +````{exercise} Jeu de la devinette 🔌 :class: note Ecrire le programme suivant : le programme pense à un nombre au hasard. Lorsque vous lui proposez un nombre, il vous dit si « c'est plus » ou si « c'est moins » jusqu'à ce que vous trouvez le bon nombre. Conseil : utiliser le module Python *random*. @@ -168,7 +168,7 @@ Y a-t-il une stratégie gagnante ? ```` -````{admonition} Exercice 3.1.2. Plus petit nombre 🔌 +````{exercise} Plus petit nombre 🔌 :class: note Transcrire l’algorithme de l’exercice qui permet de déterminer le plus petit nombre d’une liste, en un programme Python. @@ -176,7 +176,7 @@ Transcrire l’algorithme de l’exercice qui permet de déterminer le plus peti ```` -````{admonition} Exercice 3.1.3. Programmes de tri 🔌 +````{exercise} Programmes de tri 🔌 :class: note Implémenter le tri à bulles et/ou le tri par insertion vus au cours. @@ -215,7 +215,7 @@ Lancer votre programme avec 100000 éléments et comparez le temps obtenu avec v ```` --> -````{admonition} Exercice 3.1.4. Tri de Bogo🔌 +````{exercise} Tri de Bogo🔌 :class: note Coder l’algorithme du tri de Bogo en Python (voir chapitre 2 : Le saviez-vous ?). @@ -227,7 +227,7 @@ A partir de quelle taille de liste cet algorithme est-il inutilisable ? ```` -````{admonition} Exercice 3.1.5. Fibonacci 🔌 +````{exercise} Fibonacci 🔌 :class: note Ecrire un algorithme qui calcule la suite des nombres de Fibonacci. diff --git a/src/appr/algo1/algorithmes.md b/src/appr/algo1/algorithmes.md index d17b4e43..fa6133ef 100644 --- a/src/appr/algo1/algorithmes.md +++ b/src/appr/algo1/algorithmes.md @@ -1,4 +1,5 @@ + # Les algorithmes La première question que l'on va se poser est la suivante : qu'est-ce qu'un {glo}`algo|algorithme` ? Est-ce la même chose qu'un programme informatique, ou s'agit-il d'autre chose ? @@ -114,7 +115,7 @@ Lisez bien l'algorithme présenté ci-dessus. Quel problème cet algorithme perm ```` -`````{solution} +`````{solution} Algorithme mystère ````{dropdown} Cliquer ici pour voir la réponse :animate: fade-in-slide-down diff --git a/src/appr/algo1/index.md b/src/appr/algo1/index.md index bcd76cab..d7e71ea3 100644 --- a/src/appr/algo1/index.md +++ b/src/appr/algo1/index.md @@ -49,10 +49,26 @@ (algo1)= # Algorithmique I -Nous avons tous entendu parler des algorithmes. Normal, c’est le mot à la mode et que tout le monde utilise sans vraiment le comprendre. Ils sont partout, ils font toutes sortes de choses, ils nous manipulent. Pourquoi en parle-t-on de la même manière que des extraterrestres ? Dans ce cours, nous allons tenter de revenir sur terre, parce que les algorithmes ce n’est pas si compliqué que ça. On apprendra à les définir, à les faire fonctionner et surtout à reconnaître la différence entre un « bon » et un « mauvais » algorithme. +## Quoi ? +Nous avons tous entendu parler des algorithmes dans les médias. Normal, c’est le mot à la mode et que tout le monde utilise sans vraiment le comprendre. Ils sont partout, ils font toutes sortes de choses, même nous manipuler. Pourquoi en parle-t-on de la même manière que des extraterrestres ? Dans ce cours, nous allons tenter de revenir sur terre, parce que les algorithmes ce n’est pas si compliqué que ça. On apprendra à les définir, à les faire marcher et surtout à reconnaître la différence entre un programme et un algorithme, ainsi qu'entre un « bon » et un « mauvais » algorithme. -## Objectifs + + +## Pourquoi ? + +Les algorithmes existent depuis des millénaires. On doit le nom d'algorithme à Al-Khwârizmî, mathématicien perse né en l'an 780 dont les ouvrages ont contribué à la popularisation des chiffres arabes en Europe, ainsi que la classification de plusieurs algorithmes connus à ce moment. D'ailleurs l'algorithme le plus connu, l'algorithme d'Euclide, date environ de l'an 300 av J.-C. et permet de calculer le plus grand diviseur commun de deux nombres. Si Euclide a bien laissé des traces écrites de cet algorithme, il est vraisemblable qu'il ait puisé cette connaissance auprès de disciples de Pythagore lui-même. + +Les algorithmes sont devenus très populaires aujourd'hui grâce à la machine qui a permis de les automatiser. Que ce soit dans votre smartphone, sur un ordinateur ou dans un système embarqué, ils permettent de résoudre une quantité de problèmes, facilement et avec une rapidité impressionnante. + +## Comment ? + +Dans un premier temps nous allons nous intéresser à la notion même d'algorithme : qu'est-ce qui caractérise un algorithme et comment le faire exécuter par une machine ? Nous allons voir que pour un problème donné il existe de nombreuses solutions, mais que toutes ces solutions ne sont pas de *bonnes* solutions, selon le contexte dans lequel on tente de résoudre le problème. Da + + +## Objectifs d'apprentissage À la fin de ce chapitre, vous saurez ce qu'est un algorithme et vous serez capable de transcrire des algorithmes en programmes. Vous saurez résoudre des problèmes, en décomposant leur solution en étapes à suivre. Vous verrez également que pour un même problème, on peut avoir plusieurs solutions avec des propriétés, avantages et désavantages différents. @@ -97,7 +113,6 @@ Edsger Dijkstra 🇳🇱 :maxdepth: 2 :hidden: :numbered: 2 -intro algorithmes tri algo-progs diff --git a/src/appr/algo1/intro.md b/src/appr/algo1/intro.md deleted file mode 100644 index fe5ae0ad..00000000 --- a/src/appr/algo1/intro.md +++ /dev/null @@ -1,133 +0,0 @@ - - -
- - Cliquer ici pour
dossier
-
-
- -# Introduction - -## Quoi ? - -Il y a de fortes chances que vous ayez déjà entendu parler {glo}`algo|d'algorithmes` dans les médias. Il y a aussi de fortes chances que ce mot évoque pour vous des notions bien différentes de celles de votre voisin. L'objectif de ce chapitre est de vous éclairer sur la notion d'algorithme et la distinction avec la notion de programme informatique. - -## Pourquoi ? - -Les algorithmes existent depuis des millénaires. On doit le nom d'algorithme à Al-Khwârizmî, mathématicien perse né en l'an 780 dont les ouvrages ont contribué à la popularisation des chiffres arabes en Europe, ainsi que la classification de plusieurs algorithmes connus à ce moment. D'ailleurs l'algorithme le plus connu, l'algorithme d'Euclide, date environ de l'an 300 av J.-C. et permet de calculer le plus grand diviseur commun de deux nombres. Si Euclide a bien laissé des traces écrites de cet algorithme, il est vraisemblable qu'il ait puisé cette connaissance auprès de disciples de Pythagore lui-même. - -Les algorithmes sont devenus très populaires aujourd'hui grâce à la machine qui a permis de les automatiser. Que ce soit dans votre smartphone, sur un ordinateur ou dans un système embarqué, ils permettent de résoudre une quantité de problèmes, facilement et avec une rapidité impressionnante. - -## Comment ? - -Dans un premier temps nous allons nous intéresser à la notion même d'algorithme : qu'est-ce qui caractérise un algorithme et comment le faire exécuter par une machine ? Nous allons voir que pour un problème donné il existe de nombreuses solutions, mais que toutes ces solutions ne sont pas de *bonnes* solutions, selon le contexte dans lequel on tente de résoudre le problème. Dans un deuxième temps nous chercherons à départager ces différentes solutions. - - - - - - \ No newline at end of file diff --git a/src/appr/algo1/tri.md b/src/appr/algo1/tri.md index 1baea525..5d2c4e81 100644 --- a/src/appr/algo1/tri.md +++ b/src/appr/algo1/tri.md @@ -48,7 +48,7 @@ align : left -````{admonition} Exercice 0 : problème du tri +````{exercise} Problème du tri :class: note Trier les rectangles de la ligne du haut de la Figure ci-dessus en fonction de leur taille, pour arriver à la disposition de la ligne du bas. Noter toutes les étapes intermédiaires de vos actions et la disposition des rectangles avant d’arriver à la solution finale. Conseil : remplacer les rectangles par un nombre qui représente leur taille. @@ -59,7 +59,7 @@ Quels types d'opérations avez-vous effectuées ? ```` -````{admonition} Solution 0 : problème du tri +````{solution} Problème du tri :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -93,7 +93,7 @@ L’{glo}`algo|algorithme` du **tri par sé L’{glo}`algo|algorithme` du **tri à bulles** compare les éléments voisins, deux par deux. Il commence par comparer les deux premiers éléments de la liste et les met dans le bon ordre (le plus petit des deux éléments précède le plus grand des deux). Il compare ensuite les deux éléments suivants (le nouveau deuxième et le troisième élément de la liste) et les met dans le bon ordre. Il continue de la sorte jusqu’à la fin de la liste. Après ce premier parcours de la liste, le plus grand élément se retrouve en dernière position de la liste. L'algorithme parcourt à nouveau la liste, en comparant et en déplaçant les éléments voisins deux par deux (en excluant également le dernier élément qui est déjà bien trié). Après le deuxième parcours de la liste, le deuxième plus grand élément se retrouve en avant-dernière position de la liste. L'algorithme parcourt la liste de la sorte, autant de fois qu’elle possède d’éléments, en excluant les éléments bien triés en fin de la liste. -````{admonition} Exercice 2.1. Algorithme de tri +````{exercise} Algorithme de tri :class: note Il est fortement recommandé de résoudre cet exercice avant d’avancer dans le chapitre. @@ -106,7 +106,7 @@ Noter l’ordre des éléments à chaque fois qu’il change. Vous aurez besoin ```` -````{admonition} Solution 2.1. Algorithme de tri +````{solution} Algorithme de tri :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -158,13 +158,13 @@ align: left -````{admonition} Exercice 2.2. Votre algorithme de tri +````{exercise} Votre algorithme de tri :class: note Rappelez-vous quelle méthode vous avez utilisée pour résoudre l’exercice 0. De quel algorithme de tri se rapproche-t-elle le plus ? ```` -````{admonition} Solution 2.2. Votre algorithme de tri +````{solution} Votre algorithme de tri :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -174,7 +174,7 @@ Cela dépend de votre solution de l’exercice 0. Vous avez probablement utilis ``` ```` -````{admonition} Exercice 2.3. Opérations +````{exercise} Opérations :class: note Pour chaque algorithme de tri, compter le nombre de ***comparaisons*** de la taille de deux rectangles, ainsi que le nombre de ***déplacements*** (le nombre de fois que deux rectangles échangent leur place). @@ -185,7 +185,7 @@ Imaginons que ce qui prend le plus de temps est un ***déplacement***. Dans ce c ```` -````{admonition} Solution 2.3. Opérations +````{solution} Opérations :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -247,14 +247,14 @@ Dans cette configuration précise, quel algorithme est le plus rapide (présent -````{admonition} Exercice 2.6.1. L'algorithme de votre journée +````{admonition} {exercise} L'algorithme de votre journée :class: note Réfléchir à votre journée : y a-t-il des actions qui se retrouvent chaque jour ouvrable ? Arrivez-vous à esquisser un algorithme que vous suivez sans que vous en ayez conscience ? ```` -````{admonition} Exercice 2.6.2. Trois algorithmes de tri +````{admonition} {exercise} Trois algorithmes de tri :class: note @@ -263,7 +263,7 @@ Trier la liste [2, 5, 3, 4, 7, 1, 6] en utilisant les trois algorithmes de tri v ```` -````{admonition} Exercice 2.6.4. Mondrian +````{admonition} {exercise} Mondrian :class: note Analyser les œuvres cubistes de Piet Mondrian. Trouver un algorithme qui permet de créer une œuvre qui pourrait être attribuée à Mondrian. @@ -416,7 +416,7 @@ Analyser les œuvres cubistes de Piet Mondrian. Trouver un algorithme qui permet - - -```{image} media/Logn.png -:width: 400px -:height: 300px -``` -Seulement 4 étapes sont suffisantes pour parcourir un tableau trié de 16 éléments à la recherche d’un élément. A chaque étape, l’espace de recherche est divisé par 2 -
- - -De manière générale, le nombre d’étapes `x` nécessaires pour parcourir un tableau de taille `n` est : - -     2 * x = n - -     x = log2(n) ~ log(n)          # simplification : même ordre de grandeur - - -L’ordre de croissance de la recherche binaire est donc `O(log(n))`. La figure ci-dessous permet de comparer la croissance de `n` versus `log(n)`. Un {glo}`algo|algorithme` de complexité `O(log(n))` est beaucoup plus rapide qu’un {glo}`algo|algorithme` de complexité linéaire `O(n)`. La lettre O ici est pour « Ordre ». - - - -```{image} media/Graphique_Complexite_log.png -:width: 400px -:height: 300px -``` -Un algorithme avec un ordre de complexité logarithmique est plus rapide qu’un algorithme de complexité linéaire -
- - -```{admonition} Exercice 3 : recherche linéaire et binaire 🔌 -:class: note - -Programmer les algorithmes de recherche linéaire et binaire en Python. - -Rechercher une valeur entre 1 et 100 dans un tableau trié qui contient des valeurs de 1 à 100. - -Utiliser vos deux programmes pour rechercher un élément : quel algorithme est le plus rapide ? - -Augmenter la taille du tableau à 10000. Rechercher un élément vos deux programmes. Quel algorithme est plus rapide ? Est-ce significatif ? Est-ce que 10000 vous semble être un grand nombre ? - -Est-ce qu’on peut utiliser l’algorithme de recherche binaire si le tableau n’est pas trié ? Essayez. - -``` - -`````{admonition} Solution -:class: hint - -````{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -```{codeplay} -# algorithme de recherche linéaire -def search_lin(search_list, search_element, verbose=0) : - - # boucle pour parcourir la liste - for element in search_list : - - if verbose : - print("L'élément comparé est : " + str(element)) - - # l'élément de la liste correspond à l'élément recherché - if element == search_element : - return True - - # aucun élément ne correspond - return False - - -# algorithme de recherche binaire -def search_bin(search_list, search_element, verbose = 0) : - - # détermine les limites de la liste considérée - start = 0 - end = len(search_list) - - # tant que la liste - while end-start : - - # middle = len(search_list) // 2 - middle = (end-start) // 2 + start - - # compare l'élément au milieu de la liste - if search_element == search_list[middle] : - return True - - # l'élément du milieu est plus petit, on cherche dans la fin de la liste - elif search_element < search_list[middle] : - end = middle # search_list = search_list[:middle] - if verbose : - print("L'élément se trouve en début de la liste : " + str(search_list)) - - # l'élément du milieu est plus grand, on cherche dans la fin de la liste - else : - start = middle + 1 # search_list = search_list[middle+1:] - if verbose : - print("L'élément se trouve en fin de la liste : " + str(search_list)) - - # recalcule la longueur de la liste - condition d'arrêt de la boucle - # len_search_list = len(search_list) - - # aucun élément ne correspond - return False - - -import time -import random - -last = 10000 -ma_liste = list(range(1,last+1)) -mon_element = random.randint(1,last) + last - -print("L'élément recherché est : " + str(mon_element)) - -# mettre verbose à 1 pour avoir une vue de ce qui se passe -# attention, verbose à 1 fausse les temps de calcul -verbose = 0 - -time_1 = time.time() -search_lin(ma_liste, mon_element, verbose) -time_algo_lin = time.time() - time_1 -print("Recherche linéaire : " + str(time_algo_lin) + " secondes") - -time_1 = time.time() -search_bin(ma_liste, mon_element, verbose) -time_algo_bin = time.time() - time_1 -print("Recherche binaire : " + str(time_algo_bin) + " secondes") - - - -print("L'algorithme linéaire a été {0:.2f} fois plus lent.".format(time_algo_lin/time_algo_bin)) - - -# Le gain de vitesse est significatif lorsqu'on recherche dans des grandes listes. Essayez avec last = 1000000 - -# Les systèmes automatiques traitent des objets plus nombreux que 10000. - -# Non, le tableau doit être trié, sinon l'algorithme binaire n'est pas garantit de donner la bonne solution. L'algorithme linéaire va dans ce cas trouver la bonne solution, car il va comparer tous les éléments un par un. Essayer le code ci-dessous en le décommentant. - -# random.shuffle(ma_liste) -# print(search_bin(ma_liste, mon_element, verbose)) - -``` - -```` - -````` - - - - - -````{admonition} Pour aller plus loin -:class: attention - -Modifier votre programme de recherche binaire : au lieu de diviser l’espace de recherche exactement au milieu, le diviser au hasard. Cette recherche avec une composante randomisée s’apparente plus à la recherche que l’on fait lorsque l’on cherche un mot dans le dictionnaire. - -Rechercher une valeur avec les deux versions de recherche binaire. Quel algorithme est plus rapide ? - -Rechercher plusieurs valeurs avec les deux versions de recherche binaire. Est-ce que c’est toujours le même algorithme qui est le plus rapide ? - -Quel algorithme est plus rapide en moyenne ? - -Rechercher une valeur avec la nouvelle version randomisée de recherche binaire. Exécuter le programme plusieurs fois. Est-ce que ça prend toujours le même temps ? Pourquoi ? - -```` - -## Tri par sélection - -Pour rappel, le tri par sélection parcourt le tableau à la recherche du plus petit élément, et ce pour tous les éléments du tableau. Afin de trouver le plus petit élément du tableau, il faut commencer par parcourir toute la liste. Cette opération prend `cn` {glo}`instruction|instructions` : `c` {glo}`instruction|instructions` pour l’accès et la comparaison des éléments du tableau, multiplié par le nombre d’éléments. Il faut ensuite trouver le plus petit élément des éléments restants `n-1`, et ainsi de suite. Concrètement, on se retrouve avec la somme suivante : - -     cn + c(n-1) + c(n-2) + ... + c(n/2+1) + c(n/2) + ... + 3c + 2c + c - -Si on réarrange l’ordre des termes on obtient cette somme d’{glo}`instruction|instructions` : - -     cn + c + c(n-1) + 2c + c(n-2) + 3c + ... + c(n/2+1) + c(n/2) - -On groupe ensuite les termes deux par deux : - -     (cn + c) + (c(n-1) + 2c) + (c(n-2) + 3c) + ... + (c(n/2+1) + c(n/2)) - -On obtient ainsi plusieurs fois le même terme : - -     c(n+1) + c(n+1) + c(n+1) + ... + c(n+1) - -Nous avons commencé par `n` termes, que l’on a combinés deux par deux. On se retrouve donc avec la moitié des termes ou `n/2` : - -     c(n+1)*n/2 - -Le terme qui divise par 2 peut être absorbé dans la {glo}`constante|constante` `c` (la valeur de celle-ci changerait). Finalement, on ajoute une constante a pour prendre en compte le nombre d’{glo}`instruction|instructions` qui ne dépendent pas de la taille des données (p. ex : initialisations au début de l’{glo}`algo|algorithme`) : - -     c’(n+1)*n + a = c’n2 + c’n + a ou c’= c/2 - -Quand `n` est très grand, le terme qui domine cette somme est le `c’n2`. Comme ce qui nous intéresse est l’ordre de grandeur de la croissance, la complexité du tri par sélection est `O(n2)` ou quadratique. - - -```{admonition} Exercice 4 : complexité et tri par insertion ✏️📒 -:class: note - -Quelle est la complexité de l’algorithme de tri par insertion ? En d’autres termes, si le tableau contient n éléments, combien faut-il d’instructions pour trier ce tableau ? - -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -La complexité de l'algorithme par insertion est de n * n = n2 ou **quadratique**. Il arrive que l'on doive parcourir tous les éléments de la liste n fois, c'est-à-dire pour chaque élément. - -``` -```` - -```{admonition} Exercice 5 : complexité et tri à bulles ✏️📒 -:class: note - -Quelle est la complexité de l’algorithme de tri à bulles ? - -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -La complexité de l'algorithme par insertion, par sélection et à bulles est de n * n = n2 ou **quadratique**. Dans tous ces cas, il arrive que l'on doive parcourir tous les éléments de la liste n fois, c'est-à-dire pour chaque élément. - -``` -```` - -## Tri rapide - -Tous les {glo}`algo|algorithmes` de tri vus dans le chapitre précédent sont des {glo}`algo|algorithmes`s d’ordre quadratique ou de complexité `O(n2)`. Il existe d’autres {glo}`algo|algorithmes`s de tri qui sont bien plus rapides. Nous allons voir un {glo}`algo|algorithme` de tri tellement rapide, qu’on lui a donné le nom de **tri rapide**. - -On commence par définir un élément pivot : cet élément peut être le premier élément du tableau, l’élément du milieu, le dernier élément ou encore un élément au hasard. Supposons ici que l’élément pivot est le dernier élément du tableau. Une fois que l’on a défini l’élément pivot, on met tous les éléments qui sont plus petits que le pivot à sa gauche et tous les éléments qui sont plus grands que le pivot à droite de celui‑ci (voir la deuxième ligne de la Figure **Tri rapide** ci-dessous). - - - -```{image} media/Tri_rapide.png -:width: 400px -:height: 300px -``` -**Tri rapide**. Illustration du tri rapide sur le même set de données que celui utilisé pour illustrer les algorithmes de tri vus au chapitre précédent. L’élément pivot est le dernier élément des tableaux à trier -
- - -Après la répartition des éléments autour de l’élément pivot en fonction de leur taille, on se retrouve avec deux tableaux non triés, un tableau à chaque côté de l’élément pivot. On continue de traiter ces deux tableaux de la même manière que le tableau initial. On sélectionne pour chaque tableau, celui de gauche et celui de droite, un nouvel élément pivot (le dernier élément du tableau). Pour chaque nouvel élément pivot, on met à gauche les éléments du tableau qui sont plus petits que le pivot. Les éléments qui sont plus grands que le pivot se retrouvent à sa droite. On agit de la sorte jusqu’à ce qu’il ne reste plus que des tableaux à 1 élément. - -Intéressons‑nous maintenant à la complexité de cet {glo}`algo|algorithme`. A chaque étape (chaque ligne dans la Figure **Tri rapide** ci-dessus), on compare tout au plus n éléments avec les éléments pivots. Mais combien d’étapes faut-il pour que cet {glo}`algo|algorithme` se termine ? - -A chaque étape de l’{glo}`algo|algorithme`, l’espace de recherche est divisé par 2 (dans le meilleur des cas). Nous avons vu dans l’{glo}`algo|algorithme` de la recherche binaire que lorsqu’on divise l’espace de recherche par deux, on obtient une complexité de `O(log(n))`. Pour obtenir le nombre total d’{glo}`instruction|instructions` élémentaires on multiplie le nombre maximal de comparaisons par étape `n` avec le nombre d’étapes `log(n)`. Donc l’ordre de complexité du tri rapide est en moyenne `O(nlog(n))`. - -Comparons maintenant les différentes croissances des ordres de complexité vus jusqu’ici (voir la Figure ci-dessous). On voit bien que moins d’{glo}`instruction|instructions` élémentaires sont nécessaires pour le tri rapide d’ordre `O(nlog(n))` que pour le tri à sélection d’ordre `O(n2)`. - - - -```{image} media/Complexites4.png -:width: 400px -:height: 300px -``` -Comparaison des ordres de complexité vus jusqu’ici. Plus le nombre d’instructions élémentaires grandit avec la taille des données, plus l’algorithme est lent -
- - - -````{admonition} Matière à réfléchir V -:class: attention - -Appliquer le tri par rapide à un tableau déjà trié. Est-ce que le tri rapide est plus lent ou plus rapide que dans le cas moyen ? - -Quelle est la complexité du tri rapide dans ce cas ? Est-ce que le choix du pivot est important dans ce cas ? - -Mêmes questions pour le tri par insertion. - -```` - - -## Tri fusion - - -Un autre {glo}`algo|algorithme` de complexité `O(nlog(n))` est le **tri fusion**. L’{glo}`algo|algorithme` se base sur l’idée qu’il est difficile de trier beaucoup d’éléments, mais qu’il est très facile de trier deux éléments et de fusionner deux tableaux déjà triés. - - - - -L’{glo}`algo|algorithme` commence par une phase de division : on découpe le tableau en deux, jusqu’à arriver à uniquement des tableaux à 1 élément (voir la Figure **Diviser** ci-dessous). Le nombre d’étapes nécessaires pour découper le tableau en tableaux à 1 élément en divisant toujours les tableaux en deux est `log(n)`. - - - -La deuxième phase consiste à fusionner les petits tableaux. On commence par fusionner les éléments 1 à 1, dans un ordre qui dépend de leur taille. Il suffit d’assembler les deux éléments du plus petit au plus grand (voir la 2e ligne de la Figure **Fusionner** ci-dessous). - - - - -```{image} media/Tri_fusion_diviser.png -:width: 400px -:height: 300px -``` -**Diviser.** Illustration de la première phase du tri fusion. A chaque étape le tableau est découpé en deux jusqu’à ce qu’il ne reste que des tableaux à 1 élément -

- - - - -```{image} media/Tri_fusion_fusionner.png -:width: 400px -:height: 300px -``` -**Fusionner.** Illustration de la deuxième phase du tri fusion. A chaque étape les tableaux sont fusionnés par paires de deux, en faisant attention à respecter l’ordre de tri. On continue ainsi jusqu’à ce qu’il ne reste qu’un tableau unique -

- - -Dans les prochaines étapes (lignes 3 et 4 de la Figure **Fusionner** ci-dessus), on continue à fusionner les tableaux par paires de deux. Il est facile de fusionner ces tableaux, car ils sont déjà triés. Tout d’abord, on compare les premiers éléments des deux tableaux et on prend le plus petit des deux. Concrètement, on enlève le plus petit élément des deux tableaux pour commencer un nouveau tableau fusionné. On compare ensuite les premiers éléments des éléments restants dans les tableaux à fusionner et on prend à nouveau le plus petit des deux. On continue de la sorte jusqu’à ce qu’il ne reste pas d’éléments dans les tableaux à fusionner. - -Chaque étape de la phase de fusion consiste à comparer deux éléments `n` fois, autant qu’il y a d’éléments à fusionner dans le tableau. Elle prend donc un temps qui grandit linéairement en fonction de la taille du tableau `n`. En tout il y a besoin de `log(n)` d’étapes ce qui nous donne l’ordre de complexité `O(nlog(n))`. - - -```{admonition} Le saviez-vous ? -:class: hint - -Le tri rapide et le tri fusion se basent sur la stratégie algorithmique de résolution de problèmes **« diviser pour régner »**. Cette stratégie qui consiste à : - -     Diviser : décomposer le problème initial en sous-problèmes ; - -     Régner : résoudre les sous-problèmes ; - -     Combiner : calculer une solution au problème initial à partir des solutions des sous-problèmes. - -Les sous-problèmes étant plus petits, ils sont plus faciles et donc plus rapides à résoudre. Les algorithmes de ce type sont efficaces et se prêtent à la résolution en parallèle (p.ex.  multiprocesseurs). - -``` - -````{admonition} Pour aller plus loin -:class: attention - -La première question que l’on se pose lorsqu’on analyse un algorithme est son ordre de complexité. Si l’algorithme est trop lent, il ne sera pas utilisable dans la vie réelle. Lorsqu’on parle de complexité, on pense en fait à la complexité moyenne, mais on peut également calculer la complexité dans le meilleur et dans le pire cas. - -Par exemple, si on trie un tableau qui est en fait déjà trié avec le tri par insertion, la complexité dans ce cas est linéaire ou `O(n)`. Au contraire, si on trie ce même tableau avec le tri rapide, la complexité dans ce cas est quadratique ou O(n2). On voit donc que selon le tableau que l’on trie, le tri rapide peut être bien plus lent que le tri par insertion. - -Une analyse complète d’un algorithme consiste à calculer la complexité non seulement dans le **cas moyen**, mais aussi dans le **meilleur cas** et dans le **pire cas**. - -Une analyse complète va également calculer les constantes qui influencent l’ordre de complexité. Ces constantes ne sont pas importantes lors d’une première analyse d’un algorithme. En effet, les constantes n’ont que peu d’effet pour une grande taille des données n, c’est uniquement le terme qui grandit le plus rapidement en fonction de n qui compte, et qui figure dans un premier temps dans l’ordre de complexité. Par contre, lorsque l’on souhaite comparer deux algorithmes de la même complexité, il faut estimer les constantes et prendre celui des deux avec la plus petite constante. - -```` - - -```{admonition} Le saviez-vous ? -:class: hint -La complexité ne reflète pas la difficulté à implémenter un algorithme, comme on pourrait le croire, mais à quel point l’algorithme se complexifie au fur et à mesure que le nombre des entrées augmente. La complexité mesure le temps d’exécution d’un algorithme (ou sa rapidité) en termes du nombre d’instructions élémentaires exécutées en fonction de la taille des données. Mais est-ce que *complexe* veut dire la même chose que *compliqué* ? Une chose compliquée est difficile à saisir ou à faire, alors qu’une chose complexe est composée d’éléments avec de nombreuses interactions imbriquées. -``` - - -```{admonition} Exercice 6 : comparaison de tris ✏️📒 -:class: note - -Si une instruction prend 10-6 secondes, combien de temps faut-il pour trier un tableau d’1 million d’éléments avec le tri à sélection comparé au tri rapide (sans tenir compte de la constante) ? -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Pour trier 1 million d’éléments, le tri par sélection prend 106*106 *10-6 secondes ou 1 million de secondes (équivalent à plus de 11 jours), alors que le tri rapide a besoin de log2(106)*106 *10-6 ou ~20 secondes. - -Cette différence de temps est suffisante pour rendre rédhibitoire l’utilisation du tri par sélection. Pensez au nombre de clients qu’un réseau social possède, ou au nombre de produits qu’un supermarché doit gérer. -``` - -```` - -```{admonition} Exercice 7 : tri rapide et pivot ✏️📒 -:class: note - -Trier le tableau suivant avec l’algorithme de tri rapide : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main, en prenant le dernier élément comme pivot. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -Est-ce que le choix du pivot est important ? - -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri rapide, l’élément pivot est 5. On se retrouve donc avec les deux tableaux suivants : - -     [[3, 1, 4, 2], 5, [6, 8, 7, 9]] - -Les nouveaux éléments pivots sont les derniers éléments des nouveaux tableaux de gauche [3, 1, 4, 2] et le tableau de droite [6, 8, 7, 9] , donc 2 et 9. On réarrange tous les éléments des tableaux autour des éléments pivots, selon leur taille : - -     [[1], 2, [3, 4], 5, [6, 8, 7], 9 [ ]] - -On continue les mêmes opérations pour les tableaux qui contiennent plus d’un élément : [3, 4] et [6, 8, 7]. Les nouveaux pivots sont 4 et 7, car ils sont les derniers éléments des tableaux restants à plus d’un élément : - -     [1, 2, [3], 4, [ ], 5, [6], 7, [8], 9] - -Il ne reste plus de tableaux de plus d’un élément, le tableau est donc trié : - -     [1, 2, 3, 4, 5, 6, 7, 8, 9] - -Le choix du pivot est important et à prendre en comptes si on a des indications sur le tableau à trier. - -``` -```` - -```{admonition} Exercice 8 : tri fusion ✏️📒 -:class: note - -Trier le tableau suivant avec l’algorithme de tri fusion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -N’y a-t-il qu’une seule solution ? - -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri fusion, on divise le tableau en deux, jusqu’à arriver à des tableaux d’un seul élément : - -     [3, 6, 8, 7] [1, 9, 4, 2, 5] - -     [3, 6] [8, 7] [1, 9] [4, 2, 5] - -     [3] [6] [8] [7] [1] [9] [4] [2, 5] - -     [3] [6] [8] [7] [1] [9] [4] [2] [5] - -Une autre solution consiste par diviser le tableau en deux tableaux de 5 et 4 éléments lors de la première division. Lors de la deuxième étape du tri fusion, on fusionne les tableaux deux à deux, en respectant l’ordre de tri : - -     [3, 6] [7, 8] [1, 9] [2, 4] [5] - -     [3, 6, 7, 8] [1, 2, 4, 9] [5] - -     [1, 2, 3, 4, 6, 7, 8, 9] [5] - -Concrètement, pour fusionner les tableaux [3, 6, 7, 8] [1, 2, 4, 9], on prend toujours le plus petit des deux premiers éléments des deux tableaux : - -     [3, 6, 7, 8] [1, 2, 4, 9]    →    3 > 1    →    on prend 1    →    [1] - -     [3, 6, 7, 8] [2, 4, 9]    →    3 < 2    →    on prend 2    →    [1, 2] - -     [3, 6, 7, 8] [4, 9]    →    3 < 4    →    on prend 3    →    [1, 2, 3] - -     [6, 7, 8] [4, 9]    →    6 > 4    →   on prend 4    →    [1, 2, 3, 4] - -     [6, 7, 8] [9]    →    6 < 9    →    on prend 6    →    [1, 2, 3, 4, 6] - -     [7, 8] [9]    →    7 < 9    →    on prend 7    →    [1, 2, 3, 4, 6, 7] - -     [8] [9]    →    8 < 9    →    on prend 8    →    [1, 2, 3, 4, 6, 7, 8] - -     [ ] [9]    →    on prend 9    →    [1, 2, 3, 4, 6, 7, 8, 9] - -On procède de la même manière pour fusionner le tableau contenant le chiffre et on arrive ainsi à la solution du tableau trié : - -     [1, 2, 3, 4, 5, 6, 7, 8, 9] - -```` - -```{admonition} Exercice 9 : tri par selection ✏️📒 -:class: note - -Trier le tableau suivant avec l’algorithme de tri par sélection : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri par sélection, on cherche le plus petit élément : - -     [3, 6, 8, 7, **1**, 9, 4, 2, 5] - -On échange les positions du premier et du plus petit élément : - -     [**1**, 6, 8, 7, **3**, 9, 4, 2, 5] - -On cherche le plus petit élément dans le tableau, en excluant l’élément que l’on vient de trier : - -         [**1**, 6, 8, 7, 3, 9, 4, **2**, 5] - -On échange sa position avec le 2e élément du tableau : - -     [**1**, **2**, 8, 7, 3, 9, 4, **6**, 5] - -Notez que les étapes qui changent l’ordre des éléments du tableau sont disposées à gauche. On cherche le plus petit élément du tableau non trié et on l’échange avec le troisième élément : - -         [**1**, **2**, 8, 7, **3**, 9, 4, 6, 5] - -     [**1**, **2**, **3**, 7, **8**, 9, 4, 6, 5] - -On continue de la sorte jusqu’à ce que tous les éléments soient triés (les éléments triés sont en vert) : - -         [**1**, **2**, **3**, 7, 8, 9, **4**, 6, 5] - -     [**1**, **2**, **3**, **4**, 8, 9, **7**, 6, 5] - -         [**1**, **2**, **3**, **4**, 8, 9, 7, 6, **5**] - -     [**1**, **2**, **3**, **4**, **5**, 9, 7, 6, **8**] - -         [**1**, **2**, **3**, **4**, **5**, 9, 7, **6**, 8] - -     [**1**, **2**, **3**, **4**, **5**, **6**, 7, **9**, 8] - -Le septième élément du tableau est déjà à la bonne position, donc il n’y a pas besoin d’échanger la position de deux éléments. Le tableau est trié lorsque tous les éléments sont parcourus. - -         [**1**, **2**, **3**, **4**, **5**, **6**, **7**, 9, 8] - -         [**1**, **2**, **3**, **4**, **5**, **6**, **7**, 9, **8**] - - -     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - -``` -```` - -```{admonition} Exercice 10 : tri par insertion ✏️📒 -:class: note - -Trier le tableau suivant avec l’algorithme de tri par insertion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - -````{admonition} Solution -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri par insertion, on cherche à trouver la bonne position du 2e élément, dans ce cas l’élément 6 reste au même emplacement, car 3 est plus petit que 6 : - -     [3, **6**, 8, 7, 1, 9, 4, 2, 5] - -Le prochain élément considéré est le 8. Cet élément est également déjà bien placé : - -         [**3**, **6**, **8**, 7, 1, 9, 4, 2, 5] - -Comme l’ordre des éléments ne change pas, nous notons cette configuration à droite. - -Le prochain élément considéré est le 7. Cet élément n’est pas bien placé au regard du tableau que l’on a déjà trié. Sa place est avant le 8, on va donc l’insérer entre le 6 et le 8 : - -         [**3**, **6**, **8**, **7**, 1, 9, 4, 2, 5] - -     [**3**, **6**, **7**, **8**, 1, 9, 4, 2, 5] - -Le prochain élément de la liste non triée est le 1 : - -     [**3**, **6**, **7**, **8**, **1**, 9, 4, 2, 5] - -Nous allons l’insérer à la bonne position du tableau déjà trié, c’est-à-dire tout au début : - -     [**1**, **3**, **6**, **7**, **8**, 9, 4, 2, 5] - -Tous les éléments qui ont changé de position dans l’étape précédente sont désignés en rouge. Le prochain élément à considérer est le 9. Il est déjà bien placé par rapport à la partie triée du tableau : - -         [**1**, **3**, **6**, **7**, **8**, **9**, 4, 2, 5] - -On continue de la sorte jusqu’à ce que tous les éléments du tableau soient parcourus : - -         [**1**, **3**, **6**, **7**, **8**, **9**, **4**, 2, 5] - -     [**1**, **3**, **4**, **6**, **7**, **8**, **9**, 2, 5] - -         [**1**, **3**, **4**, **6**, **7**, **8**, **9**, **2**, 5] - -     [**1**, **2**, **3**, **4**, **6**, **7**, **8**, **9**, 5] - -         [**1**, **2**, **3**, **4**, **6**, **7**, **8**, **9**, **5**] - -Lorsque le dernier élément du tableau est inséré à la bonne position, tout le tableau est trié : - -     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - -``` -```` - -```{admonition} Exercice 11 : tri à bulles ✏️📒 -:class: note - -Trier le tableau suivant avec l’algorithme de tri à bulles : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - -````{admonition} Exercice 12. Comparaison temporelle des algorithmes de tris 🔌 -:class: note - -Créer une liste qui contient les valeurs de 1 à n dans un ordre aléatoire, où n prend la valeur 100, par exemple. Vous pouvez utiliser la fonction shuffle() du module random. - -Implémenter au moins deux des trois algorithmes de tri vu au cours. -A l’aide du module time et de sa fonction time(), chronométrez le temps prend le tri d'une liste de 100, 500, 1000, 10000, 20000, 30000, 40000 puis 50000 nombres. - -Noter les temps obtenus et affichez-les sous forme de courbe dans un tableur. Ce graphique permet de visualiser le temps d’exécution du tri en fonction de la taille de la liste. Que constatez‑vous ? - -Sur la base de ces mesures, pouvez-vous estimer le temps que prendrait le tri de 100000 éléments ? - -Lancer votre programme avec 100000 éléments et comparez le temps obtenu avec votre estimation. - -```` - - diff --git a/src/appr/algo2/heuristiques.md b/src/appr/algo2/heuristiques.md index e5a9ad77..f7462925 100644 --- a/src/appr/algo2/heuristiques.md +++ b/src/appr/algo2/heuristiques.md @@ -21,7 +21,7 @@ Si le calcul d’un itinéraire prenait 1 milliseconde, combien de temps faudrai Il existe des problèmes difficiles à résoudre. Nous allons nous pencher sur un problème qui s’appelle le **problème du sac à dos**. Prenons un sac à dos et une multitude d’objets qui ont chacun un poids. Notre objectif est de choisir les objets à mettre dans le sac à dos pour le remplir au maximum, mais sans dépasser sa capacité. Donc la question que l'on se pose est la suivante : quels objets devrions-nous emporter, sans dépasser le poids maximal que le sac à dos peut contenir ? -```{admonition} Exercice 5.0. Le problème du sac à dos +```{exercise} Le problème du sac à dos :class: note Comment procéderiez-vous pour résoudre ce problème du sac à dos ? Prenez le temps d’imaginer un {glo}`algo|algorithme` qui puisse résoudre ce problème ? @@ -31,7 +31,7 @@ Appliquer cet algorithme pour 5 objets de poids 1, 3, 5 et 7 kg et un Est-ce que votre algorithme donne toujours la meilleure solution ? ``` -````{admonition} Solution 5.0. Le problème du sac à dos +````{solution} Le problème du sac à dos :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -95,13 +95,13 @@ L'algorithme le plus simple pour résoudre ce problème est un **Cliquer ici pour voir la réponse @@ -169,14 +169,14 @@ name : heuristique Il existe encore d’autres types d’algorithmes {glo}`heuristique|heuristiques`, plus lents, mais qui permettent de s’approcher davantage de la solution optimale. Ils utilisent par exemple des stratégies de résolution statistiques, génétiques ou neuronales. L'apprentissage automatique à qui l'on doit les succès récents de l'intelligence artificielle repose sur des algorithmes heuristiques. La majorité des problèmes que l’on tente de résoudre aujourd’hui sont difficiles et leurs algorithmes de résolution ne trouvent pas la meilleure solution. -```{admonition} Exercice 5.2. L'univers dans un sac à dos +```{exercise} L'univers dans un sac à dos :class: note L’âge estimé de l’univers est de 14 milliards d’années. Si le calcul d’une combinaison d’objets dans le problème du sac à dos prenait une microseconde, pour quel nombre d’objets serait-il possible de trouver une solution exacte sans dépasser l’âge de l’univers ? ``` -````{admonition} Solution 5.2. L'univers dans un sac à dos +````{solution} L'univers dans un sac à dos :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -192,7 +192,7 @@ n = log2(1.4 * 1010 / 10-6) = log2(1 ```` -```{admonition} Exercice 5.3. Parcours du parcours du parcours d'un tableau +```{exercise} Parcours du parcours du parcours d'un tableau :class: note Quelle est la complexité d’un algorithme qui pour chacun de ses éléments doit parcourir le tableau, puis pour chaque combinaison de deux de ses élements doit encore parcourir le tableau ? @@ -200,7 +200,7 @@ Quelle est la complexité d’un algorithme qui pour chacun de ses éléments do ``` -````{admonition} Solution 5.3. Parcours du parcours du parcours d'un tableau +````{exercise} Parcours du parcours du parcours d'un tableau :class: hint ```{dropdown} Cliquer ici pour voir la réponse diff --git a/src/appr/algo2/index.md b/src/appr/algo2/index.md index acc13fb0..ab8b1f30 100644 --- a/src/appr/algo2/index.md +++ b/src/appr/algo2/index.md @@ -2,16 +2,41 @@ # Algorithmique II +## Quoi ? Pour résoudre un problème, il faut commencer par le décomposer en sous-problèmes. Pour chaque sous-problème à résoudre, on décrit les opérations à réaliser sous la forme d’un {glo}`algo|algorithme`. Il existe une multitude d’{glo}`algo|algorithmes` pour résoudre un problème, mais ils ne se valent pas tous. L’**algorithmique** étudie les propriétés de ces {glo}`algo|algorithmes`. Cette analyse est nécessaire pour nous aider à décider quel {glo}`algo|algorithme` utiliser. On se propose à présent de passer en revue quelques propriétés importantes des {glo}`algo|algorithmes`. + + +```{figure} media/Shadok.jpeg +--- +alt: devise shadok +width: 300px + +``` + +## Pourquoi ? + +Si tous les chemins mènent à Rome, on ne peut en emprunter qu'un. Lorsqu'on est face à plusieurs chemins pour arriver au même résultat, il est important de choisir le chemin le plus optimal. + +Vous avez déjà rencontré plusieurs algorithmes pour arriver jusqu'ici. Encore plus fort, vous avez rencontré plusieurs algorithmes pour résoudre un même problème, ce qui nous met face à un dilemme : quelle algorithme choisir ? Et y a-t-il une solution à tout problème ? + +## Comment ? + +Dans un premier temps nous allons nous intéresser à la notion de complexité : comment déterminer la vitesse d'un algorithme ? Si plusieurs *bonnes* solutions existent, alors il faut choisir la plus rapide. Mais sera-t-elle toujours la solution la plus rapide ? + +Dans un deuxième temps, si vous le souhaitez, vous pouver ouvrir la porte merveilleuse de la récursivité, à la manière des *Infinity Mirror Room* de Yayoi Kusama. + + + + ```{toctree} :maxdepth: 2 :hidden: :numbered: 2 -intro + principes recherche tris diff --git a/src/appr/algo2/principes.md b/src/appr/algo2/principes.md index 2f30747b..e0673a44 100644 --- a/src/appr/algo2/principes.md +++ b/src/appr/algo2/principes.md @@ -40,14 +40,14 @@ La **terminaison** est une propriét Si on exécute cet {glo}`algo|algorithme`, le {glo}`programme|programme` ne s’arrête jamais : `i` est {glo}`incrementation|incrémenté` de `1` indéfiniment.  En pratique, si on retranscrit cet algorithme en programme et que l’on exécute le programme, le programme finira par s’arrêter lorsque les nombres représentés seront trop grands pour être représentés. -```{admonition} Exercice 1.0. L'infini en programme +```{exercise} L'infini en programme :class: note Retranscrire l’algorithme infini en programme. Après combien de boucles le programme s’arrête‑t‑il ? ``` -````{admonition} Solution 1.0. L'infini en programme +````{solution} L'infini en programme :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -70,14 +70,14 @@ Pour faire en sorte que le programme finisse par s’arrêter, nous pouvons le m Fin Tant que ``` - ```{admonition} Exercice 1.1. L'infini ne finit plus de finir + ```{exercise} L'infini ne finit plus de finir :class: note L’algorithme ci-dessus est appelé « Algorithme qui compte toujours infini ». Pourquoi est-il toujours infini ? Dans quel cas cet algorithme ne s’arrête jamais ? ``` -````{admonition} Solution 1.1. L'infini ne finit plus de finir +````{solution} L'infini ne finit plus de finir :class: hint ```{dropdown} Cliquer ici pour voir la réponse diff --git a/src/appr/algo2/recherche.md b/src/appr/algo2/recherche.md index 0ecc9550..7fedfd8f 100644 --- a/src/appr/algo2/recherche.md +++ b/src/appr/algo2/recherche.md @@ -44,7 +44,7 @@ name : fig-comp-log **Complexité linéaire**. La complexité de l'algorithme de recherche linéaire, comme son nom l'indique, est linéaire. La relation entre la taille du tableau `n` et le nombre d'instructions nécessaires pour retrouver un élément dans ce tableau représente une ligne. ``` -```{admonition} Exercice 2.0. Compter jusqu'à n +```{exercise} Compter jusqu'à n :class: note Ecrire un algorithme qui affiche tous les nombres de 1 à `n`. @@ -54,7 +54,7 @@ Combien d’instructions élémentaires sont nécessaires lorsque `n` vaut 100 ? Quelle est la complexité de cet algorithme ? ``` -`````{admonition} Solution 2.0. Compter jusqu'à n +`````{solution} Compter jusqu'à n :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -86,7 +86,7 @@ name : fig-rech-lin2 ````` -```{admonition} Exercice 2.1. Compter par pas de 2 +```{exercise} Compter par pas de 2 :class: note Ecrire un algorithme qui affiche tous les nombres *pairs* de 1 à `n`. @@ -96,7 +96,7 @@ Combien d’instructions élémentaires sont nécessaires lorsque `n` vaut 100 ? Quelle est la complexité de cet algorithme ? ``` -`````{admonition} Solution 2.1. Compter par pas de 2 +`````{solution} Compter par pas de 2 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -133,7 +133,7 @@ La différence de croissance se cache dans la constante `c` de l’ordre de gra -```{admonition} Exercice 2.2. Recherche linéaire🔌 +```{exercise} Recherche linéaire🔌 :class: note Programmer l'algorithme de recherche linéaire en Python. Rechercher une valeur entre 1 et 1000000 dans un tableau qui contient les valeurs allant de 1 à 1000000. @@ -145,7 +145,7 @@ Est-ce que ce résultat vaut si les éléments du tableau ne sont pas dans l'ord ``` -`````{admonition} Solution 2.2. Recherche linéaire🔌 +`````{solution} Recherche linéaire🔌 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -375,7 +375,7 @@ Un algorithme avec un ordre de complexité logarithmique est plus rapide qu’un --> -```{admonition} Exercice 2.3 Recherche binaire 🔌 +```{exercise} Recherche binaire 🔌 :class: note Programmer l'algorithme de recherche binaire en Python. Rechercher une valeur entre 0 et 100 dans un tableau qui contient les valeurs allant de 0 à 100. @@ -386,7 +386,7 @@ Est-ce qu’on peut utiliser l’algorithme de recherche binaire si le tableau n ``` -`````{admonition} Solution 2.3. Recherche binaire 🔌 +`````{solution} Recherche binaire 🔌 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -473,7 +473,7 @@ print("J'ai fini de calculer...") -```{admonition} Exercice 2.4. Recherche linéaire versus binaire 🔌 +```{exercise} Recherche linéaire versus binaire 🔌 :class: note Reprendre les programmes de recherche linéaire et recherche binaire en Python et les utiliser pour rechercher un élément dans un tableau à 100 éléments : quel algorithme est le plus rapide ? @@ -484,7 +484,7 @@ Est-ce que **un million** vous semble être un grand nombre pour une taille de d ``` -`````{admonition} Exercice 2.4. Recherche linéaire versus binaire 🔌 +`````{exercise} Recherche linéaire versus binaire 🔌 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -609,12 +609,12 @@ print("Gain : " + str(resultat_dif)) ## Exercices -```{admonition} Exercice 2.5. Recherche binaire aléatoire 🔌 +```{exercise} Recherche binaire aléatoire 🔌 :class: note Modifier votre programme de recherche binaire : au lieu de diviser l’espace de recherche exactement au milieu, le diviser au hasard. Cette recherche avec une composante aléatoire s’apparente plus à la recherche que l’on fait lorsque l’on cherche un mot dans le dictionnaire. -```` +``` ````{admonition} Ai-je compris ? diff --git a/src/appr/algo2/recursivite.md b/src/appr/algo2/recursivite.md index 8365e284..84ccc661 100644 --- a/src/appr/algo2/recursivite.md +++ b/src/appr/algo2/recursivite.md @@ -202,14 +202,14 @@ Les deux ingrédients indispensables à toute {glo}`fonctionrec|fonction récurs -```{admonition} Exercice 4.0. Position de la condition d'arrêt +```{exercise} Position de la condition d'arrêt :class: note Sans la condition d'arrêt, un programme récursif ne se termine pas, et s'appelle soi-même indéfiniment. Il est important que cette condition d’arrêt précède l’appel récursif à la fonction. Pourquoi est-ce le cas ? ``` -````{admonition} Solution 4.0. Position de la condition d'arrêt +````{solution} Position de la condition d'arrêt :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -406,7 +406,7 @@ print("\nVoici le tableau trié : ", resultat) ## Exercices supplémentaires -````{admonition} Exercice 4.1 Fractale 🔌 +````{exercise} Fractale 🔌 :class: note Une fractale est un objet géométrique, dont la définition récursive est naturelle. Essayez le code suivant pour différentes valeurs de `n` (augmenter à chaque fois de 1). @@ -468,7 +468,7 @@ turtle.exitonclick() # garde la fenêtre ouverte -```{admonition} Exercice 4.2. Une question de fusion +```{exercise} Une question de fusion :class: note Trier le tableau suivant avec l’algorithme de tri par fusion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. @@ -476,7 +476,7 @@ Trier le tableau suivant avec l’algorithme de tri par fusion : [3, 6, 8, 7, ``` -````{admonition} Exercice 4.3. Dans l'autre sens 🔌 +````{exercise} Dans l'autre sens 🔌 :class: note En Python, proposer une fonction qui inverse l’ordre des lettres dans un mot. Vous pouvez parcourir les lettres du mot directement ou à travers un indice. @@ -488,7 +488,7 @@ Proposer une autre fonction qui inverse l’ordre des lettres dans un mot de man -````{admonition} Exercice 4.4. Factorielle 🔌 +````{exercise} Factorielle 🔌 :class: note La fonction factorielle `n!` en mathématiques est le produit de tous les nombres entiers jusqu’à `n`. C’est une des fonctions les plus simples à calculer de manière récursive. Elle peut être définie comme ceci : diff --git a/src/appr/algo2/tris.md b/src/appr/algo2/tris.md index a59bb026..b298dedf 100644 --- a/src/appr/algo2/tris.md +++ b/src/appr/algo2/tris.md @@ -81,7 +81,7 @@ Avec une complexité quadratique, le Tri par sélection est un algorithme relati -```{admonition} Exercice 3.0. Complexité du Tri par insertion +```{exercise} Complexité du Tri par insertion :class: note Quelle est la complexité de l’algorithme de **Tri par insertion** ? En d’autres termes, si le tableau contient n éléments, combien faut-il d’instructions pour trier ce tableau ? Pour rappel, le Tri par insertion parcourt le tableau dans l'ordre et pour chaque nouvel élément, l'insère à l'emplacement correct des éléments déjà parcourus. @@ -92,7 +92,7 @@ Est-ce que la complexité du Tri par insertion est la même si les éléments du ``` -````{admonition} Solution 3.0. Complexité du Tri par insertion +````{solution} Complexité du Tri par insertion :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -107,14 +107,14 @@ Dans le meilleur cas, lorsque les éléments sont déjà dans le bon ordre, on d ``` ```` -```{admonition} Exercice 3.1. Complexité du Tri à bulles +```{exercise} Complexité du Tri à bulles :class: note Quelle est la complexité de l’algorithme de **Tri à bulles** ? En d’autres termes, si le tableau contient n éléments, combien faut-il d’instructions pour trier ce tableau ? Pour rappel, le Tri à bulles compare les éléments deux par deux en les réarrangeant dans le bon ordre, afin que l'élément le plus grand remonte vers la fin du tableau tel une bulle d'air dans de l'eau. Cette opération est répétée n fois, pour chaque élément du tableau. ``` -````{admonition} Solution 3.1. Complexité du Tri à bulles +````{solution} Complexité du Tri à bulles :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -182,7 +182,7 @@ Est-ce que *complexe* veut dire la m ``` -```{admonition} Exercice 3.2. Le pire du Tri rapide +```{exercise} Le pire du Tri rapide :class: note Que se passe-t-il si on essaie de trier un tableau déjà trié avec l'algorithme du **Tri rapide**, en prenant toujours comme pivot le dernier élément ? Essayer par exemple avec le tableau [1, 2, 3, 4, 5, 6, 7]. @@ -193,7 +193,7 @@ Est-ce qu'un autre choix de pivot aurait été plus judicieux ? ``` -````{admonition} Solution 3.2. Le pire du Tri rapide +````{solution} Le pire du Tri rapide :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -237,7 +237,7 @@ Si on prend comme pivot l'élément du milieu du tableau, on se retrouve avec de ```` -```{admonition} Exercice 3.3. Le meilleur et le pire du Tri par insertion +```{exercise} Le meilleur et le pire du Tri par insertion :class: note Que se passe-t-il si on essaie de trier un tableau déjà trié avec l'algorithme du **Tri par insertion** ? Essayer par exemple avec le tableau [1, 2, 3, 4, 5, 6, 7]. @@ -248,7 +248,7 @@ Que se passe-t-il si on essaie de trier un tableau déjà trié, mais dans l'ord ``` -````{admonition} Solution 3.3. Le meilleur et le pire du Tri par insertion +````{solution} Le meilleur et le pire du Tri par insertion :class: hint ```{dropdown} Cliquer ici pour voir la réponse @@ -321,14 +321,14 @@ La notation « Grand O », que l'on utilise pour écrire mathématiquement la ## Exercices -```{admonition} Exercice 3.4. Une question à un million +```{exercise} Une question à un million :class: note Si une instruction prend 10-6 secondes, combien de temps faut-il pour trier un tableau d’un million d’éléments avec le tri à sélection comparé au tri rapide (sans tenir compte de la constante) ? ``` -```{admonition} Exercice 3.5. Une question de pivot +```{exercise} Une question de pivot :class: note Trier le tableau suivant avec l’algorithme de tri rapide : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main, en prenant le dernier élément comme pivot. Représenter l’état du tableau lors de toutes les étapes intermédiaires. @@ -337,28 +337,28 @@ Est-ce que le choix du pivot est important ? ``` -```{admonition} Exercice 3.6. Une question de sélection +```{exercise} Une question de sélection :class: note Trier le tableau suivant avec l’algorithme de tri par sélection : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. ``` -```{admonition} Exercice 3.7. Une question d'insertion +```{exercise} Une question d'insertion :class: note Trier le tableau suivant avec l’algorithme de tri par insertion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. ``` -```{admonition} Exercice 3.8. Une question de bulles +```{exercise} Une question de bulles :class: note Trier le tableau suivant avec l’algorithme de tri à bulles : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. ``` -````{admonition} Exercice 3.9. Une question de chronomètre 🔌 +````{exercise} Une question de chronomètre 🔌 :class: note Créer une liste qui contient les valeurs de 1 à n dans un ordre aléatoire, où n prend la valeur 100, par exemple. Indice : utiliser la fonction `shuffle()` du module `random`. diff --git a/src/appr/archi/sys-log.md b/src/appr/archi/sys-log.md index a697916b..35d5758f 100644 --- a/src/appr/archi/sys-log.md +++ b/src/appr/archi/sys-log.md @@ -101,7 +101,7 @@ width: 200px --- ``` -Ici, les deux transistors sont les composants symbolisés par un cercle. Rappelons qu'ils laissent passer du courant de haut en bas lorsqu'ils détectent un courant sur l'entrée qui vient de la gauche. Ici, comme on a en haut une tension de 4 volts, on aura une tension similaire sur la sortie **Z** que si à la fois les entrées **X** et **Y** sont «actives» — donc lorsque les deux transistors sont «ouverts». Sinon, on aura une tension de 0 volt sur la sortie **Z**. +Ici, les deux transistors sont les composants symbolisés par un cercle. Rappelons qu'ils laissent passer du courant de haut en bas lorsqu'ils détectent un courant sur l'entrée qui vient de la gauche. Ici, comme on a en haut une tension de 5 volts, on aura une tension similaire sur la sortie $Z$ que si à la fois les entrées $X$ et $Y$ sont «actives» — donc lorsque les deux transistors sont «ouverts». Sinon, on aura une tension de 0 volt sur la sortie $Z$. ```` diff --git a/src/appr/conf.py b/src/appr/conf.py index acfe45ab..3e110fa8 100644 --- a/src/appr/conf.py +++ b/src/appr/conf.py @@ -157,7 +157,7 @@ }, } -html_css_files = ['styles/global.css', 'styles/reactions.css', 'styles/progress.css', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'] +html_css_files = ['styles/global.css', 'styles/global_appr.css', 'styles/reactions.css', 'styles/progress.css', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/src/appr/prog1/code/tp1.py b/src/appr/prog1/code/tp1.py new file mode 100644 index 00000000..d5d9e88c --- /dev/null +++ b/src/appr/prog1/code/tp1.py @@ -0,0 +1,25 @@ +""" +tp1 - introduction + +Nom : +Classe : +Date : + +- installez Thonny chez vous +- nommez ce fichier : tp1_classe_prenom (minuscules, sans accents) +- ajoutez 100+ ligne de code pour faire un dessin concrèt +- ajoutez des commentaires qui expliquent les éléments du dessin +- exéctutez le code et montrez l'image +- prenez une capture d'écran entier, + qui montre les fênetre code et fenêtre dessin sans être superposés +- déposez sur Moodle : + tp1_classe_prenom.py (code) + tp1_classe_preneom.jpg (capture d'écran en format JPG) +""" + +from turtle import * + +# mettez votre code ici +forward(100) + +done() \ No newline at end of file diff --git a/src/appr/prog1/code/tp2.py b/src/appr/prog1/code/tp2.py new file mode 100644 index 00000000..05a09e62 --- /dev/null +++ b/src/appr/prog1/code/tp2.py @@ -0,0 +1,59 @@ +""" +tp2 - définir + +Nom : +Classe : +Date : + +- nommez ce fichier : tp2_classe_prenom (minuscules, sans accents) +- créez des fonctions pour les lettres de l'abc +- créer une fonction pour écrire votre nom +- récrivez l'abc et votre nom une deuxième fois plus petit +- déposez sur Moodle : + tp2_classe_prenom.py (code) + tp2_classe_prenom.eps (image vectorielle) + tp2_classe_preneom.jpg (image) +""" +from turtle import * +from tkinter import * + +d = 30 + +def A(): + dot() + down() + left(70) # demi-montée + forward(d) + right(70) + forward(0.6*d) # trait du milieu + backward(0.6*d) + left(70) + forward(d) # partie haute + right(140) + forward(2*d) # descente + left(70) + up() + forward(d/2) # avancer à la prochaine lettre + + +def ABC(): + A() + A() + A() + +def prenom(): + ... + +# afficher l'ABC et votre prénom +backward(280) +ABC() +prenom() + +# afficher l'ABC et votre prénom avec une autre taille +d = 10 +forward(100) +ABC() +prenom() + +Screen().getcanvas().postscript(file='tp2.eps') +done() \ No newline at end of file diff --git a/src/appr/prog1/code/tp3.py b/src/appr/prog1/code/tp3.py new file mode 100644 index 00000000..27f9391e --- /dev/null +++ b/src/appr/prog1/code/tp3.py @@ -0,0 +1,45 @@ +""" +tp3 - répéter + +Nom : +Classe : +Date : + +- nommez ce fichier : tp3_classe_prenom (minuscules, sans accents) +- créez 5+ fonctions qui utilisent la répétion +- utilisez la variable d (distance) pour vos déplacements +- composez une scène de jeu vidéo (pacman, tetris, minecraft, etc. +- utilisez de la couleur +- déposez sur Moodle : + tp3_classe_prenom.py (code) + tp3_classe_prenom.eps (image vectorielle) + tp3_classe_preneom.jpg (image) +""" +from turtle import * +from tkinter import * + +d = 20 + +def pacman(): + down() + left(45) + forward(d) + left(90) + circle(d, 270) + left(90) + forward(d) + right(135) + for i in range(5): + up() + forward(d) + dot(d/5) + +# ajoutez vos fonctions ici + +pacman() + + + +# remplacer avec tp3_classe_prenom +Screen().getcanvas().postscript(file='tp2.eps') +done() \ No newline at end of file diff --git a/src/appr/prog1/media/turtle.cfg b/src/appr/prog1/code/turtle.cfg similarity index 100% rename from src/appr/prog1/media/turtle.cfg rename to src/appr/prog1/code/turtle.cfg diff --git a/src/appr/prog1/definir.md b/src/appr/prog1/definir.md index f75a7d0d..d2d53812 100644 --- a/src/appr/prog1/definir.md +++ b/src/appr/prog1/definir.md @@ -619,3 +619,69 @@ O() ... done() ``` + +### TP + +Créez un alphabet et écrivez votre nom. + +```{codeplay} +""" +tp2 - définir + +Nom : +Classe : +Date : + +- nommez ce fichier : tp2_classe_prenom (minuscules, sans accents) +- créez des fonctions pour les lettres de l'abc +- créer une fonction pour écrire votre nom +- récrivez l'abc et votre nom une deuxième fois plus petit +- déposez sur Moodle : + tp2_classe_prenom.py (code) + tp2_classe_prenom.eps (image vectorielle) + tp2_classe_preneom.jpg (image) +""" +from turtle import * +# from tkinter import * + +d = 30 + +def A(): + dot() + down() + left(70) # demi-montée + forward(d) + right(70) + forward(0.6*d) # trait du milieu + backward(0.6*d) + left(70) + forward(d) # partie haute + right(140) + forward(2*d) # descente + left(70) + up() + forward(d/2) # avancer à la prochaine lettre + + +def ABC(): + A() + A() + A() + +def prenom(): + ... + +# afficher l'ABC et votre prénom +backward(280) +ABC() +prenom() + +# afficher l'ABC et votre prénom avec une autre taille +d = 10 +forward(100) +ABC() +prenom() + +#Screen().getcanvas().postscript(file='tp2.eps') +done() +``` diff --git a/src/appr/prog1/dessiner.md b/src/appr/prog1/dessiner.md index fe9cc27f..286ac968 100644 --- a/src/appr/prog1/dessiner.md +++ b/src/appr/prog1/dessiner.md @@ -415,3 +415,36 @@ forward(100) ... done() ``` + +### TP + +Téléchargez le fichier ci-dessous et utilisez-le comme base de départ pour votre travail pratique. + +```{codeplay} +:file: tp1.py +""" +tp1 - introduction + +Nom : +Classe : +Date : + +- installez Thonny chez vous +- nommez ce fichier : tp1_classe_prenom.py (minuscules, sans accents) +- ajoutez 100+ ligne de code pour faire un dessin concrèt +- ajoutez des commentaires qui expliquent les éléments du dessin +- exéctutez le code et montrez l'image +- prenez une capture d'écran entier, + qui montre la fênetre code et la fenêtre dessin sans être superposée +- Déposez sur Moodle : + tp1_classe_prenom.py (code) + tp1_classe_preneom.jpg (capture d'écran en format JPG) +""" + +from turtle import * + +# mettez votre code ici ! +forward(100) + +done() +``` diff --git a/src/appr/prog1/parametrer.md b/src/appr/prog1/parametrer.md index 3af4bac5..eaaf1644 100644 --- a/src/appr/prog1/parametrer.md +++ b/src/appr/prog1/parametrer.md @@ -28,6 +28,10 @@ Un paramètre de fonction est une variable locale qui peut être utilisée dans Lors de l'appel de la fonction, nous donnons des valeurs à la fonction. Ces valeurs sont les **arguments** de la fonction. +```{exercise} +Faites le premier rectangle plus petit, et le deuxième plus grand. +``` + ```{codeplay} from turtle import * @@ -86,10 +90,15 @@ polygone(100, 5) # pentagon Nous revenons à notre fonction pour dessiner une maison. +```{exercise} +Ajoutez une maison de taille 100. +``` + ```{codeplay} from turtle import * def maison(d): + dot() forward (1.41*d) # sol left(90) forward(d) # mur droit @@ -118,6 +127,7 @@ up() def maison(d, c): down() + dot() fillcolor(c) begin_fill() forward (1.41*d) # sol @@ -138,6 +148,36 @@ forward(150) maison(50, 'yellow') ``` +## Drapeau tricolore + +```{exercise} +Modifiez les couleurs pour obtenir le drapeau d'un autre pay. +Créez une deuxième fonction `drapeau2(d, c, c2, c3)` qui crée un drapeau avec des barres horizontales. +``` + +```{codeplay} +from turtle import * + +def rectangle(d, d2, c): + fillcolor(c) + begin_fill() + for i in range(2): + forward(d) + left(90) + forward(d2) + left(90) + end_fill() + +def drapeau(d, c, c2, c3): + rectangle(d, 2*d, c) + forward(d) + rectangle(d, 2*d, c2) + forward(d) + rectangle(d, 2*d, c3) + +drapeau(50, 'blue', 'white', 'red') +``` + ## Arbre Pour dessiner un arbre simple, nous utilisons un segment droit pour le tronc et un disque (dot) pour le feuillage. @@ -147,6 +187,10 @@ C'est une fonction qui a 3 paramètres - `c` -- couleur du tronc - `c2` -- couleur du feuillage +```{exercise} +Definissez une fonction `foret(n)` qui dessine `n` arbres. +``` + ```{codeplay} from turtle import * @@ -207,10 +251,16 @@ bus(150, 'lightblue') ## Coeur +```{exercise} +Ajoutez deux paramètres: `w` pour l'épaisseur de la ligne (width), et `c2` pour la couleur de ligne. +La fonction aura la forme `coeur(r, w, c, c2)`. +``` + ```{codeplay} from turtle import * def coeur(r, c): + down() fillcolor(c) begin_fill() left(90) @@ -221,9 +271,11 @@ def coeur(r, c): circle(r, 225) left(90) end_fill() + up() -coeur(50, 'red') -coeur(30, 'pink') +coeur(50, 'darkviolet') +forward(130) +coeur(40, 'tomato') ``` ## Escalier @@ -236,6 +288,7 @@ coeur(30, 'pink') from turtle import * def escalier(d, d2, n): + dot() # marqueur de début for i in range(n): forward(d) left(90) @@ -522,8 +575,8 @@ def stickman(d, bras=(30, -45), jambes=(10, -30)): right(90) forward(d/2) # cou - leg(bras[0], a) - leg(bras[1], a) + leg(bras[0], d) + leg(bras[1], d) forward(d) leg(jambes[0], d) diff --git a/src/appr/prog1/repeter.md b/src/appr/prog1/repeter.md index 59c99dcc..269cf831 100644 --- a/src/appr/prog1/repeter.md +++ b/src/appr/prog1/repeter.md @@ -546,3 +546,53 @@ dot() ... done() ``` + +### TP + +Créez une scène de jeu vidéo en utilisant la répétition, des cercles et de la couleur. + +```{codeplay} +:file: tp3.py +""" +tp3 - répéter + +Nom : +Classe : +Date : + +- nommez ce fichier : tp3_classe_prenom (minuscules, sans accents) +- créez 5+ fonctions qui utilisent la répétion +- utilisez la variable d (distance) pour vos déplacements +- composez une scène de jeu vidéo (pacman, tetris, minecraft, etc. +- utilisez de la couleur +- déposez sur Moodle : + tp3_classe_prenom.py (code) + tp3_classe_prenom.eps (image vectorielle) + tp3_classe_preneom.jpg (image) +""" +from turtle import * +# from tkinter import * + +d = 20 + +def pacman(): + down() + left(45) + forward(d) + left(90) + circle(d, 270) + left(90) + forward(d) + right(135) + for i in range(5): + up() + forward(d) + dot(d/5) + +# ajoutez vos fonctions ici + +pacman() + +# Screen().getcanvas().postscript(file='tp2.eps') +done() +``` diff --git a/src/appr/resx/adressage.md b/src/appr/resx/adressage.md index d9de32b1..eb5a1b1d 100644 --- a/src/appr/resx/adressage.md +++ b/src/appr/resx/adressage.md @@ -10,7 +10,17 @@ basée aux États-Unis dont la fonction principale est la gestion de l'adressage Les noms de domaines sont gérés de manière hiérarchique, selon le *nom de domaine de premier niveau*, c'est à dire la "terminaison" de l'adresse (*.ch*, *.org*, *.fr*, etc.)Ainsi la gestion des adresses en *.ch* est confiée à Switch, une fondation suisse dont c'est le rôle principal.La personne qui a créé le site *champignons.ch* a donc réservé ce nom de domaine auprès de Switch (en passant par un intermédiaire) et peut le conserver moyennant un paiement d'environ CHF 15.- par an. -[Faire un encadré sur l'internationalisation des noms de domaines, et les controverses (.sucks)? ] + +```{didyouknow} +Au début, les noms de domaine de premier niveau étaient limités à quelques possibilités, telles que ".com" pour les organisations +commerciales, ".edu" pour les universités (américaines), ".gov" pour le gouvernement (américain), ".mil" pour l'armée (américaine), ".org" +pour les organisations (à but non-lucratif) et, dès les années 80, différents pays ont décidé d'enregistrer des noms de domaine de premier +niveau pour leur pays, par exemple ".ch" pour la Suisse, ".fr" pour la France. Puis il a été décidé d'ouvrir d'autres noms de domaine et +de les mettre aux enchères. Une entreprise a +alors décidé de vendre des domaines ".sucks" qu'elle a vendu très cher à certaines grandes entreprises (par exemple apple.sucks) qui avaient +peur que ce site ne devienne une plateforme pour les critiquer. + +```` Si les noms de domaines sont pratiques pour désigner des adresses sur Internet, les machines, elles, utilisent des nombres pour référencer les machines connectées à Internet, c'est ce qu'on appelle les *adresses IP*. Ainsi, @@ -59,6 +69,11 @@ for i in addr: ```{exercise} Lesquelles des adresses suivantes sont des adresses IP valides: +1. ```240.264.23.2``` +1. ```123.8.12.2.34``` +1. ```123.23.2``` +1. ```205.233.12.23``` + ``` Pour répondre à une telle question automatiquement nous pourrions ajouter des testes comme celui-ci. @@ -101,28 +116,35 @@ Parmi les adresses suivantes, indiquer lesquelles sont au format IPv4, lesquelle 1. ```ADEFE.ACDEA.AABCD.DDEBC.FFEDA.AEABC.ACADE.EFDF``` 1. ```1230.121D.12AEAB.1231D.4324B.2765.5435D.4378``` 1. ``` D2G3.4234.534FG.2141.12GE.12AD.85C2.GE32``` +1. ``` 123A.3213.564E.6746.2DD2.A897``` +1. ``` 124.234.432.21``` ```` -```{togofurther} Blocs et Masques - -Les adresse IP sont structurées hérarchiquement - -```` ### Gouvernance Comme les noms de domaine, les adresses IP sont gérées hiérarchiquement. Ainsi, les adresses de la forme `46.x.x.x` (c'est-à-dire celles qui commencent par `46 = 00101110`) sont assignées au Centre de Coordination Européen qui les répartit entre différents *Registres Internet locaux* tels que Switch qui va pouvoir -louer une partie de ces adresses IP à des organisations, des entreprises (par exemple des fournisseurs d'accès Internet) ou des particuliers qui en feraient la demande. +louer une partie de ces adresses IP à des organisations, des entreprises (par exemple des fournisseurs d'accès Internet) +ou des particuliers qui en feraient la demande. Certains blocs d'adresses IP sont réservés à des usages particuliers. Par exemple les adresses `10.x.x.x` ou `192.168.x.x` sont réservées aux réseaux privés, c'est-à-dire des machines qui ne communiquent pas directement avec le reste d'Internet. Ainsi, ces adresses peuvent être utilisées au sein du réseau interne des entreprises, ou pour faire communiquer différents appareils connectés (lampes, télévision, four, télécommande) au sein d'une -maison. +maison. Dans l'exemple ci-dessous, un fournisseur d'accès à Internet (tel que Swisscom par exemple) à reçu toutes les +adresses de type 213.221.x.x. Il en garde une partie pour son propre usage, par exemple pour son site web ou ses routeurs, +c'est-dire les machines qui s'occupe d'acheminer les donnée sur Internet. Une autre partie des adresses sera louée à +des entreprises ou des particuliers qui sont ses clients. Ceux-ci bénéficieront donc d'une adresse IP leur permettant d'être +joignable par le reste d'Internet. Les particuliers et entreprises ont généralement un réseau privé, un intranet, qui utilise +les adresses 10.x.x.x. + +```{figure} media/IPnetwork.svg +:width: 600 +``` ```{exercise} @@ -133,6 +155,10 @@ maison. - Combien y a-t-il d'adresses IP de type `192.168.x.x` ? ``` + + + + ### Adressage statique et dynamique Une adresse IP peut être allouée de manière *statique* ou *dynamique*. Dans le cas de l'adressage statique, on configure la machine en lui indiquant son adresse IP, est c'est elle qui annonce au réseau quelle est son @@ -151,8 +177,23 @@ Déterminez si votre machine a une adresse IP statique ou dynamique moyen pourriez-vous imaginer pour que vous puissiez vous joindre. 2. En tant que propriétaire d'un site web, vous avez accès aux adresses IP des machines qui visitent votre site. Pouvez-vous dès lors identifier une même personne -qui revient plusieurs fois sur votre site. +qui revient plusieurs fois sur votre site ? + + + ``` +```{solution} +1. Vous pouvez vous connecter tous deux à un serveur central qui a une adresse IP fixe et qui s'occupera de relayer vos message à vos adresses +dynamiques. C'est ce que fait un serveur mail ou de messagerie telle que Signal ou Whatsapp. + +2. Si elle a une adresse IP dynamique, alors elle aura probablement des adresses IP différentes lors de ses visites en des jours différents. On +ne pourra donc pas l'identifier en regardant uniquement son adresse IP. Par contre, en enregistrant d'autres paramètres que son navaigateur +voudra bien nous transmettre, tels que son système d'exploitation, la langue, l'appareil, etc., on peut reconstituer son empreinte numérique +et l'identifier ainsi. C'est ce qu'on appelle en anglais le fingerprinting, que l'on peut [bloquer avec certains navigateurs](https://www.mozilla.org/fr/firefox/features/block-fingerprinting/). + + +``` + ### Système de noms de domaine diff --git a/src/appr/resx/media/IPnetwork.svg b/src/appr/resx/media/IPnetwork.svg new file mode 100644 index 00000000..41cc08ed --- /dev/null +++ b/src/appr/resx/media/IPnetwork.svg @@ -0,0 +1,613 @@ + + + +ordi 1ordi 2imprimante10.0.1.110.0.1.2010.0.1.1010.0.1.35Modem/borne wifi chez AlicetabletteordiRouteur du fournisseur d'accèsModem/borne wifi chez Bobserveur du moteur de rechercheAutre fournisseur d’accèsExemple: le fournisseur d'accès internet a obtenu les adresses 213.221.x.x 4.78.x.x127.217.168.14 .213.221.190.41213.221.190.4510.0.1.110.0.1.2010.0.1.21213.221.0.1 diff --git a/src/appr/resx/routage.md b/src/appr/resx/routage.md index a2a42d98..c7f32a75 100644 --- a/src/appr/resx/routage.md +++ b/src/appr/resx/routage.md @@ -41,6 +41,24 @@ autre routeur soit au destinataire). +```{togofurther} Masques de réseau +Pour qu'une machine sache si une autre machine est dans le même sous-réseau qu'elle, son sous-réseau est spécifié par un +*masque* de réseau composé d'une suite de 32 bits (en IPv4) dont les $n$ premiers sont à 1 et les $32-n$ suivants sont à 0. +Par exemple, une machine peut avoir une adresse IP 128.178.23.132 avec un masque de 11111111.11111111.1111111.000000000. +Cela signifie que toutes les machines qui ont la même adresse IP là où le masque vaut 1 sont dans le même sous-réseau. Dans +notre exemple, cela correspond à toutes les adresses IP 128.178.23.x. Pour gagner de la place, les masques sont aussi exprimés +en 4 nombres décimaux, dans notre exemple 255.255.255.0, ou alors, pour faire encore plus court, on peut simplement spécifier +le nombre de 1 du masque, ce qui donne, toujours pour le même exemple, 128.178.23.132/24. + +Ainsi toutes les adresses IP qui n'a pas les même $n$ premiers bits, fait partie d'un différent sous-réseau. Pour lui envoyer +des paquets, il faudra passer par la *passerelle par défault* (*default gateway* en anglais) qui est le routeur qui s'occupe de +communiquer avec l'extérieur du sous-réseau. + +```` + + + + ### Format effectif [Mettre cette information comme facultative, utile si on veut travailler avec un vrai réseau] diff --git a/src/ens/algo1/exo/solutions.md b/src/ens/algo1/exo/solutions.md index 74cc9ec2..71ea19e7 100644 --- a/src/ens/algo1/exo/solutions.md +++ b/src/ens/algo1/exo/solutions.md @@ -1,10 +1,8 @@ - - ## Solutions des exercices ### 1. Les algorithmes -````{admonition} Exercice 4. Forme mystère +````{admonition} Exercice 1.5. Forme mystère :class: note L’algorithme suivant contrôle un crayon. Quelle forme dessine-t-il ? @@ -15,7 +13,7 @@ Répéter 8 fois : ``` ```` -`````{admonition} Solution 4. Forme mystère +`````{admonition} Solution 1.5. Forme mystère :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -51,7 +49,7 @@ Un hexagone. Pour vérifier, exécuter le code ci-dessus. On pourrait croire que ````` -````{admonition} Exercice 5. Nombre minimum +````{admonition} Exercice 1.6. Nombre minimum :class: note Ecrire un algorithme qui permet de trouver le plus petit nombre d’une liste. Penser à décomposer la solution en différentes étapes. @@ -62,7 +60,7 @@ L'algorithme trouve-t-il la bonne solution ? Sinon, modifier votre algorithme af ```` -`````{admonition} Solution 5. Nombre minimum +`````{admonition} Solution 1.6. Nombre minimum :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -141,7 +139,7 @@ Le résultat obtenu est bien le résultat attendu, l'algorithme a trouvé la plu -````{admonition} Exercice 6. Le prochain anniversaire +````{admonition} Exercice 1.7. Le prochain anniversaire :class: note On souhaite déterminer l’élève dont la date d’anniversaire est la plus proche de la date d’aujourd’hui, dans le futur. Ecrire un algorithme qui permet de trouver cet élève (utiliser un langage familier). Penser à décomposer le problème en sous-problèmes. @@ -152,7 +150,7 @@ Un ordinateur peut-il réaliser les opérations décrites par votre algorithme ? ```` -`````{admonition} Solution 6. Le prochain anniversaire +`````{admonition} Solution 1.7. Le prochain anniversaire :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -173,7 +171,7 @@ Oui, un ordinateur peut exécuter ces opérations, mais elles doivent être déc -````{admonition} Exercice 7. Echange de trois variables +````{admonition} Exercice 1.8. Echange de trois variables :class: note Écrire un algorithme qui effectue la permutation circulaire des variables X, Y et Z : à la fin de l’algorithme, X contient la valeur de Z, Y la valeur de X et Z la valeur de Y. Pour rappel, une variable ne peut contenir qu'une valeur à la fois. @@ -182,7 +180,7 @@ Conseil : mettez-vous à la place de la machine et représentez le contenu de ch ```` -`````{admonition} Solution 7. Echange de trois variables +`````{admonition} Solution 1.8. Echange de trois variables :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -208,7 +206,7 @@ Nous avons donc la confirmation que la solution obtenue résout correctement not -````{admonition} Exercice 8. Affectations +````{admonition} Exercice 1.9. Affectations :class: note Quel est le résultat de la suite des trois affectations suivantes ? @@ -223,7 +221,7 @@ X ← X – Y ```` -`````{admonition} Solution 8. Affectations +`````{admonition} Solution 1.9. Affectations :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -254,14 +252,14 @@ Cet algorithme échange les valeurs des deux variables *sans avoir le besoin d'u ### 2. Trie, cherche et trouve -````{admonition} Exercice 4. L'algorithme de votre journée +````{admonition} Exercice 2.5. L'algorithme de votre journée :class: note Réfléchissez à votre journée : y a-t-il des actions qui se retrouvent chaque jour ouvrable ? Arrivez-vous à esquisser un algorithme que vous suivez sans que vous en ayez conscience ? ```` -`````{admonition} Solution 4. L'algorithme de votre journée +`````{admonition} Solution 2.5. L'algorithme de votre journée :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -294,7 +292,7 @@ Se coucher ```` ````` -````{admonition} Exercice 5. Trois algorithmes de tri +````{admonition} Exercice 2.6. Trois algorithmes de tri :class: note @@ -302,7 +300,7 @@ Trier la liste [2,5,3,4,7,1,6] en utilisant les trois algorithmes de tri vus ada ```` -`````{admonition} Solution 5. Trois algorithmes de tri +`````{admonition} Solution 2.6. Trois algorithmes de tri :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -362,7 +360,7 @@ Voici le détail de toutes les étapes intermédiaires des trois algorithmes de ````` -````{admonition} Exercice 6. Vérificateur de tri +````{admonition} Exercice 2.7. Vérificateur de tri :class: note Ecrivez un algorithme qui vérifie si une liste est triée. @@ -377,7 +375,7 @@ Comparer vos algorithmes. Sont-ils différents ? -`````{admonition} Solution 6. Vérificateur de tri +`````{admonition} Solution 2.7. Vérificateur de tri :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -405,7 +403,7 @@ L'algorithme prend une liste (triée ou non triée) en entrée et retourne `Vrai ````` -````{admonition} Exercice 7. Mondrian +````{admonition} Exercice 2.8. Mondrian :class: note Analysez les œuvres cubistes de Piet Mondrian. Trouvez un algorithme qui permet de créer une œuvre qui pourrait être attribuée à Mondrian. @@ -414,7 +412,7 @@ Analysez les œuvres cubistes de Piet Mondrian. Trouvez un algorithme qui permet -`````{admonition} Solution 7. Mondrian +`````{admonition} Solution 2.8. Mondrian :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -452,14 +450,14 @@ Si vous avez un niveau de programmation avancé, vous pouvez essayer de coder ce ### 3. Des algorithmes aux programmes -````{admonition} Exercice 1. Jeu de la devinette 🔌 +````{admonition} Exercice 3.1. Jeu de la devinette 🔌 :class: note Ecrire le programme suivant : le programme pense à un nombre au hasard. Lorsque vous lui proposez un nombre, il vous dit si «c'est plus» ou «si c'est moins» jusqu'à ce que vous ayez trouvé. ```` -`````{admonition} Solution 1. Jeu de la devinette 🔌 +`````{admonition} Solution 3.1. Jeu de la devinette 🔌 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -503,14 +501,14 @@ La stratégie gagnante consiste à toujours viser au milieu de la plage de nombr -````{admonition} Exercice 2. Plus petit nombre 🔌 +````{admonition} Exercice 3.2. Plus petit nombre 🔌 :class: note Transcrire l’algorithme de l’exercice qui permet de déterminer le plus petit nombre d’une liste, en un programme Python. ```` -`````{admonition} Solution 2. Plus petit nombre 🔌🔌 +`````{admonition} Solution 3.2. Plus petit nombre 🔌🔌 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -543,7 +541,7 @@ print(trouver_minimum(rect)) -````{admonition} Exercice 3. Programmes de tri 🔌 +````{admonition} Exercice 3.3. Programmes de tri 🔌 :class: note Implémenter le tri à bulles et/ou le tri par insertion vus au cours. @@ -562,7 +560,7 @@ Lancer votre programme avec 100000 éléments et comparez le temps obtenu avec v ```` -`````{admonition} Solution 3. Programmes de tri +`````{admonition} Solution 3.3. Programmes de tri :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -685,7 +683,7 @@ plt.show() -````{admonition} Exercice 4. Bogosort 🔌 +````{admonition} Exercice 3.4. Bogosort 🔌 :class: note Coder l’algorithme du tri de Bogo en Python (voir chapitre 2 : Le saviez-vous ?). @@ -696,7 +694,7 @@ A partir de quelle taille de liste cet algorithme est-il inutilisable ? ```` -`````{admonition} Solution 4. Tri de Bogo +`````{admonition} Solution 3.4. Tri de Bogo :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -738,7 +736,7 @@ En relançant le programme une dizaine de fois, le minimum d'itérations nécess -````{admonition} Exercice 5. Fibonacci 🔌 +````{admonition} Exercice 3.5. Fibonacci 🔌 :class: note Ecrire un algorithme qui calcule la suite des nombres de Fibonacci. @@ -749,7 +747,7 @@ Comparer avec les solutions trouvées par vos camarades de classe. ```` -`````{admonition} Solution 5. Fibonacci 🔌 +`````{admonition} Solution 3.5. Fibonacci 🔌 :class: hint ````{dropdown} Cliquer ici pour voir la réponse @@ -840,432 +838,4 @@ if nb : -```{admonition} Exercice 3.4. Une question à un million -:class: note - -Si une instruction prend 10-6 secondes, combien de temps faut-il pour trier un tableau d’un million d’éléments avec le tri à sélection comparé au tri rapide (sans tenir compte de la constante) ? - -``` - -````{admonition} Solution 3.4. Une question à un million -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Pour trier 1 million d’éléments, le tri par sélection prend 106*106 *10-6 secondes ou 1 million de secondes (équivalent à plus de 11 jours), alors que le tri rapide a besoin de log2(106)*106 *10-6 ou ~20 secondes. - -Cette différence de temps est suffisante pour rendre rédhibitoire l’utilisation du tri par sélection. Pensez au nombre de clients qu’un réseau social possède, ou au nombre de produits qu’un supermarché doit gérer. -``` -```` - - -```{admonition} Exercice 3.5. Une question de pivot -:class: note - -Trier le tableau suivant avec l’algorithme de tri rapide : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main, en prenant le dernier élément comme pivot. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -Est-ce que le choix du pivot est important ? - -``` - -````{admonition} Solution 3.5. Une question de pivot -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri rapide, l’élément pivot est 5. On se retrouve donc avec les deux tableaux suivants : - -     [[3, 1, 4, 2], 5, [6, 8, 7, 9]] - -Les nouveaux éléments pivots sont les derniers éléments des nouveaux tableaux de gauche [3, 1, 4, 2] et le tableau de droite [6, 8, 7, 9] , donc 2 et 9. On réarrange tous les éléments des tableaux autour des éléments pivots, selon leur taille : - -     [[1], 2, [3, 4], 5, [6, 8, 7], 9 [ ]] - -On continue les mêmes opérations pour les tableaux qui contiennent plus d’un élément : [3, 4] et [6, 8, 7]. Les nouveaux pivots sont 4 et 7, car ils sont les derniers éléments des tableaux restants à plus d’un élément : - -     [1, 2, [3], 4, [ ], 5, [6], 7, [8], 9] - -Il ne reste plus de tableaux de plus d’un élément, le tableau est donc trié : - -     [1, 2, 3, 4, 5, 6, 7, 8, 9] - -Le choix du pivot est important et à prendre en compte si on a des indications sur le tableau à trier. - -``` -```` - - - - -```{admonition} Exercice 3.6. Une question de sélection -:class: note - -Trier le tableau suivant avec l’algorithme de tri par sélection : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - -````{admonition} Solution 3.6. Une question de sélection -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri par insertion, on cherche à trouver la bonne position du 2e élément, dans ce cas l’élément 6 reste au même emplacement, car 3 est plus petit que 6 : - -     [3, **6**, 8, 7, 1, 9, 4, 2, 5] - -Le prochain élément considéré est le 8. Cet élément est également déjà bien placé : - -         [**3**, **6**, **8**, 7, 1, 9, 4, 2, 5] - -Comme l’ordre des éléments ne change pas, nous notons cette configuration à droite. - -Le prochain élément considéré est le 7. Cet élément n’est pas bien placé au regard du tableau que l’on a déjà trié. Sa place est avant le 8, on va donc l’insérer entre le 6 et le 8 : - -         [**3**, **6**, **8**, **7**, 1, 9, 4, 2, 5] - -     [**3**, **6**, **7**, **8**, 1, 9, 4, 2, 5] - -Le prochain élément de la liste non triée est le 1 : - -     [**3**, **6**, **7**, **8**, **1**, 9, 4, 2, 5] - -Nous allons l’insérer à la bonne position du tableau déjà trié, c’est-à-dire tout au début : - -     [**1**, **3**, **6**, **7**, **8**, 9, 4, 2, 5] - -Tous les éléments qui ont changé de position dans l’étape précédente sont désignés en rouge. Le prochain élément à considérer est le 9. Il est déjà bien placé par rapport à la partie triée du tableau : - -         [**1**, **3**, **6**, **7**, **8**, **9**, 4, 2, 5] - -On continue de la sorte jusqu’à ce que tous les éléments du tableau soient parcourus : - -         [**1**, **3**, **6**, **7**, **8**, **9**, **4**, 2, 5] - -     [**1**, **3**, **4**, **6**, **7**, **8**, **9**, 2, 5] - -         [**1**, **3**, **4**, **6**, **7**, **8**, **9**, **2**, 5] - -     [**1**, **2**, **3**, **4**, **6**, **7**, **8**, **9**, 5] - -         [**1**, **2**, **3**, **4**, **6**, **7**, **8**, **9**, **5**] - -Lorsque le dernier élément du tableau est inséré à la bonne position, tout le tableau est trié : - -     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - -``` -```` - - -```{admonition} Exercice 3.7. Une question d'insertion -:class: note - -Trier le tableau suivant avec l’algorithme de tri par insertion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - -````{admonition} Solution 3.7. Une question d'insertion -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors de la première étape du tri par sélection, on cherche le plus petit élément : - -     [3, 6, 8, 7, **1**, 9, 4, 2, 5] - -On échange les positions du premier et du plus petit élément : - -     [**1**, 6, 8, 7, **3**, 9, 4, 2, 5] - -On cherche le plus petit élément dans le tableau, en excluant l’élément que l’on vient de trier : - -         [**1**, 6, 8, 7, 3, 9, 4, **2**, 5] - -On échange sa position avec le 2e élément du tableau : - -     [**1**, **2**, 8, 7, 3, 9, 4, **6**, 5] - -Notez que les étapes qui changent l’ordre des éléments du tableau sont disposées à gauche. On cherche le plus petit élément du tableau non trié et on l’échange avec le troisième élément : - -         [**1**, **2**, 8, 7, **3**, 9, 4, 6, 5] - -     [**1**, **2**, **3**, 7, **8**, 9, 4, 6, 5] - -On continue de la sorte jusqu’à ce que tous les éléments soient triés (les éléments triés sont en vert) : - -         [**1**, **2**, **3**, 7, 8, 9, **4**, 6, 5] - -     [**1**, **2**, **3**, **4**, 8, 9, **7**, 6, 5] - -         [**1**, **2**, **3**, **4**, 8, 9, 7, 6, **5**] - -     [**1**, **2**, **3**, **4**, **5**, 9, 7, 6, **8**] - -         [**1**, **2**, **3**, **4**, **5**, 9, 7, **6**, 8] - -     [**1**, **2**, **3**, **4**, **5**, **6**, 7, **9**, 8] - -Le septième élément du tableau est déjà à la bonne position, donc il n’y a pas besoin d’échanger la position de deux éléments. Le tableau est trié lorsque tous les éléments sont parcourus. - -         [**1**, **2**, **3**, **4**, **5**, **6**, **7**, 9, 8] - -         [**1**, **2**, **3**, **4**, **5**, **6**, **7**, 9, **8**] - - -     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - -``` -```` - - - -```{admonition} Exercice 3.8. Une question de bulles -:class: note - -Trier le tableau suivant avec l’algorithme de tri à bulles : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - - -````{admonition} Solution 3.8. Une question de bulles -:class: hint - -```{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Lors du tri à bulles, on considère les éléments deux par deux. S’ils sont dans le bon ordre, on ne fait rien, sinon on échange leur position : - -     [**3**, **6**, 8, 7, 1, 9, 4, 2, 5] -    [3, **6**, **8**, 7, 1, 9, 4, 2, 5] -    [3, 6, **8**, **7**, 1, 9, 4, 2, 5] -        [3, 6, **7**, **8**, 1, 9, 4, 2, 5] -    [3, 6, 7, **8**, **1**, 9, 4, 2, 5] -        [3, 6, 7, **1**, **8**, 9, 4, 2, 5] -    [3, 6, 7, 1, **8**, **9**, 4, 2, 5] -    [3, 6, 7, 1, 8, **9**, **4**, 2, 5] -        [3, 6, 7, 1, 8, **4**, **9**, 2, 5] -    [3, 6, 7, 1, 8, 4, **9**, **2**, 5] -        [3, 6, 7, 1, 8, 4, **2**, **9**, 5] -    [3, 6, 7, 1, 8, 4, 2, **9**, **5**] -        [3, 6, 7, 1, 8, 4, 2, **5**, **9**] - -Il faut procéder à nouveau par un parcours de la liste depuis son début, où on compare et on réarrange les éléments deux par deux : - -     [**3**, **6**, 7, 1, 8, 4, 2, 5, **9**] -     [3, **6**, **7**, 1, 8, 4, 2, 5, **9**] -     [3, 6, **7**, **1**, 8, 4, 2, 5, **9**] -         [3, 6, **1**, **7**, 8, 4, 2, 5, **9**] -     [3, 6, 1, **7**, **8**, 4, 2, 5, **9**] -     [3, 6, 1, 7, **8**, **4**, 2, 5, **9**] -         [3, 6, 1, 7, **4**, **8**, 2, 5, **9**] -     [3, 6, 1, 7, 4, **8**, **2**, 5, **9**] -         [3, 6, 1, 7, 4, **2**, **8**, 5, **9**] -     [3, 6, 1, 7, 4, 2, **8**, **5**, **9**] -          [3, 6, 1, 7, 4, 2, **5**, **8**, **9**] - -Une deuxième « bulle » remonte, le deuxième élément le plus grand. On refait à nouveau un parcours du tableau (les éléments bien triés sont en gras) : - -     [**3**, **6**, 1, 7, 4, 2, 5, **8**, **9**] -     [3, **6**, **1**, 1, 7, 4, 2, 5, **8**, **9**] -         [3, **1**, **6**, 7, 4, 2, 5, **8**, **9**] -     [3, 1, **6**, **7**, 4, 2, 5, **8**, **9**] -     [3, 1, 6, **7**, **4**, 2, 5, **8**, **9**] -         [3, 1, 6, **4**, **7**, 2, 5, **8**, **9**] -     [3, 1, 6, 4, **7**, **2**, 5, **8**, **9**] -         [3, 1, 6, 4, **2**, **7**, 5, **8**, **9**] -     [3, 1, 6, 4, 2, **7**, **5**, **8**, **9**] -         [3, 1, 6, 4, 2, **5**, **7**, **8**, **9**] - -Lorsqu’on atteint la partie déjà triée du tableau (éléments en gras), on recommence depuis le début du tableau : - -     [**3**, **1**, 6, 4, 2, 5, **7**, **8**, **9**] -         [**1**, **3**, 6, 4, 2, 5, **7**, **8**, **9**] -     [1, **3**, **6**, 4, 2, 5, **7**, **8**, **9**] -     [1, 3, **6**, **4**, 2, 5, **7**, **8**, **9**] -         [1, 3, **4**, **6**, 2, 5, **7**, **8**, **9**] -     [1, 3, 4, **6**, **2**, 5, **7**, **8**, **9**] -         [1, 3, 4, **2**, **6**, 5, **7**, **8**, **9**] -     [1, 3, 4, 2, **6**, **5**, **7**, **8**, **9**] -         [1, 3, 4, 2, **5**, **6**, **7**, **8**, **9**] - -On a atteint la partie triée du tableau, on recommence depuis le début : - -     [**1**, **3**, 4, 2, 5, **6**, **7**, **8**, **9**] -     [1, **3**, **4**, 2, 5, **6**, **7**, **8**, **9**] -     [1, 3, **4**, **2**, 5, **6**, **7**, **8**, **9**] -         [1, 3, **2**, **4**, 5, **6**, **7**, **8**, **9**] -     [1, 3, 2, **4**, **5**, **6**, **7**, **8**, **9**] - -Les bulles (les plus grands nombres) continuent à remonter : - -     [**1**, **3**, 2, 4, 5, **6**, **7**, **8**, **9**] -     [1, **3**, **2**, 4, 5, **6**, **7**, **8**, **9**] -         [1, **2**, **3**, 4, 5, **6**, **7**, **8**, **9**] -     [1, 2, **3**, **4**, 5, **6**, **7**, **8**, **9**] -     [1, 2, 3, **4**, **5**, **6**, **7**, **8**, **9**] - -On recommence à nouveau à comparer les éléments depuis le début du tableau : - -     [**1**, **2**, 3, 4, **5**, **6**, **7**, **8**, **9**] -     [1, **2**, **3**, 4, **5**, **6**, **7**, **8**, **9**] -     [1, 2, **3**, **4**, 4, **5**, **6**, **7**, **8**, **9**] - -Même si nous n'avons pas du intervertir la position de deux éléments, il faut à nouveau parcourir le tableau depuis le début : - -     [**1**, **2**, 3, **4**, **5**, **6**, **7**, **8**, **9**] -     [1, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - -Et on fait une dernière comparaison : - -     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - -Le tableau est désormais trié : - -     [1, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] - - -``` -```` - - -````{admonition} Exercice 3.9. Une question de chronomètre 🔌 -:class: note - -Créer une liste qui contient les valeurs de 1 à n dans un ordre aléatoire, où n prend la valeur 100, par exemple. Indice : utiliser la fonction `shuffle()` du module `random`. - -Implémenter au moins deux des trois algorithmes de tri vu au cours. -A l’aide du module `time` et de sa fonction `time()`, chronométrer le temps prend le tri d'une liste de 100, 500, 1000, 10000, 20000, 30000, 40000 puis 50000 nombres. - -Noter les temps obtenus et les afficher sous forme de courbe dans un tableur. Ce graphique permet de visualiser le temps d’exécution du tri en fonction de la taille de la liste. Que peut-on constater ? - -Sur la base de ces mesures, peut-on estimer le temps que prendrait le tri de 100000 éléments ? - -Lancer votre programme avec 100000 éléments et comparer le temps obtenu avec votre estimation. - -```` - -**Solution à compléter** - - - -```{admonition} Exercice 4.2. Une question de fusion -:class: note - -Trier le tableau suivant avec l’algorithme de tri par fusion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. - -``` - - -**Solution à compléter** - -````{admonition} Exercice 4.3. Dans l'autre sens 🔌 -:class: note - -En Python, proposer une fonction qui inverse l’ordre des lettres dans un mot. Vous pouvez parcourir les lettres du mot directement ou à travers un indice. - -Proposer une autre fonction qui inverse l’ordre des lettres dans un mot de manière récursive. - -```` - - - -`````{admonition} Solution 4.3. Dans l'autre sens 🔌 -:class: hint - -````{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Voici plusieurs implémentations itératives et une récursive de la fonction qui inverse un mot : - -```{codeplay} - -def inverser_mot_iteratif(mot) : - mot_inverse = "" - for lettre in mot : - mot_inverse = lettre + mot_inverse - return mot_inverse - -def inverser_mot_iteratif_2(mot) : - mot_inverse = "" - for indice in range(len(mot)-1,-1,-1) : - mot_inverse += mot[indice] - return mot_inverse - -def inverser_mot_recursif(mot) : - if len(mot) == 1: - return mot - else : - return inverser_mot_recursif(mot[1:]) + mot[0] - -un_mot = "mot" - -print(inverser_mot_iteratif(un_mot)) -print(inverser_mot_iteratif_2(un_mot)) -print(inverser_mot_recursif(un_mot)) - -``` -```` -````` - - - - -````{admonition} Exercice 4.4. Factorielle 🔌 -:class: note - -La fonction factorielle `n!` en mathématiques est le produit de tous les nombres entiers jusqu’à `n`. C’est une des fonctions les plus simples à calculer de manière récursive. Elle peut être définie comme ceci : - - n! = (n-1)! * n - -Programmer cette fonction de manière récursive en Python. Proposer également une implémentation itérative de la factorielle où les éléments de 1 à `n` sont traités l’un après l’autre. - -```` - - -`````{admonition} Solution 4.4. Factorielle 🔌 -:class: hint - -````{dropdown} Cliquer ici pour voir la réponse -:animate: fade-in-slide-down - -Voici une implémentation en Python de la fonction factorielle où la fonction fait appel à elle-même, sans oublier la condition d’arrêt : - -```{codeplay} -# fonction factorielle (définition récursive) -def factorielle_recursive(nombre): - - if nombre == 1: - res = 1 - else: - res = nombre * factorielle_recursive(nombre-1) - - return res - -res = factorielle_recursive(5) -print(res) - -``` - -Voici une implémentation en Python de la fonction factorielle qui n’est pas récursive : - -```{codeplay} - -def factorielle(nombre): - res = 1 - for n in range(2,nombre+1) : - res = res * n - return res - -res = factorielle(5) -print(res) - -``` -```` -````` - - diff --git a/src/ens/algo2/exo/index.md b/src/ens/algo2/exo/index.md new file mode 100644 index 00000000..f05e3fb2 --- /dev/null +++ b/src/ens/algo2/exo/index.md @@ -0,0 +1,4 @@ +```{toctree} +:maxdepth: 1 +Solutions des exercices +``` \ No newline at end of file diff --git a/src/ens/algo2/exo/solutions.md b/src/ens/algo2/exo/solutions.md new file mode 100644 index 00000000..1fe16115 --- /dev/null +++ b/src/ens/algo2/exo/solutions.md @@ -0,0 +1,451 @@ +### 2. Algorithmes de recherche + +## Exercices + +```{admonition} Exercice 2.6. Recherche binaire aléatoire 🔌 +:class: note + +Modifier votre programme de recherche binaire : au lieu de diviser l’espace de recherche exactement au milieu, le diviser au hasard. Cette recherche avec une composante aléatoire s’apparente plus à la recherche que l’on fait lorsque l’on cherche un mot dans le dictionnaire. + +``` + +**Solution à compléter** + + + + +### 1. Algorithmes de tri + + +```{admonition} Exercice 3.5. Une question à un million +:class: note + +Si une instruction prend 10-6 secondes, combien de temps faut-il pour trier un tableau d’un million d’éléments avec le tri à sélection comparé au tri rapide (sans tenir compte de la constante) ? + +``` + +````{admonition} Solution 3.5. Une question à un million +:class: hint + +```{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Pour trier 1 million d’éléments, le tri par sélection prend 106*106 *10-6 secondes ou 1 million de secondes (équivalent à plus de 11 jours), alors que le tri rapide a besoin de log2(106)*106 *10-6 ou ~20 secondes. + +Cette différence de temps est suffisante pour rendre rédhibitoire l’utilisation du tri par sélection. Pensez au nombre de clients qu’un réseau social possède, ou au nombre de produits qu’un supermarché doit gérer. +``` +```` + + +```{admonition} Exercice 3.6. Une question de pivot +:class: note + +Trier le tableau suivant avec l’algorithme de tri rapide : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main, en prenant le dernier élément comme pivot. Représenter l’état du tableau lors de toutes les étapes intermédiaires. + +Est-ce que le choix du pivot est important ? + +``` + +````{admonition} Solution 3.6. Une question de pivot +:class: hint + +```{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Lors de la première étape du tri rapide, l’élément pivot est 5. On se retrouve donc avec les deux tableaux suivants : + +     [[3, 1, 4, 2], 5, [6, 8, 7, 9]] + +Les nouveaux éléments pivots sont les derniers éléments des nouveaux tableaux de gauche [3, 1, 4, 2] et le tableau de droite [6, 8, 7, 9] , donc 2 et 9. On réarrange tous les éléments des tableaux autour des éléments pivots, selon leur taille : + +     [[1], 2, [3, 4], 5, [6, 8, 7], 9 [ ]] + +On continue les mêmes opérations pour les tableaux qui contiennent plus d’un élément : [3, 4] et [6, 8, 7]. Les nouveaux pivots sont 4 et 7, car ils sont les derniers éléments des tableaux restants à plus d’un élément : + +     [1, 2, [3], 4, [ ], 5, [6], 7, [8], 9] + +Il ne reste plus de tableaux de plus d’un élément, le tableau est donc trié : + +     [1, 2, 3, 4, 5, 6, 7, 8, 9] + +Le choix du pivot est important et à prendre en compte si on a des indications sur le tableau à trier. + +``` +```` + + + + +```{admonition} Exercice 3.7. Une question de sélection +:class: note + +Trier le tableau suivant avec l’algorithme de tri par sélection : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. + +``` + +````{admonition} Solution 3.7. Une question de sélection +:class: hint + +```{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Lors de la première étape du tri par insertion, on cherche à trouver la bonne position du 2e élément, dans ce cas l’élément 6 reste au même emplacement, car 3 est plus petit que 6 : + +     [3, **6**, 8, 7, 1, 9, 4, 2, 5] + +Le prochain élément considéré est le 8. Cet élément est également déjà bien placé : + +         [**3**, **6**, **8**, 7, 1, 9, 4, 2, 5] + +Comme l’ordre des éléments ne change pas, nous notons cette configuration à droite. + +Le prochain élément considéré est le 7. Cet élément n’est pas bien placé au regard du tableau que l’on a déjà trié. Sa place est avant le 8, on va donc l’insérer entre le 6 et le 8 : + +         [**3**, **6**, **8**, **7**, 1, 9, 4, 2, 5] + +     [**3**, **6**, **7**, **8**, 1, 9, 4, 2, 5] + +Le prochain élément de la liste non triée est le 1 : + +     [**3**, **6**, **7**, **8**, **1**, 9, 4, 2, 5] + +Nous allons l’insérer à la bonne position du tableau déjà trié, c’est-à-dire tout au début : + +     [**1**, **3**, **6**, **7**, **8**, 9, 4, 2, 5] + +Tous les éléments qui ont changé de position dans l’étape précédente sont désignés en rouge. Le prochain élément à considérer est le 9. Il est déjà bien placé par rapport à la partie triée du tableau : + +         [**1**, **3**, **6**, **7**, **8**, **9**, 4, 2, 5] + +On continue de la sorte jusqu’à ce que tous les éléments du tableau soient parcourus : + +         [**1**, **3**, **6**, **7**, **8**, **9**, **4**, 2, 5] + +     [**1**, **3**, **4**, **6**, **7**, **8**, **9**, 2, 5] + +         [**1**, **3**, **4**, **6**, **7**, **8**, **9**, **2**, 5] + +     [**1**, **2**, **3**, **4**, **6**, **7**, **8**, **9**, 5] + +         [**1**, **2**, **3**, **4**, **6**, **7**, **8**, **9**, **5**] + +Lorsque le dernier élément du tableau est inséré à la bonne position, tout le tableau est trié : + +     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] + +``` +```` + + +```{admonition} Exercice 3.8. Une question d'insertion +:class: note + +Trier le tableau suivant avec l’algorithme de tri par insertion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. + +``` + +````{admonition} Solution 3.8. Une question d'insertion +:class: hint + +```{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Lors de la première étape du tri par sélection, on cherche le plus petit élément : + +     [3, 6, 8, 7, **1**, 9, 4, 2, 5] + +On échange les positions du premier et du plus petit élément : + +     [**1**, 6, 8, 7, **3**, 9, 4, 2, 5] + +On cherche le plus petit élément dans le tableau, en excluant l’élément que l’on vient de trier : + +         [**1**, 6, 8, 7, 3, 9, 4, **2**, 5] + +On échange sa position avec le 2e élément du tableau : + +     [**1**, **2**, 8, 7, 3, 9, 4, **6**, 5] + +Notez que les étapes qui changent l’ordre des éléments du tableau sont disposées à gauche. On cherche le plus petit élément du tableau non trié et on l’échange avec le troisième élément : + +         [**1**, **2**, 8, 7, **3**, 9, 4, 6, 5] + +     [**1**, **2**, **3**, 7, **8**, 9, 4, 6, 5] + +On continue de la sorte jusqu’à ce que tous les éléments soient triés (les éléments triés sont en vert) : + +         [**1**, **2**, **3**, 7, 8, 9, **4**, 6, 5] + +     [**1**, **2**, **3**, **4**, 8, 9, **7**, 6, 5] + +         [**1**, **2**, **3**, **4**, 8, 9, 7, 6, **5**] + +     [**1**, **2**, **3**, **4**, **5**, 9, 7, 6, **8**] + +         [**1**, **2**, **3**, **4**, **5**, 9, 7, **6**, 8] + +     [**1**, **2**, **3**, **4**, **5**, **6**, 7, **9**, 8] + +Le septième élément du tableau est déjà à la bonne position, donc il n’y a pas besoin d’échanger la position de deux éléments. Le tableau est trié lorsque tous les éléments sont parcourus. + +         [**1**, **2**, **3**, **4**, **5**, **6**, **7**, 9, 8] + +         [**1**, **2**, **3**, **4**, **5**, **6**, **7**, 9, **8**] + + +     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] + +``` +```` + + + +```{admonition} Exercice 3.9. Une question de bulles +:class: note + +Trier le tableau suivant avec l’algorithme de tri à bulles : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. + +``` + + +````{admonition} Solution 3.9. Une question de bulles +:class: hint + +```{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Lors du tri à bulles, on considère les éléments deux par deux. S’ils sont dans le bon ordre, on ne fait rien, sinon on échange leur position : + +     [**3**, **6**, 8, 7, 1, 9, 4, 2, 5] +    [3, **6**, **8**, 7, 1, 9, 4, 2, 5] +    [3, 6, **8**, **7**, 1, 9, 4, 2, 5] +        [3, 6, **7**, **8**, 1, 9, 4, 2, 5] +    [3, 6, 7, **8**, **1**, 9, 4, 2, 5] +        [3, 6, 7, **1**, **8**, 9, 4, 2, 5] +    [3, 6, 7, 1, **8**, **9**, 4, 2, 5] +    [3, 6, 7, 1, 8, **9**, **4**, 2, 5] +        [3, 6, 7, 1, 8, **4**, **9**, 2, 5] +    [3, 6, 7, 1, 8, 4, **9**, **2**, 5] +        [3, 6, 7, 1, 8, 4, **2**, **9**, 5] +    [3, 6, 7, 1, 8, 4, 2, **9**, **5**] +        [3, 6, 7, 1, 8, 4, 2, **5**, **9**] + +Il faut procéder à nouveau par un parcours de la liste depuis son début, où on compare et on réarrange les éléments deux par deux : + +     [**3**, **6**, 7, 1, 8, 4, 2, 5, **9**] +     [3, **6**, **7**, 1, 8, 4, 2, 5, **9**] +     [3, 6, **7**, **1**, 8, 4, 2, 5, **9**] +         [3, 6, **1**, **7**, 8, 4, 2, 5, **9**] +     [3, 6, 1, **7**, **8**, 4, 2, 5, **9**] +     [3, 6, 1, 7, **8**, **4**, 2, 5, **9**] +         [3, 6, 1, 7, **4**, **8**, 2, 5, **9**] +     [3, 6, 1, 7, 4, **8**, **2**, 5, **9**] +         [3, 6, 1, 7, 4, **2**, **8**, 5, **9**] +     [3, 6, 1, 7, 4, 2, **8**, **5**, **9**] +          [3, 6, 1, 7, 4, 2, **5**, **8**, **9**] + +Une deuxième « bulle » remonte, le deuxième élément le plus grand. On refait à nouveau un parcours du tableau (les éléments bien triés sont en gras) : + +     [**3**, **6**, 1, 7, 4, 2, 5, **8**, **9**] +     [3, **6**, **1**, 1, 7, 4, 2, 5, **8**, **9**] +         [3, **1**, **6**, 7, 4, 2, 5, **8**, **9**] +     [3, 1, **6**, **7**, 4, 2, 5, **8**, **9**] +     [3, 1, 6, **7**, **4**, 2, 5, **8**, **9**] +         [3, 1, 6, **4**, **7**, 2, 5, **8**, **9**] +     [3, 1, 6, 4, **7**, **2**, 5, **8**, **9**] +         [3, 1, 6, 4, **2**, **7**, 5, **8**, **9**] +     [3, 1, 6, 4, 2, **7**, **5**, **8**, **9**] +         [3, 1, 6, 4, 2, **5**, **7**, **8**, **9**] + +Lorsqu’on atteint la partie déjà triée du tableau (éléments en gras), on recommence depuis le début du tableau : + +     [**3**, **1**, 6, 4, 2, 5, **7**, **8**, **9**] +         [**1**, **3**, 6, 4, 2, 5, **7**, **8**, **9**] +     [1, **3**, **6**, 4, 2, 5, **7**, **8**, **9**] +     [1, 3, **6**, **4**, 2, 5, **7**, **8**, **9**] +         [1, 3, **4**, **6**, 2, 5, **7**, **8**, **9**] +     [1, 3, 4, **6**, **2**, 5, **7**, **8**, **9**] +         [1, 3, 4, **2**, **6**, 5, **7**, **8**, **9**] +     [1, 3, 4, 2, **6**, **5**, **7**, **8**, **9**] +         [1, 3, 4, 2, **5**, **6**, **7**, **8**, **9**] + +On a atteint la partie triée du tableau, on recommence depuis le début : + +     [**1**, **3**, 4, 2, 5, **6**, **7**, **8**, **9**] +     [1, **3**, **4**, 2, 5, **6**, **7**, **8**, **9**] +     [1, 3, **4**, **2**, 5, **6**, **7**, **8**, **9**] +         [1, 3, **2**, **4**, 5, **6**, **7**, **8**, **9**] +     [1, 3, 2, **4**, **5**, **6**, **7**, **8**, **9**] + +Les bulles (les plus grands nombres) continuent à remonter : + +     [**1**, **3**, 2, 4, 5, **6**, **7**, **8**, **9**] +     [1, **3**, **2**, 4, 5, **6**, **7**, **8**, **9**] +         [1, **2**, **3**, 4, 5, **6**, **7**, **8**, **9**] +     [1, 2, **3**, **4**, 5, **6**, **7**, **8**, **9**] +     [1, 2, 3, **4**, **5**, **6**, **7**, **8**, **9**] + +On recommence à nouveau à comparer les éléments depuis le début du tableau : + +     [**1**, **2**, 3, 4, **5**, **6**, **7**, **8**, **9**] +     [1, **2**, **3**, 4, **5**, **6**, **7**, **8**, **9**] +     [1, 2, **3**, **4**, 4, **5**, **6**, **7**, **8**, **9**] + +Même si nous n'avons pas du intervertir la position de deux éléments, il faut à nouveau parcourir le tableau depuis le début : + +     [**1**, **2**, 3, **4**, **5**, **6**, **7**, **8**, **9**] +     [1, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] + +Et on fait une dernière comparaison : + +     [**1**, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] + +Le tableau est désormais trié : + +     [1, **2**, **3**, **4**, **5**, **6**, **7**, **8**, **9**] + + +``` +```` + + +````{admonition} Exercice 3.10. Une question de chronomètre 🔌 +:class: note + +Créer une liste qui contient les valeurs de 1 à n dans un ordre aléatoire, où n prend la valeur 100, par exemple. Indice : utiliser la fonction `shuffle()` du module `random`. + +Implémenter au moins deux des trois algorithmes de tri vu au cours. +A l’aide du module `time` et de sa fonction `time()`, chronométrer le temps prend le tri d'une liste de 100, 500, 1000, 10000, 20000, 30000, 40000 puis 50000 nombres. + +Noter les temps obtenus et les afficher sous forme de courbe dans un tableur. Ce graphique permet de visualiser le temps d’exécution du tri en fonction de la taille de la liste. Que peut-on constater ? + +Sur la base de ces mesures, peut-on estimer le temps que prendrait le tri de 100000 éléments ? + +Lancer votre programme avec 100000 éléments et comparer le temps obtenu avec votre estimation. + +```` + +**Solution à compléter** + + + +## 4. Récursivité [en option] + + +```{admonition} Exercice 5.3. Une question de fusion +:class: note + +Trier le tableau suivant avec l’algorithme de tri par fusion : [3, 6, 8, 7, 1, 9, 4, 2, 5] à la main. Représenter l’état du tableau lors de toutes les étapes intermédiaires. + +``` + + +**Solution à compléter** + +````{admonition} Exercice 5.4. Dans l'autre sens 🔌 +:class: note + +En Python, proposer une fonction qui inverse l’ordre des lettres dans un mot. Vous pouvez parcourir les lettres du mot directement ou à travers un indice. + +Proposer une autre fonction qui inverse l’ordre des lettres dans un mot de manière récursive. + +```` + + + +`````{admonition} Solution 5.4. Dans l'autre sens 🔌 +:class: hint + +````{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Voici plusieurs implémentations itératives et une récursive de la fonction qui inverse un mot : + +```{codeplay} + +def inverser_mot_iteratif(mot) : + mot_inverse = "" + for lettre in mot : + mot_inverse = lettre + mot_inverse + return mot_inverse + +def inverser_mot_iteratif_2(mot) : + mot_inverse = "" + for indice in range(len(mot)-1,-1,-1) : + mot_inverse += mot[indice] + return mot_inverse + +def inverser_mot_recursif(mot) : + if len(mot) == 1: + return mot + else : + return inverser_mot_recursif(mot[1:]) + mot[0] + +un_mot = "mot" + +print(inverser_mot_iteratif(un_mot)) +print(inverser_mot_iteratif_2(un_mot)) +print(inverser_mot_recursif(un_mot)) + +``` +```` +````` + + + + +````{admonition} Exercice 5.5. Factorielle 🔌 +:class: note + +La fonction factorielle `n!` en mathématiques est le produit de tous les nombres entiers jusqu’à `n`. C’est une des fonctions les plus simples à calculer de manière récursive. Elle peut être définie comme ceci : + + n! = (n-1)! * n + +Programmer cette fonction de manière récursive en Python. Proposer également une implémentation itérative de la factorielle où les éléments de 1 à `n` sont traités l’un après l’autre. + +```` + + +`````{admonition} Solution 5.5. Factorielle 🔌 +:class: hint + +````{dropdown} Cliquer ici pour voir la réponse +:animate: fade-in-slide-down + +Voici une implémentation en Python de la fonction factorielle où la fonction fait appel à elle-même, sans oublier la condition d’arrêt : + +```{codeplay} +# fonction factorielle (définition récursive) +def factorielle_recursive(nombre): + + if nombre == 1: + res = 1 + else: + res = nombre * factorielle_recursive(nombre-1) + + return res + +res = factorielle_recursive(5) +print(res) + +``` + +Voici une implémentation en Python de la fonction factorielle qui n’est pas récursive : + +```{codeplay} + +def factorielle(nombre): + res = 1 + for n in range(2,nombre+1) : + res = res * n + return res + +res = factorielle(5) +print(res) + +``` +```` +````` + + + diff --git a/src/ens/algo2/index.md b/src/ens/algo2/index.md index c18f0d7c..810d1f06 100644 --- a/src/ens/algo2/index.md +++ b/src/ens/algo2/index.md @@ -1 +1,6 @@ -# Algorithmique II \ No newline at end of file +# Algorithmique II + +:maxdepth: 1 + +Solutions des exercices +``` \ No newline at end of file diff --git a/src/ens/conf.py b/src/ens/conf.py index 2fb22d48..e5d8e0e4 100644 --- a/src/ens/conf.py +++ b/src/ens/conf.py @@ -133,7 +133,7 @@ }, } -html_css_files = ['styles/global.css', 'styles/reactions.css', 'styles/progress.css', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'] +html_css_files = ['styles/global.css', 'styles/global_ens.css', 'styles/reactions.css', 'styles/progress.css', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/src/ens/enjx1/grandes-thematiques/economie-numerique.md b/src/ens/enjx1/grandes-thematiques/economie-numerique.md index 601c8a99..860d348c 100644 --- a/src/ens/enjx1/grandes-thematiques/economie-numerique.md +++ b/src/ens/enjx1/grandes-thematiques/economie-numerique.md @@ -347,7 +347,7 @@ d) Comment Google est-elle devenue une des entreprises les plus riches au monde, ````{dropdown} **Réponse** L’objectif de Google n’est pas de vendre des produits ou services aux internautes mais de recueillir le plus grand nombre de traces concernant leur profil et leur comportement (notamment au travers de sa régie Doubleclick) afin de proposer à des annonceurs des espaces publicitaires ciblés, L’entreprise a donc intérêt à offrir des services gratuits afin de maximiser le nombre d’utilisateurs et d’interactions sur toutes ses plateformes (Gmail, Chrome, Google Maps, YouTube, etc.). Par ailleurs, plus ces services comptent d’usagers, plus ils deviennent attractifs et performants, à la fois pour les utilisateurs et les annonceurs. C’est ce cercle vertueux qui a permis à Google d’occuper une position dominante. Une fois cette place acquise, il devient difficile pour un concurrent d’émerger. -A noter toutefois que les recettes de Google proviennent avant tout de la vente de mots-clés associés à des profils. Ce sont ces mots-cles qui permettent de déterminer au mieux l’intention de l’internaute et de proposer un espace publicitaire pertinent. Le profilage de l’utilisateur est donc moins nécessaire pour Google que pour d’autres plateformes, telles que Facebook. Le profilage de l’utilisateur est donc moins nécessaire pour Google que pour d’autres plateformes, telles que Facebook. C’est également la raison pour laquelle Google peut envisager [certaines mesures en faveur de la protection de la vie privée](https://siecledigital.fr/2021/03/04/fin-des-cookies-tiers-google-abandonne-entierement-le-ciblage-individuel/). +A noter toutefois que les recettes de Google proviennent avant tout de la vente de mots-clés associés à des profils. Ce sont ces mots-cles qui permettent de déterminer au mieux l’intention de l’internaute et de proposer un espace publicitaire pertinent. Le profilage de l’utilisateur est donc moins nécessaire pour Google que pour d’autres plateformes, telles que Facebook. C’est également la raison pour laquelle Google peut envisager [certaines mesures en faveur de la protection de la vie privée](https://siecledigital.fr/2021/03/04/fin-des-cookies-tiers-google-abandonne-entierement-le-ciblage-individuel/). ```` e) Si Google représente plus de 90% des parts de marché dans le domaine des moteurs de recherche, des services concurrents existent. Proposer aux élèves, en petits groupes, de rechercher des alternatives à Google et déterminer quels sont leurs modèles économiques et leurs spécificités. diff --git a/src/ens/enjx1/index.md b/src/ens/enjx1/index.md index 6b080200..09c4d858 100644 --- a/src/ens/enjx1/index.md +++ b/src/ens/enjx1/index.md @@ -33,7 +33,8 @@ l’informatique tient à sa capacité à décomposer tout problème en élémen procédures que l’on peut composer, combiner, enchaîner. Il s’agit d’une éducation à « ouvrir les boîtes noires » des objets numériques qui nous entourent pour en comprendre les rouages, et à tester les différentes manières d’envisager une solution. -Environnement socio-technique + +### Environnement socio-technique Il s’agit de replacer l’objet abordé dans un contexte qui est spécifique, qu’il soit culturel, historique, géographique, économique, social ou personnel. @@ -87,4 +88,4 @@ Ces contenus étant en cours d'élaboration, nous apprécierions connaître l'av Si vous souhaitez participer à notre enquête, rendez-vous [ici](https://www.surveymonkey.com/r/s2postensejs). -Nous vous remercions par avance pour votre collaboration. \ No newline at end of file +Nous vous remercions par avance pour votre collaboration. diff --git a/src/ens/enjx2/activ/media/emissions_cartes.pdf b/src/ens/enjx2/activ/media/emissions_cartes.pdf index 1ecc96c1..616bd715 100755 Binary files a/src/ens/enjx2/activ/media/emissions_cartes.pdf and b/src/ens/enjx2/activ/media/emissions_cartes.pdf differ diff --git a/src/exts/exercise.py b/src/exts/exercise.py index f862a799..34410926 100644 --- a/src/exts/exercise.py +++ b/src/exts/exercise.py @@ -14,16 +14,18 @@ def run(self): admonition = nodes.admonition("", classes=["admonition", "note"]) + label = self.arguments[0] if len(self.arguments) > 0 else None + if self.env.docname not in self.nextNumberByDoc: Exercise.nextNumberByDoc[self.env.docname] = 1 - + number = Exercise.nextNumberByDoc[self.env.docname] - Solution.lastQuestion[self.env.docname] = number + Solution.lastQuestion[self.env.docname] = (number, label) Exercise.nextNumberByDoc[self.env.docname] += 1 title = "Exercice {}".format(number) - if len(self.arguments) > 0: - title += " – {}".format(self.arguments[0]) + if label is not None: + title += " – {}".format(label) textnodes, _ = self.state.inline_text(title, self.lineno) label = nodes.title(title, *textnodes) @@ -49,10 +51,13 @@ def run(self): admonition = nodes.admonition("", classes=["admonition", "hint"]) title = "Solution" - number = Solution.lastQuestion.get(self.env.docname, None) - if number is not None: + last_question = Solution.lastQuestion.get(self.env.docname, None) + if last_question is not None: del Solution.lastQuestion[self.env.docname] + number, label = last_question title += " {}".format(number) + if label is not None: + title += " – {}".format(label) textnodes, _ = self.state.inline_text(title, self.lineno) label = nodes.title(title, *textnodes)