Oui, on peut dire pleins de choses sur la non élégance de cet algo, mais c'est vraiment un truc comme ça que j'ai appris.
C'est le bon algo, avec néanmoins une comparaison inutile entre les deux nombres. Le principe est celui-ci :
prendre deux nombres a et b
calculer le reste r de la division de a par b
si r est nul, b est le pgcd recherché
sinon recommencer en 1 avec b et r
et c'est ce que fait ma boucle en un one liner. Il n'est pas nécessaire de chercher à savoir lequel des deux nombres est le plus grand. Si b est plus grand que a, le reste est a, et le point 4 remet tout dans le bon ordre au premier tour. Ensuite, le reste, qui servira de diviseur, sera toujours plus petit que le dividende.
De ce que je lis 40% des élèves n'y arrivaient pas.
J'ai eu beau cherché dans ce document, je ne vois pas d'où tu tires ce nombre. De mémoire, on était bien moins de 60% à y arriver. J'ai raconté cette anecdote pour montrer que le changement de base était accessible à certain élèves de primaires (les plus doués en maths d'entre eux) et qu'il devait donc être une formalité pour des étudiants dans le supérieur (ceux qui font des études d'info). Ceci étant, je me demande la part d'enfants qui appliquent sans comprendre et ceux qui comprennent réellement : la raison leur est enseignée (voir par exemple la chaîne lumni lancée pendant le confinement) mais combien la retienne et la comprenne réellement, je ne le sais.
Ceci étant, je maintiens que, comme pour le pgcg, l'alogrithme est hautement récursif et fonctionnel :
Ici les nombres sont représentés par une liste de chifres en mode "petit boutiste". Le code lui même reproduit parfaitement les différentes étapes d'apprentissage d'un enfant, et les sources d'erreurs potentielles où il faut prendre garde.
L'on apprend d'abord à ajouter des chiffres de petites tailles. Ma nièce en CP est à ce stade là, elle n'a pas encore à gérer le cas de la retenue dans la fonction ajouter_chiffre. Ensuite, lorsque la somme dépasse la dizaine, on leur enseigne que l'on crée un paquet de dix (ou dizaine) et que l'on garde le reste : deuxième branche du if then else de la fonction ajouter_chiffre. C'est là que se situe l'origine et la raison d'être de la retenue.
Ensuite, lorsque l'on pose l'addition, on a deux listes de chiffres puis l'on a va en construire une autre (sans modifier les deux en entrées) en appliquant itérativement (c'est-à-dire récursivement) l'addition de chiffre sur nos deux listes jusqu'à épuisement complet.
De plus, les différentes branches montre bien deux sources d'erreurs ou de confusion qui arrive au cours de l'apprentissage :
la première étant qu'un enfant peut ne pas savoir quoi faire lorsqu'il a épuisé une liste mais pas l'autre (deuxième branche du code)
la seconde étant qu'au début ils leur arrivent souvent d'oublier de redescendre la retenue s'il en reste une à la fin (le if then else de la dernière branche).
Enfin, la méthode est facilement généralisable pour un programmeur (ou un enfant dont le niveau d'abstraction est suffisamment développé). Ici la base est codée en dur dans l'addition de chiffres : il suffit d'en faire un paramètre. ;-)
(* le tilde ~ devant le paramètre est là pour avoir un paramètre nommé *)letajoute_chiffre~basec1c2=letres=c1+c2inifres<basethen(res,0)else(res-base,1)letadditionner~basel1l2=letrecloop(res,retenue)mn=matchm,nwith|c1::reste1,c2::reste2->letc,retenue=ajoute_chiffre~basec1(c2+retenue)inloop(c::res,retenue)reste1reste2|[],c::reste|c::reste,[]->letc,retenue=ajoute_chiffrec~base(0+retenue)inloop(c::res,retenue)[]reste|[],[]->List.rev(ifretenue=0thenreselseretenue::res)inloop([],0)l1l2(* exemples *)(* 31 + 35 = 66 en base 10 *)additionner~base:10[1;3][5;3];;-:intlist=[6;6](* la même en base 16 *)additionner~base:16[15;1][3;2];;-:intlist=[2;4](* puis en base 13 *)additionner~base:13[5;2][9;2];;-:intlist=[1;5]
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Pour alimenter la discussion ...
Posté par kantien . En réponse à la dépêche Python dépasse Java en popularité selon l’indice TIOBE de novembre. Évalué à 2.
C'est le bon algo, avec néanmoins une comparaison inutile entre les deux nombres. Le principe est celui-ci :
et c'est ce que fait ma boucle en un one liner. Il n'est pas nécessaire de chercher à savoir lequel des deux nombres est le plus grand. Si b est plus grand que a, le reste est a, et le point 4 remet tout dans le bon ordre au premier tour. Ensuite, le reste, qui servira de diviseur, sera toujours plus petit que le dividende.
J'ai eu beau cherché dans ce document, je ne vois pas d'où tu tires ce nombre. De mémoire, on était bien moins de 60% à y arriver. J'ai raconté cette anecdote pour montrer que le changement de base était accessible à certain élèves de primaires (les plus doués en maths d'entre eux) et qu'il devait donc être une formalité pour des étudiants dans le supérieur (ceux qui font des études d'info). Ceci étant, je me demande la part d'enfants qui appliquent sans comprendre et ceux qui comprennent réellement : la raison leur est enseignée (voir par exemple la chaîne lumni lancée pendant le confinement) mais combien la retienne et la comprenne réellement, je ne le sais.
Ceci étant, je maintiens que, comme pour le pgcg, l'alogrithme est hautement récursif et fonctionnel :
Ici les nombres sont représentés par une liste de chifres en mode "petit boutiste". Le code lui même reproduit parfaitement les différentes étapes d'apprentissage d'un enfant, et les sources d'erreurs potentielles où il faut prendre garde.
L'on apprend d'abord à ajouter des chiffres de petites tailles. Ma nièce en CP est à ce stade là, elle n'a pas encore à gérer le cas de la retenue dans la fonction
ajouter_chiffre. Ensuite, lorsque la somme dépasse la dizaine, on leur enseigne que l'on crée un paquet de dix (ou dizaine) et que l'on garde le reste : deuxième branche duif then elsede la fonctionajouter_chiffre. C'est là que se situe l'origine et la raison d'être de la retenue.Ensuite, lorsque l'on pose l'addition, on a deux listes de chiffres puis l'on a va en construire une autre (sans modifier les deux en entrées) en appliquant itérativement (c'est-à-dire récursivement) l'addition de chiffre sur nos deux listes jusqu'à épuisement complet.
De plus, les différentes branches montre bien deux sources d'erreurs ou de confusion qui arrive au cours de l'apprentissage :
if then elsede la dernière branche).Enfin, la méthode est facilement généralisable pour un programmeur (ou un enfant dont le niveau d'abstraction est suffisamment développé). Ici la base est codée en dur dans l'addition de chiffres : il suffit d'en faire un paramètre. ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.