Algorithmique

Introduction :
- Initiation à l'algorithmique
- Petites instructions basiques

I) Les instructions conditionnelles Si / Sinon
II) Les boucles Tant que... Faire / Faire... Tant que
III) La boucle Pour
IV) Les tableaux
V) Le modulo
VI) La saisie sécurisée
VII) Les sous-fonctions

par Robin MICHAY

Initiation à l'algorithmique

De quoi est composé un algorithme ?

Test(x : entier ; y : entier ; tab : tableau ) : entier
Donnée modifiée (si tableau dans ARG) : tab, le tableau
Données (rentrées par l'utilisateur, si arguments) : x, y
Variables locales (les variables utilisées dans l'algorithme) : i, j
début

     |i <- 0

     |j <- 1
     |...
fin

Orange : nom de l'algorithme
Rouge : Données qui seront modifiées (le tableau se trouve dedans s'il est dans les arguments, sinon on le met dans VL)
Vert : Ce sont les données rentrées par l'utilisateur, les arguments en gros
Bleu : Ce sont les variables qui seront utilisées durant l'algorithme
Cyan : Marque le début et la fin de l'algorithme

-----------------------------------------------------

Arguments ou variables locales ?

Nombreux sont ceux qui ne savent pas différencier les arguments des variables locales.
Pour faire court, les arguments sont rentrés par l'utilisateur lorsqu'ils veulent utiliser la fonction.
On suppose la fonction pgcd(x ; y) un algorithme qui donne le plus grand diviseur commun de x et y. Si l'utilisateur tape pgcd(15 ; 35), l'algorithme affichera "5". 15 et 35 sont des arguments, non des variables locales.
En revanche les variables utilisées à l'intérieur de l'algorithme qui ne sont pas des arguments sont des variables.
/!\ Le tableau n'est dans donnée modifiée que s'il est dans les arguments, sinon on le place dans les VARIABLES LOCALES /!\

Instructions basiques

Afficher "x_=_" + x

L'instruction Afficher est simple, elle permet d'afficher ce qui suit. En rouge la chaîne de caractères, en bleu la valeur de la variable (ici x), en vert la transition entre chaîne de caractères et valeur.

x <- x+1

Cette instruction sert à affecter à une variable une valeur. En rouge la variable à laquelle on doit affecter la valeur, en bleu la valeur affectée.

I) Si / Sinon

L'instruction Si exprime une condition qui doit être respectée pour que la suite de l'algorithme opère. Elle peut-être considérée comme la vérification de cette condition (un booléen).

début
     |x <- alea( )
     |Si x pair alors afficher "x est pair"
fin

Exemple :

a) Si

Dans le cas où il y aurait plusieurs instructions à l'intérieur d'une même condition, il faudra respecter une certaine mise en forme.

Exemple :

début

     |x<-alea( )
     |Si x pair alors
          |x<-2
          |Afficher "X = 2"
     |fin Si
fin

b) Sinon

Sinon est la condition englobant le reste des conditions de Si.
Dans un langage plus français, on va dire que Sinon va désigner toutes les autres conditions qui ne sont pas comprises dans le Si, cela signifie qu'il ne peut pas y avoir de Sinon sans Si.

Exemple :

début
     |x <- alea( )
     |Si x pair alors afficher "x est pair"

     |Sinon alors afficher "x est impair"
fin

Dans le cas où il y aurait plusieurs instructions à l'intérieur d'une même condition, il faudra respecter une certaine mise en forme.

Exemple :

début

     |x<-alea( )
     |Si x pair alors
          |x<-2
          |Afficher "X = 2"
     |Sinon alors
          |Afficher "X est impair."
          |Afficher "X = " + x

     |Fin Si
fin

Exercices Si/Sinon

Ex 1 :
Un magasin de photos propose le développement au tarif de 0,16 € l’unité ; le tarif est de 0,12 € pour une
commande d’au moins 75 photos.
b) Ecrire un algorithme qui demande le nombre de photos à développer et qui affiche le prix à payer. 

 

II) Faire ttq et ttq faire

La boucle Tant que... Faire (que l'on va appelé TtqF) est une boucle qui va se répéter tant que la condition donnée par le Tant que n'est pas respectée. C'est-à-dire qu'on va attribuer à cette boucle une condition pour qu'elle s'arrête.

début
     |x <- 0
     |Tant que x < 10 Faire
          |x <- x + 1
     |fin tant que
     |Afficher "X = 10"
fin

a) Tant que... Faire

Exemple :

La boucle Faire... Tant que (qu'on appellera FTtq) est presque similaire à la boucle TtqF.
La différence est que FTtq que exécute la boucle une première fois avant de vérifier si la condition est respectée ou non.

b) Faire... Tant que

début
     |x <- 0
     |Tant que x < 0 Faire
          |x <- x + 1

     |Fin Tant que
     |Afficher "X = " + x
fin
Dans ce cas-là le logiciel affichera "X = 0"

 

Exemple TtqF :

Exemple FTtq :

début
     |x <- 0
     |Faire
          |x <- x + 1

     |Tant que x < 0
     |Afficher "X = " + x
fin

Ici, le logiciel affichera "X = 1", la boucle sera quand même effectuée une fois !
 

Différence entre TtqF et Fttq :

Exercices TtqF / FTtq

Exo1 :
Écrivez un algorithme qui affichera 12 fois le mot "Salut".

Exo2 :
Écrivez un algorithme qui affichera le mot "Salut" le nombre de fois que l'utilisateur l'a demandé.

Exo3 :
Écrivez un algorithme qui demande à l'utilisateur de saisir un nombre y. On part de x = 5. Si x est impair, on lui ajoute 3, et s'il est pair on lui retire 1, et ce jusqu'à ce que x soit supérieur ou égal au nombre saisi par l'utilisateur. A la fin, le nombre d'opérations nécessaires pour que x soit supérieur ou égal à y doit être affiché.

III) Pour

La boucle Pour a pour but de lancer un compteur i, et une fois ce compteur atteint, la boucle s'arrêtera. On peut choisir à quelle vitesse le compteur i augmente (de 2 en 2, de 3 en 3, etc.). Par défaut le compteur augmente de 1 en 1.

début
     |Pour i<-0 à 9 afficher i
fin

Résultat : 0123456789

Exemple :

Exemple :

début
     |Pour i<-0 à 9 par pas de 2 afficher i
fin

Résultat : 02468

Différence avec le TtqF :

La boucle Pour ne peut qu'augmenter par un nombre de pas déterminé. C'est-à-dire qu'elle va s'exécuter un nombre de fois fixe. Dans l'exemple précédent, la boucle Pour s'est exécuté 10 fois (de 0 à 9).

Exemple avec TtqF :

début

     |x<-0

     |Tant que x < 100 faire

          |Si x = 0 faire x<-5
          |Si x impair faire x<- x + 3
          |Sinon faire x<- x - 1
     |fin Tant que
fin

Dans ce cas là, le nombre x est réduit de 1 dans le cas où x est pair, ce qui serait impossible avec une boucle Pour.

IV) Les tableaux

Comment créer ce tableau ?

La création du tableau se fait dans les Données modifiées et/ou les Variables locales.
Ainsi, il suffit de préciser au début :
Donnée modifiée : tab, le tableau (si en arguments)
Variables locales : i, l'index des cellules, tab (sinon)

Et si je souhaite remplir ce tableau ?

Nous venons d'apprendre à utiliser la boucle Pour, nous allons l'appliquer dans la création du tableau.

-----------------------------------------------------

Variables locales : i, l'index des cellules, tab le tableau
Pour i <- 0 à 8 (cela va remplir les cellules 0 à 8, donc les 9)
     |tab[i] <- i (elles vont être remplies par i)
fin Pour

Note : tab[i] ==> ici, le i désigne le numéro de la cellule

Ce tableau sera ainsi créé :

Avec en rouge le numéro de la cellule du tableau (ce qu'il y a entre les crochets dans "tab[]") et en noir ce qui remplit le tableau.

/!\ Ce qui est en rouge n'est pas affiché, c'est juste pour apporter davantage de précisions /!\

Tableaux à 2 dimensions

Un tableau à deux dimensions s'écrit tab[i;j] avec i le numéro de la ligne et j le numéro de la colonne du tableau.

 

Comment créer un tableau à deux dimensions ?

V) Le modulo

Qu'est-ce que le modulo ? Le modulo est le reste de la division euclidienne d'un nombre par la valeur du modulo. Il est utilisé en algorithmique pour définir l'intervalle d'un nombre.

Exemple :

5 ≡ 2 (mod 3) --> on lit "5 est congru à 2 modulo 3"

"≡", étant un terme un peu trop mathématique sera remplacé par "=" par la suite.

Reprenons l'exemple ci-dessus :
5 = 2 (mod 3)

En effet, si on divise 5 par 3, cela donne 1 et il reste 2.

Autres exemples :
11 = 1 (mod 2)

30 = 0 (mod 30)

29 = 9 (mod 10)

C'est comme si on retirait au nombre la valeur du modulo jusqu'à ce qu'on ne puisse plus retirer cette valeur sans que ce nombre devienne négatif.

Ainsi, on remarque que cela donne un intervalle au nombre.

Autre exemple :
x <- (alea( ) mod 30) [alea une fonction qui donne aléatoirement un nombre compris entre 0 et 999]

Dans ce cas-là, x ne pourra pas dépasser 29 (30 = 0 (mod 30))

VI) La saisie sécurisée

La saisie sécurisée est une vérification de ce que saisit l'utilisateur. En quoi cela va nous être utile ? Supposons que nous demandons à l'utilisateur de rentrer un entier, et qu'il rentre une chaîne de caractère. Sans cette saisie sécurisée, le reste de l'algorithme risque d'avoir des "bugs".

 

Comment intégrer une saisie sécurisée ?

Saisie sécurisée avec Si

Nous pouvons vérifier la saisie rentrée par l'utilisateur à l'aide de l'instruction conditionnelle Si.

début

     |Afficher "saisissez un entier"
     |x <- saisir( )
     |Si x entier alors

          |...
          |...
     |Sinon alors afficher "Vous devez saisir un entier."

fin

Dans ce cas-là, la saisie est bien sécurisée, l'utilisateur doit bel et bien rentrer un entier pour que l'algorithme se poursuive. Le problème est que l'utilisateur devra le relancer à chaque fois que sa saisie est différente d'un nombre entier. Pour éviter ceci, nous pouvons l'intégrer à l'intérieur d'une boucle.

Exemple :

Intégrée dans une boucle FTtq

Intégrer une saisie sécurisée à l'intérieur d'une boucle FTtq permet de répéter à l'utilisateur de rentrer une saisie qui RESPECTE la condition demandée.
En français ? Imaginons que nous demandons à l'utilisateur de rentrer un nombre entier. La boucle va nous permettre de répéter cette demande automatiquement tant que l'utilisateur n'aura pas saisi un nombre entier.

Exemple :

début

     |err <- vrai
     |Faire

          |Afficher "Choisissez un nombre pair."

          |x <- saisir( )

          |Si x pair alors err <- faux

          |Sinon alors afficher "Erreur, choisissez un nombre pair."
     |Tant que err = vrai

fin

VII) Les sous-fonctions

Chaque algorithme correspond à une fonction.

On peut intégrer des fonctions à l'intérieur d'une seule fonction, que l'on va appeler des "sous-fonctions".

À quoi servent-elles ?

En développement par exemple, on peut mettre une fonction "header" et une autre "footer" que l'on aura juste à rappeler à chaque nouvelle page pour qu'elles apparaissent, cela permet un gain de temps et un gain de lignes de code.

Elles permettent également de simplifier un code en le séparant en "sous-parties"

Exemple d'exercices plus complexes

KnuthShuffle( )

aussi appelée la Navette de Knuth

Concevoir et réaliser un algorithme qui va créer un tableau d'une taille n (rentrée en argument par l'utilisateur), que l'on va respectivement remplir de 1 à n+1, puis que l'on va mélanger de façon ALÉATOIRE sans COLLISION de manière OPTIMISÉE.

BatailleNavale( )

Concevoir et réaliser un algorithme qui initialise un tableau vide, de 100 cellules, et qui demande au joueur 1 puis au joueur 2 de saisir la place de leur bateau, puis qui alterne le tour entre le joueur 1 et le joueur 2. Le joueur qui joue tire, on vérifie si la case touchée est la case choisie au départ par l'autre joueur. Si c'est le cas, arrêter l'algorithme et afficher le vainqueur.

Damier( )

Concevoir et réaliser un algorithme qui initialise un damier de taille n (n>=3), où la couleur alterne entre noir et blanc pour chaque case.

 

Exemple :

XOXOX

OXOXO

XOXOX

OXOXO

XOXOX

avec X = noir, O = blanc, et n = 5

Melange()

Concevoir et réaliser un algorithme qui mélange aléatoirement un tableau à deux dimensions (avec KnuthShuffle)

Exemple pour n = 5 :

X X X O O
O
X
O
O
X O
X

Cesar()

Concevoir et réaliser un algorithme qui chiffre une phrase avec le code Cesar (décalage de X lettres) et l'affiche.

Correction KnuthShuffle

KnuthShuffle(tab:1 tableau, n:entier)
Donnée modifiée : tab, le tableau à mélanger
Donnée : n, la taille du tableau
Variables locales : i, j les index des cellules à transposer à chaque étape
Début
     |Pour i<-0 à n faire tab[i]<-i+1
     |Pour i<-0 à n-1
          |j<-i+(alea( ) modulo (n-i) )
          |tab[i]<->tab[j]
     |Fin pour

     |Retourner tab
Fin

Correction Bataille Navale

BatailleNavale()

Variables locales : n, un entier désignant la longueur du tableau (ici 100),

                                 boat, un tableau à deux dimensions qui contient les coordonnées du bateau de chaque joueur,

                                 attack, un tableau contenant les coordonnées de l'attaque

                                 joueur, le numéro du joueur qui joue

                                 state, l'état du jeu (1 en cours, 2 terminé)

début

     |n<-100

     |Afficher "Joueur 1  : saisissez les coordonnées du bateau"

     |boat[0][0] <- Saisir()

     |boat[0][1] <- Saisir()

     |Afficher "Joueur 2 : saisissez les coordonnées du bateau"

     |boat[1][0] <- Saisir()

     |boat[1][1] <- Saisir()

     |state <- 1

     |joueur <- 1

     |Faire

          |Afficher "Joueur "+joueur+ " : où attaquez-vous ? (coordonnées)"

          |attack[0] <- saisir()

          |attack[1] <- saisir()

          |Si attack[0] = boat[1+(joueur modulo 2)][0] et attack[1] = boat[1+(joueur modulo 2)][1] alors state = 2

          |Sinon joueur = 1 + (joueur modulo 2)

     |Tant que state = 1

     |Afficher "Joueur "+joueur+" gagne !"

fin

Correction Damier

Damier()

Variables locales : tab, un tableau à deux dimensions de taille n (saisi par l'utilisateur)

                                 n, un entier désignant la taille du tableau

début

     |n<-Saisir()

     |Pour i<-0 et i<n, faire

          |Pour j<-0 et j<n, faire 

               |Si i+j est pair, tab[i][j] = X

               |Sinon tab[i][j] = O

          |Fin pour

     |Fin pour

fin

Correction Melange

Melange(tab)

Données modifiées : tab, un tableau à deux dimensions qui va être mélangé

Variables locales : n, un entier désignant la taille du tableau

                                 r, un tableau contenant les coordonnées de la cellule à transposer

                                 i et j les index du tableau

début

     |Pour i<-0 à n, faire

          |Pour j<-0 à n, faire

               |r[0] = i + (alea() modulo (n-i) )

               |Si i = r[0] alors r[1] = j + (alea() modulo (n-i) )

               |Sinon r[1] = alea() modulo n

               |tab[i][j] <-> tab[r[0]][r[1]]

          |Fin pour

     |Fin pour

     |Retourner tab

fin

Correction Cesar

Cesar(tablettres, phrase)

Données : tablettres, un tableau contenant l'alphabet à chaque index (avec tablettres[0] = "A" et tablettres[25] = "Z")

                   phrase, la phrase 

Variables locales : n, un entier désignant la taille du tableau

                                 r, un tableau contenant les coordonnées de la cellule à transposer

                                 i et j les index du tableau

début

     |Pour i<-0 à n, faire

          |Pour j<-0 à n, faire

               |r[0] = i + (alea() modulo (n-i) )

               |Si i = r[0] alors r[1] = j + (alea() modulo (n-i) )

               |Sinon r[1] = alea() modulo n

               |tab[i][j] <-> tab[r[0]][r[1]]

          |Fin pour

     |Fin pour

     |Retourner tab

fin

Algorithmique

By robinbrm

Algorithmique

  • 1,439