Enoncé
Ecrire un programme qui lit deux entiers a et b et vérifie est ce que b est un diviseur de a.
Solution
Ma principale motivation pour cette article est une solution que je lis plusieurs fois durant les séances de TD Algorithmique pour les étudiants MI. Les étudiants en Mathématiques et Informatique sont généralement des matheux qui maîtrise les maths et qui projèctent chaque nouvelle notion acquise sur une notion mathématiques.
Dans le cas de vérification si un nombre divise un autre, le code que je lis souvent est le suivant :
Cette solution n'est même pas "compilable". En effet, la variable k n'a jamais été initialisée. Cela donne des avertissements (Warning) sous des compilateur et des erreur (Error) sous d'autres.
Mais cette solution n'est pas vraiement loin de la réalité. En effet, les étudiants, qui gardent encore un esprit matheux par excellence, reposent sur la définition suivante :
Soit a et b deux entiers.
On dit que b est un diviseur de a s'il existe un entier k tel que k.b = a.
L'erreur n'est pas dans la définition mais dans la traduction de la définition. L'erreur faite par les étudiants ici est plus simple de ce qu'elle parraît. En effet, ils ont montré deux confusions :
La suposition "il existe un entier k" nous oblige à le chercher, c'est à dire à parcourir les valeurs des nombres entiers, d'où la boucle.
Alors ce qu'il faut faire, c'est de choisir la bonne définition. C'est aussi simple que cela. La définition à prendre est la définition la plus élémentaires que nous enseignons aux enfants :
Soient a et b deux entiers.
On dit que b est un diviseur de a si le reste de division de a sur b est nul.
Comment choisir la bonne définition ? Il n'y a pas une méthode exacte; c'est par la pratique, la lecture des codes et l'expérience. Dans ce cas, il fallait lister des opérations possibles et penser à choisir la définition la plus proche d'une telle ou telle opération ou bien celle qui nécessite un code minimal.
Le code sera ainsi :
Dans les exemples suivants, vous allez voir que cette vérification n'est pas réalisée juste pour faire un affichage. Elle est utilisée pour aider les étudiants à comprendre et utiliser la notion d'une variable booléenne.
Ecrire un programme qui lit deux entiers a et b et vérifie est ce que b est un diviseur de a.
Solution
Ma principale motivation pour cette article est une solution que je lis plusieurs fois durant les séances de TD Algorithmique pour les étudiants MI. Les étudiants en Mathématiques et Informatique sont généralement des matheux qui maîtrise les maths et qui projèctent chaque nouvelle notion acquise sur une notion mathématiques.
Dans le cas de vérification si un nombre divise un autre, le code que je lis souvent est le suivant :
Program Diviseur; Var a, b, k : Integer; Begin ReadLn(a, b); If (k * b = a) Then WriteLn('b divise a') Else WriteLn('b ne divise pas a'); End.
Cette solution n'est même pas "compilable". En effet, la variable k n'a jamais été initialisée. Cela donne des avertissements (Warning) sous des compilateur et des erreur (Error) sous d'autres.
Mais cette solution n'est pas vraiement loin de la réalité. En effet, les étudiants, qui gardent encore un esprit matheux par excellence, reposent sur la définition suivante :
Soit a et b deux entiers.
On dit que b est un diviseur de a s'il existe un entier k tel que k.b = a.
L'erreur n'est pas dans la définition mais dans la traduction de la définition. L'erreur faite par les étudiants ici est plus simple de ce qu'elle parraît. En effet, ils ont montré deux confusions :
- La déclaration algorithmique est différente de la déclaration mathématique. Décalrer une variable en algorithmique ne veut pas dire qu'elle prendra une valeur sur le champs.
- L'ordinateur va chercher la bonne valeur pour eux.
Program VerifierDiviseur; Var a, b, k : Integer; diviseur : Boolean; Begin ReadLn(a, b); k := 2; diviseur := false; While (not(diviseur) And (k < a)) Do Begin If (k * b = a) Then diviseur := true Else k := k + 1; End; If (diviseur) Then WriteLn('b divise a') Else WriteLn('b ne divise pas a'); End.
La suposition "il existe un entier k" nous oblige à le chercher, c'est à dire à parcourir les valeurs des nombres entiers, d'où la boucle.
Alors ce qu'il faut faire, c'est de choisir la bonne définition. C'est aussi simple que cela. La définition à prendre est la définition la plus élémentaires que nous enseignons aux enfants :
Soient a et b deux entiers.
On dit que b est un diviseur de a si le reste de division de a sur b est nul.
Comment choisir la bonne définition ? Il n'y a pas une méthode exacte; c'est par la pratique, la lecture des codes et l'expérience. Dans ce cas, il fallait lister des opérations possibles et penser à choisir la définition la plus proche d'une telle ou telle opération ou bien celle qui nécessite un code minimal.
Le code sera ainsi :
Program VerifierDiviseur; Var a, b : Integer; Begin ReadLn(a, b); If (a mod b = 0) Then WriteLn('b divise a') Else WriteLn('b ne divise pas a'); End.
Dans les exemples suivants, vous allez voir que cette vérification n'est pas réalisée juste pour faire un affichage. Elle est utilisée pour aider les étudiants à comprendre et utiliser la notion d'une variable booléenne.