Seconde I Présentation a) Définition Algorithmique : introduction Le mot "algorithme" vient du nom de l’auteur persan Al-Khuwarizmi (né vers 780 - mort vers 850) qui a écrit en langue arabe le plus ancien traite d’algèbre "abrégé de calcul par la complétion et la simplification" dans lequel il décrivait des procédés de calcul à suivre étape par étape pour résoudre des problèmes ramenés à des équations. Dans un premier temps rédiger un algorithme consiste à décrire les différentes étapes de calcul pour résoudre un problème algébrique, numérique ou décisionnel. Plus généralement le mot "algorithme" désigne tout procédé de calcul systématique voire automatique. S’ajoute à cela la notion de "finitude". On définit parfois les algorithmes de la manière suivante : "un algorithme est une suite finie de règles à appliquer dans un ordre déterminé à un nombre fini de données pour arriver, en un nombre fini d’étapes, à un certain résultat et cela indépendamment des données." Le résultat doit donc s’obtenir en un temps fini. A propos des "règles à appliquer", il faut entendre un traitement fait sur des données imposé par une suite "d’instructions" visant à transformer ces données pour arriver au résultat visé. Ces "instructions" sont de natures diverses selon le type de données au départ. C’est ce que nous allons préciser. b) Algorithme et langage de programmation Un algorithme est rédigé dans un pseudo-langage (en Français). Il peut ensuite être implémenté dans un langage de programmation donné. Pourquoi apprendre l’algorithmique pour apprendre à programmer ? En quoi a-t-on besoin d’un langage spécial, distinct des langages de programmation compréhensibles par les ordinateurs ? Parce que l’algorithmique exprime les instructions résolvant un problème donné indépendamment des particularités de tel ou tel langage. Pour prendre une image, si un programme était une dissertation, l’algorithmique serait le plan, une fois mis de côté la rédaction et l’orthographe. Or, vous savez qu’il vaut mieux faire d’abord le plan et rédiger ensuite que l’inverse… Apprendre l’algorithmique, c’est apprendre à manier la structure logique d’un programme informatique. 1 Seconde Algorithmique : introduction Il existe de nombreux langages de programmation sur calculatrice ou ordinateur. On peut en citer une liste non exhaustive : Ti basic (pour calculatrice), Langage C, C++, Visual Basic, COBOL, FORTRAN, Python, Java, JavaScript, etc. ….. Nous utiliserons dans nos travaux dirigés le langage TI basic des calculatrices et le logiciel AlgoBox. II Les éléments de base d’un algorithme simple a) Les trois étapes Trois étapes structurent un algorithme simple : La préparation du traitement Il s’agit de repérer les données nécessaires à la résolution. Ces données peuvent être numériques, ou sous forme de textes (on dit souvent chaines de caractères), ou de type logique (deux valeurs possibles, vrai ou faux), ou enfin de type graphique (des points). Souvent les données pertinentes doivent être agencées sous une forme plus vaste, comme par exemple des tableaux ou listes où on peut par exemple ranger commodément les valeurs prises par une fonction sur un grand nombre de points. Dans cette phase peut aussi figurer ce qu’on appelle l’entrée des données, qui peut se manifester par la saisie de caractères ou de nombres sur le clavier, ou la lecture de la position du pointeur de la souris, ou encore par la lecture d’un fichier contenant ces nombres ou caractères. Il s’agit aussi de repérer les résultats intermédiaires qu’il est bon de mémoriser pour la suite car indispensables au traitement. Il est parfois utile d’utiliser des variables auxiliaires pour ne pas perturber les données initiales. Le traitement Il s’agit de déterminer toutes les étapes des traitements à faire et donc des "instructions" à donner pour une exécution automatique. Si ces instructions s’exécutent en séquence, on parle d’algorithme séquentiel. Si les opérations s’exécutent sur plusieurs processeurs en parallèle, on parle d’algorithme parallèle. Si les taches s’exécutent sur un réseau de processeurs on parle d’algorithme réparti ou distribué. Nous ne traiterons ici que des algorithmes séquentiels. 2 Seconde Algorithmique : introduction La sortie des résultats Les résultats obtenus peuvent être affichés sur l’écran, ou imprimés sur papier, ou bien encore conservés dans un fichier. Si on n’en fait rien, ils "restent" en mémoire jusqu’à la prochaine exécution ou sont perdus. A l’occasion, la sortie pourrait être graphique (afficher ou déplacer le pointeur de la souris ou des objets sur l’écran) ou sonore … voire sur Internet. b) Les instructions Les "instructions" sont les "briques de base" des algorithmes, dont l’assemblage dans un ordre précis conduit au résultat attendu. Nous les présenterons dans un pseudo-langage " en français". Pour plus de facilité, nous suivrons pas à pas le développement de la formalisation concernant l’algorithme suivant : Un joueur lance deux dés et fait la somme des points obtenus. S’il obtient 8, il gagne 10€, sinon il perd 1€. Variante : le joueur rejoue 10 fois (et cumule ses gains et pertes). Autre variante : le joueur rejoue jusqu’à avoir un gain cumulé de 5€. Instructions pour traiter les données Pour réaliser ces trois étapes évoquées précédemment, on a besoin d’ "instructions de base " comme la lecture de données, l’affectation de variables et l’écriture de données. L’affectation de données dans des variables La formalisation de notre algorithme commence par le tirage d’un dé et la mémorisation des points obtenus. Cette action nécessite de créer une "mémoire" ou variable destinée à cet usage, zone de mémoire a laquelle il est commode de donner un nom ou identificateur. Les identificateurs sont des suites de lettres et chiffres (sans espaces) qui doivent être choisies judicieusement pour que l’algorithme soit immédiatement lisible et interprétable. Dans notre exemple nous pouvons choisir dé1 pour la variable qui contiendra le résultat du tirage du premier dé. Dans notre pseudo-langage en français, nous traduirons l’affectation par l’instruction : identificateur prend la valeur valeur. L’affectation remplace la valeur précédente de la variable par la nouvelle. Ainsi l’instruction "A prend la valeur 2" affecte la valeur 2 à la variable dont A est l’identificateur et ceci quelle que soit la valeur contenue au préalable dans la variable A. 3 Seconde Algorithmique : introduction La lecture (ou entrée) des données La "lecture de données" pourra se faire par interrogation de l’utilisateur ou par extraction a partir d’un fichier rangé sur un disque voire de données accessibles par Internet. On a choisi de la traduire par l’instruction : Saisir identificateur. Par exemple, dans XCAS l’instruction : input(A); va affecter dans la variable nommée A un nombre ou une expression tapée au clavier. L’écriture (ou sortie) des données L’écriture des données permet d’afficher pour l’utilisateur les valeurs des variables après traitement (ou en cours de traitement dans le cas ou l’on veut contrôler l’exécution). On a choisi de la traduire par l’instruction : Afficher identificateur. On pourra peaufiner la présentation des résultats pour avoir un affichage lisible et compréhensible. Une variante consiste à "sortir" directement des informations non contenues dans une variable, nous le traduirons par : Afficher " message". Les séquences d’instructions Le "traitement des données" se fait par une suite d’instructions parmi lesquelles figurent des affectations d’opérations ou de calculs. Ces opérations ou ces calculs sont spécifiques selon le type des données utilisées (nombres entiers, nombres décimaux, ou chaines de caractères) ou selon les structures données utilisées (listes, tableaux, etc.). Les instructions, simples ou complexes, sont en principe traitées les unes après les autres dans leur ordre d’apparition dans le programme. Dans la plupart des langages de programmation, les instructions d’une même séquence sont séparées par un caractère deux-points ou point-virgule ou simplement par un passage a la ligne. Par exemple, dans notre exemple la séquence correspondant aux tirages des deux dés et au calcul de la somme des deux dés se réalise par les 3 instructions d'affectation suivantes : dé1 prend la valeur nombre_aléatoire(1,6) dé2 prend la valeur nombre_aléatoire(1,6) Somme prend la valeur (dé1 + dé2) 4 Seconde Algorithmique : introduction Instructions (ou structures) de contrôle Le traitement de données se fait parfois sous conditions ou de manière spécifique. On parle alors de "structures de contrôle". Elles sont de plusieurs natures différentes : La « structure alternative » Selon qu’une certaine condition est vérifiée ou non, on fera un certain traitement ou un autre (par "traitement" on entend, comme explique ci-dessus, une ou plusieurs instructions en séquence). Pour revenir à notre joueur, l’alternative la plus simple est d’afficher un message favorable si la somme des deux dés (soit la variable somme) vaut 8 et défavorable sinon : On a choisi de traduire la structure alternative par l’instruction : Si condition alors │ Traitement 1 Sinon └ Traitement 2 Fin Si On peut d’ailleurs imaginer que, selon le cas, il se peut que, si la condition n’est pas vérifiée, il n’y ait pas de Traitement 2 à effectuer alors la série d’instruction du Traitement 2 est vide. On écrira alors l’instruction : Si condition alors Traitement 1 Fin Si Pour ce qui concerne la "condition", c’est une expression logique prenant l’une des deux valeurs VRAI ou FAUX, qui peut être simple ou complexe. Par exemple une "condition simple" peut correspondre a un test d’égalité "A est égal à B" noté A=B, ou un test d’inégalité "A est strictement inférieur a B" noté A<B, "A est strictement supérieur à B" noté A>B, "A est supérieur ou égal à B noté A>=B, "A est inférieur ou égal à B" noté A<=B. Une "condition complexe" est une combinaison logique de conditions simples. Par exemple le test "A est égal à B" et "B est égal à C", se note (A=B) ET (B=C) et le test "A est strictement inférieur à B " ou "B est strictement supérieur à C" se note (A<B) OU (B>C). 5 Seconde Algorithmique : introduction On peut aussi imaginer des structures alternatives "imbriquées" telles que : Si condition alors │ Si condition alors │ │ Traitement 1 │ Sinon │ └ Traitement 2 Fin Si Sinon └ Traitement 3 Fin Si Pour la lisibilité on utilise l’indentation qui consiste à écrire les instructions sur des lignes différentes en décalant les mots. Dans notre exemple, le test pour déterminer si le joueur a gagné se traduit par : Si somme = 8 alors Afficher "Gagné" Sinon Afficher "Perdu" Fin Si Les structures répétitives Elles permettent d’exécuter plusieurs fois de suite le même traitement c’est à dire la même série d’instructions. La plus simple à comprendre est la "structure itérative" qui consiste à répéter un certain traitement un nombre N de fois fixé à l’avance. Dans la plupart des langages (y compris ceux des calculatrices) on utilise pour cela un compteur I (c’est une variable) pour contrôler le nombre (entier) de tours. A chaque "tour" le compteur I augmente automatiquement de 1. Nous formulerons cela dans notre pseudo-langage par l’instruction : Pour I de 1 jusqu’a N faire │Traitement 1 I suivant 6 Seconde Algorithmique : introduction Exercice 1: Ecrire un algorithme qui demande un nombre de départ, et qui calcule la somme des entiers jusqu’à ce nombre. Par exemple, si l’on entre 5, le programme doit calculer : 1 + 2 + 3 + 4 + 5 = 15 NB : on souhaite afficher uniquement le résultat, pas la décomposition du calcul. Une autre structure répétitive est celle qui consiste à répéter un certain traitement tant qu’une certaine condition reste valide. (On ne souhaite évidemment pas que la répétition se fasse une infinité de fois). Nous formulerons cette structure ainsi : Tant que condition faire │Traitement 1 Fin Tant que Le nombre de répétitions dépendra de la condition. Si la condition n’est pas vérifiée au début alors le Traitement 1 ne sera pas exécuté du tout. Si la condition est vérifiée au début et si la condition n’est pas susceptible d’être modifiée lors du Traitement 1, alors le Traitement 1 sera exécute indéfiniment et l’utilisateur sera obligé d’arrêter (brutalement) le programme. On dit que le programme "boucle indéfiniment", ce qui est une erreur majeure de programmation. Pour que l’algorithme soit correct, il est nécessaire que la condition cesse d’être vérifiée au bout d’un nombre fini de répétitions. Un raisonnement mathématique permet parfois de s’en assurer, mais il est parfois difficile d’avoir l’assurance du fait que le programme ne bouclera jamais indéfiniment. Exercice 2 : Ecrire un algorithme qui demande un nombre compris entre 10 et 20, jusqu’à ce que la réponse convienne. En cas de réponse supérieure à 20, on fera apparaître un message : « Plus petit ! », et inversement, « Plus grand ! » si le nombre est inférieur à 10. Une dernière variante de la structure répétitive consiste à répéter un traitement jusqu’a ce qu’une certaine condition soit vérifiée. C’est ce qui se produit lorsque notre joueur recommence à jouer en espérant atteindre un gain de 5€. On la traduit par l’instruction : Répète │Traitement 1 └ Jusqu’à condition 7 Seconde Algorithmique : introduction On remarquera que dans ce type d’instruction, le test étant fait a la fin de la boucle, cela implique que le traitement est exécuté au moins une fois même si la condition est vérifiée au début. Exercice 3 Ecrire l'algorithme complet du jeu proposé pour le lancer de deux dés : Un joueur lance deux dés et fait la somme des points obtenus. S’il obtient 8, il gagne 10€, sinon il perd 1€. Exercice 4 : Variante 1 : le joueur rejoue 10 fois (et cumule ses gains et pertes). Ecrire l'algorithme complet du la variante 1 du jeu proposé pour le lancer de deux dés. Exercice 5 : Variante 2 : le joueur rejoue jusqu’à avoir un gain cumulé de 5€. Exercice 6 : Jeu du nombre à deviner Ecrire un algorithme correspondant au jeu suivant : • • • • L'ordinateur (ou la calculatrice) choisit un nombre aléatoire entre 0 et 100. Le joueur propose un nombre et l'ordinateur répond "trop grand" "trop petit" ou "gagné" selon le résultat de la comparaison du nombre proposé et du nombre secret. On continue jusqu'à ce que le joueur trouve le nombre secret On affiche le nombre de propositions faites par le joueur. Exercice 7 : Jeu du nombre à deviner : variante Modifier l'algorithme précédent en limitant à 6 le nombre de propositions. III Implémentation dans un langage de programmation 1) Implémenter l'algorithme du jeu du nombre à deviner : a) Sur une calculatrice en langage TI-basic b) Sur ordinateur avec Excel VBA c) Sur ordinateur avec le logiciel Xcas 2) Comment choisir les différents nombres afin d'optimiser le nombre total de propositions ? 8 Seconde 1) a) Algorithmique : introduction Sur une calculatrice en langage TI-basic Le programme suivant est utilisable sur calculatrice TI 80 à 84 plus. Pour accéder au menu programme il suffit d'appuyer sur la touche PRGM. On choisit "NEW" et on saisit le nom du programme, par exemple DEVIN. On saisit les différentes instructions du programme traduction de l'algorithme précédemment écrit. Après chaque ligne écrite, on passe à la ligne suivante avec la touche "ENTER". Pour chaque ligne est indiquée en commentaire la séquence de touche à utiliser pour saisir la bonne commande. Listing du programme : :0 R :randInt(1,100) N :1 T :While T=1 :Input "CHOIX",C :R+1 R :If C < N :Then :Disp "TROP PETIT" :End :If C > N :Then :Disp "TROP GRAND" :End :If C = N :Then :Disp "GAGNE EN ",R, "COUPS" 0 T :End :End ' s'obtient avec STO 'randInt s'obtient avec MATH PRB 5 'While s'obtient avec PRGM CTL 5 'Input s'obtient avec PRGM I/O 1 'If s'obtient avec PRGM CTL 1 'Then s'obtient avec PRGM CTL 2 'Disp s'obtient avec PRGM I/O 3 'End s'obtient avec PRGM CTL 7 'If s'obtient avec PRGM CTL 1 'Then s'obtient avec PRGM CTL 2 'Disp s'obtient avec PRGM I/O 3 'End s'obtient avec PRGM CTL 7 'If s'obtient avec PRGM CTL 1 'Then s'obtient avec PRGM CTL 2 'Disp s'obtient avec PRGM I/O 3 'End s'obtient avec PRGM CTL 7 'End s'obtient avec PRGM CTL 7 On exécute le programme avec PRGM EXEC + choix du programme. 9 Seconde Algorithmique : introduction b) Sur ordinateur avec Excel VBA On lance le tableur Excel puis on accède à l'environnement Visual Basic avec les touches ALT F11. On insère un module : menu "Insertion module" On insère une procédure : menu "Insertion procédure" On saisit le nom de la procédure par exemple : devin. Le type de la procédure est Sub et la portée Public. On obtient dans l'éditeur intégré : Public Sub devin() End Sub On écrit ensuite les lignes d'instructions du programme à l'intérieur de la procédure. 10 Seconde Algorithmique : introduction Listing du programme : Public Sub devin() Dim secret, proposition, nb_coups As Integer Dim trouve As Boolean nb_coups = 0 trouve = False Randomize secret = Int(100 * Rnd + 1) While Not (trouve) proposition = InputBox("Saisir la proposition (un nombre entier compris entre 1 et 100") proposition = CInt(proposition) nb_coups = nb_coups + 1 If proposition = secret Then MsgBox ("Bravo ! trouvé en " + CStr(nb_coups) + " coups") trouve = True Else If proposition < secret Then MsgBox ("trop petit") Else MsgBox ("trop grand") End If End If Wend End Sub Remarques : La fonction Rnd renvoie un nombre aléatoire compris entre 0 et 1. La fonction Int renvoie la partie entière d'un nombre. Donc l'instruction Int(100*Rnd + 1) renvoie un nombre aléatoire entre 1 et 100. L'instruction InputBox() permet de demander la saisie au clavier d'une variable et renvoie une variable de type chaîne de caractère. La fonction Cint() permet de convertir la chaîne de caractère saisie en nombre entier. L'instruction Msgbox() permet l'affichage d'un texte dans une fenêtre popup. 11 Seconde Algorithmique : introduction La fonction Cstr() permet de convertir la variable nb_coups de type entier en une chaîne de caractères. c) Sur ordinateur avec Xcas On peut saisir "ALT p" pour afficher une fenêtre pour les programmes. On a la possibilité de saisir les structures de contrôles ou itératives en français" ou bien en anglais. Ici le programme proposé est rédigé avec les structures en français. Listing du programme : devin():= { local nb_coups,trouve,secret; nb_coups := 0; trouve := false; secret := floor(rand(1,100)); print(secret); tantque (non(trouve)) faire input(proposition); nb_coups := nb_coups + 1; si (proposition==secret) alors print("Bravo ! nombre trouvé en " + nb_coups + " coup(s)."); trouve := true; sinon si (proposition < secret) alors print("Trop petit"); sinon print("Trop grand"); fsi fsi ftantque }:; 12 Seconde Algorithmique : introduction CORRECTION Exercice 1: Ecrire un algorithme qui demande un nombre de départ, et qui calcule la somme des entiers jusqu’à ce nombre. Par exemple, si l’on entre 5, le programme doit calculer : 1 + 2 + 3 + 4 + 5 = 15 NB : on souhaite afficher uniquement le résultat, pas la décomposition du calcul. Variables N, i, Som en Entier Debut Ecrire "Entrez un nombre : " Lire N Som ← 0 Pour i ← 1 à N Som ← Som + i i Suivant Ecrire "La somme est : ", Som Fin Exercice 2 : Ecrire un algorithme qui demande un nombre compris entre 10 et 20, jusqu’à ce que la réponse convienne. En cas de réponse supérieure à 20, on fera apparaître un message : « Plus petit ! », et inversement, « Plus grand ! » si le nombre est inférieur à 10. Variable N en Entier Debut N←0 Ecrire "Entrez un nombre entre 10 et 20" TantQue N < 10 ou N > 20 Lire N Si N < 10 Alors Ecrire "Plus grand !" Sinon Si N > 20 Alors Ecrire "Plus petit !" FinSi FinSi FinTantQue Fin 13 Seconde Algorithmique : introduction CORRECTION Exercice 3 Début Variables dé1, dé2,somme : entiers Traitement dé1 prend la valeur nombre_aléatoire(1,6) dé2 prend la valeur nombre_aléatoire(1,6) somme prend la valeur (dé1 + dé2) Si somme = 8 alors Afficher "gagné 10 €" Sinon Afficher "perdu 1 €" Fin Si Fin Exercice 4 Variante 1 : le joueur rejoue 10 fois (et cumule ses gains et pertes). Début Variables i,dé1, dé2,somme,gains : entiers Traitement gains prend la valeur 0 Pour i = 1 à 10 dé1 prend la valeur nombre_aléatoire(1,6) dé2 prend la valeur nombre_aléatoire(1,6) somme prend la valeur (dé1 + dé2) Si somme = 8 alors gains prend la valeur (gains + 10) Sinon Gains prend la valeur (gains – 1) Fin Si i Suivant Si gains > 0 alors Afficher "Gain de : " gains " €" Sinon Afficher "Perte de : " –gains " €" Fin Si Fin 14 Seconde Algorithmique : introduction CORRECTION Exercice 5 Variante 2 : le joueur rejoue jusqu’à avoir un gain cumulé de 5€ . Début Variables i,dé1, dé2,somme,gains,nb_parties : entiers Traitement gains prend la valeur 0 nb_parties prend la valeur 0 Tant que (gains < 5) nb_parties prend la valeur (nb_parties + 1) dé1 prend la valeur nombre_aléatoire(1,6) dé2 prend la valeur nombre_aléatoire(1,6) somme prend la valeur (dé1 + dé2) Si somme = 8 alors gains prend la valeur (gains + 10) Sinon Gains prend la valeur (gains – 1) Fin Si Fin Tant que Afficher nb_parties " jouées" Fin Exercice 6 : Jeu du nombre à deviner Début Variables secret, proposition, nb_parties : entiers trouvé : booléen Traitement nb_parties prend la valeur 0 trouvé prend la valeur faux secret prend la valeur nombre_aléatoire(1,100) Tant que (trouvé = faux) Lire proposition nb_parties prend la valeur (nb_parties + 1) Si secret = proposition alors Afficher "Gagné en " nb_parties " coups" Trouvé prend la valeur vrai Sinon Si proposition < secret alors Afficher "trop petit" Sinon Afficher "trop grand" Fin si Fin si Fin Tant que Fin 15 Seconde Algorithmique : introduction CORRECTION Exercice 7 : Jeu du nombre à deviner : variante Début Variables secret, proposition, nb_parties : entiers trouvé : booléen Traitement nb_parties prend la valeur 0 trouvé prend la valeur faux secret prend la valeur nombre_aléatoire(1,100) Tant que (trouvé = faux et nb_parties < 5) Lire proposition nb_parties prend la valeur (nb_parties + 1) Si secret = proposition alors Afficher "Gagné en " nb_parties " coups" Trouvé prend la valeur vrai Sinon Si nb_parties = 6 alors Afficher "perdu" Sinon Si proposition < secret alors Afficher "trop petit" Sinon Afficher "trop grand" Fin si Fin si Fin si Fin Tant que Fin III Implémentation dans un langage de programmation 2) Pour optimiser le nombre de propositions, on propose la moyenne des extrémités de chaque intervalle. Exemple : si le nombre à deviner est 82 On propose d'abord la moyenne de 1 et 100 soit environ 50. Puis on propose la moyenne de 75 et 100 soit environ 88. Puis on propose la moyenne de 75 et 88 soit environ 82. On a trouvé le résultat en 3 étapes. Cette méthode se nomme recherche par dichotomie. 16 Seconde Algorithmique : introduction CORRECTION Nous l'étudierons encore sur le chapitre "FONCTIONS"; notamment pour recherche le (s) zéro(s) d'une fonction. 17