L2AnalyseStructuree-enonce-cpp

publicité
Autour de Kaprekar [th07] - Exercice
Karine Zampieri, Stéphane Rivière
Unisciel
algoprog
Version 8 janvier 2017
Table des matières
1 Algorithme de Kaprekar (18 points)
1.1 Énoncé . . . . . . . . . . . . . . . . .
1.2 Cas de trois chiffres (4 points) . . .
1.3 Le suivant de Kaprekar (8 points) .
1.4 Cas général (6 points) . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2 Nombre de Kaprekar (7 points)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
2
3
5
6
C++ - Autour de Kaprekar (Examen)
Objectif
Cet exercice décrit et réalise l’algorithme de Kaprekar et détermine les nombres de
Kaprekar.
Consignes :
• Mots-clés : Analyse Structurée.
• Durée : 2 heures
• Documents : Aucun
• Langage : C++ et pseudo-code
• Barème : 25 points
Paramètres
Il est impératif de réaliser des passages par référence constant pour des tableaux et/ou
structures qui ne doivent pas être modifiés. L’absence du qualificatif const induira une
pénalité.
Doxygen (dans le barême)
Les procédures et fonctions doivent être documentés.
1
Unisciel algoprog – Autour de Kaprekar [th07]
1
1.1
2
Algorithme de Kaprekar (18 points)
Énoncé
Algorithme de Kaprekar
Un des algorithmes (qui date des années 1949) du mathématicien Kaprekar est le
suivant :
1. Prendre un entier positif.
2. Ordonner ses chiffres par ordre décroissant et par ordre croissant.
3. Soustraire les deux entiers ainsi formés.
4. Poursuivre ce processus jusqu’à ce que l’une des possibilités suivantes soit atteinte :
• 0 (cas dégénéré).
• Un entier constant.
• Un cycle.
Exemple
Voici deux itérations du processus :
2213 -> 3221-1223=1998 -> 9981-1899=8082 -> etc
Objectif
Programmer cet algorithme pour un entier à trois chiffres et dans le cas général pour
des entiers d’au plus 9 chiffres.
1.2
Cas de trois chiffres (4 points)
Analyse
Pour un entier à trois chiffres, l’algorithme fournit un entier constant dans les cas non
dégénérés. Ainsi donc, le processus se poursuit tant que l’entier courant est différent de
son prédécesseur.
Pour déterminer le successeur d’un entier n, il s’agit de le décomposer en ses trois chiffres
a, b, c, de les ordonner en sens décroissant (par exemple) et d’en déduire les entiers n2
(le plus grand) et n1 (le plus petit) puis d’en faire la différence.
Exemple
n =
==>
==>
==>
==>
==>
198
a=8, b=9, c=1
decroitre3i(a,b,c)
a=9, b=8, c=1
n2 = 9*100+8*10+1 = 981 et n1 = 1*100+8*10+9 = 189
n2-n1 = 981-189 = 792
Unisciel algoprog – Autour de Kaprekar [th07]
3
(0.5 point) Écrivez une procédure permuter2i(a,b) qui échange les contenus de deux
entiers a et b.
(0.5 point) Écrivez une procédure decroitre2i(a,b) qui classe deux entiers a et b
par ordre décroissant, c.-à-d. qu’à l’issue de la procédure, a doit contenir le plus grand
entier et b le plus petit de (a,b).
(0.5 point) Déduisez une procédure decroitre3i(a,b,c) qui classe trois entiers a, b
et c par ordre décroissant, en appelant trois fois la procédure decroitre2i :
• Classez a et b en ordre décroissant.
• Puis classez b et c en ordre décroissant.
• Puis classez a et b en ordre décroissant.
(1 point) Déduisez une fonction kaprekarSucc3i(n) qui calcule et renvoie le suivant
d’un entier n (de trois chiffres) selon l’algorithme de Kaprekar (Voir ci-avant l’analyse).
Exemples :
kaprekarSucc3i(198) ==> 981-189=792
kaprekarSucc3i(792) ==> 972-279=693
(0.5 point) Écrivez une fonction saisieEntier(binf,bsup) qui renvoie un entier saisi
par l’utilisateur appartenant à l’intervalle d’entiers [binf..bsup]. Il faudra itérer la
saisie jusqu’à ce que l’entier soit dans l’intervalle.
(1 point) Enfin écrivez une procédure test_kaprekar3i qui saisit un entier à trois
chiffres (donc compris entre 100 et 999) puis affiche la suite des nombres générés selon
l’algorithme de Kaprekar. Exemple d’exécution :
Entier dans [100..999]? 293
293
--> 693
--> 594
--> 495
--> 495
1.3
Le suivant de Kaprekar (8 points)
Analyse
Dans le cas général, la première opération consiste à représenter les chiffres d’un entier
par un tableau d’entiers. Ainsi donc, pour calculer le suivant de Kaprekar, il convient
de :
1. Décomposer l’entier n en la séquence de ses chiffres.
2. Trier cette séquence de chiffres (par exemple par ordre croissant).
Unisciel algoprog – Autour de Kaprekar [th07]
4
3. Évaluer la séquence de chiffres, d’où l’entier n2 (le plus grand).
4. Renverser la séquence de chiffres.
5. Évaluer la séquence de chiffres, d’où l’entier n1 (le plus petit).
6. Retourner l’entier n2 − n1 .
Exemple
n =
==>
==>
==>
==>
==>
==>
==>
==>
1235648
cs=[8,4,6,5,3,2,1], nc=7
trierChiffres(cs)
cs=[1,2,3,4,5,6,8], nc=7
n2 = 8654321
renverserChiffres(cs)
cs=[8,6,5,4,3,2,1], nc=7
n1 = 1234568
n2-n1 = 8654321-1234568 = 7419753
(0.5 point) Définissez la constante TMAX=10 puis le type Chiffres comme étant :
• Soit, une structure contenant un tableau de TMAX entiers et un entier nc représentant le nombre de chiffres effectif dans le tableau.
• Soit, un vecteur dynamique d’entiers (type vector<int>).
(0.5 point) Écrivez une procédure ajouterChiffre(cs,val) qui ajoute un chiffre de
valeur val à la fin d’un Chiffres cs. Exemple :
Soient: cs=[8,1,2,2], nc=4
Après: ajouterChiffre(cs,6)
Alors: cs=[8,1,2,2,6], nc=5
(1 point) Déduisez une procédure decomposer(n,cs) qui décompose un entier positif n
en ses chiffres (base 10) dans un Chiffres cs. Exemple : Pour 62218, la procédure doit
initialiser cs avec [8,1,2,2,6] et l’entier nc avec 5.
(1 point) Dualement, écrivez une fonction evalChiffres(cs) qui calcule et renvoie la
valeur de l’entier représenté par un Chiffres cs. Exemple :
Soient: cs=[8,0,2,2,6], nc=5
evalChiffres(cs) ==> 62208
(0.5 point) Écrivez une procédure afficherChiffres(cs) qui affiche un Chiffres cs
en affichant chacun de ses chiffres.
Unisciel algoprog – Autour de Kaprekar [th07]
5
(2 points) Écrivez une procédure trierChiffres(cs) qui classe par ordre croissant les
éléments d’un Chiffres cs. Étant donné que le nombre d’éléments à trier n’est pas
grand, optez pour une méthode de tri naı̈ve (à savoir en O(n2 )), au choix : sélection du
maximum ou par insertion avec butoir.
(0.5 point) Écrivez une procédure renverserChiffres(cs) qui renverse les éléments
d’un Chiffres cs. Exemple :
Soient: cs=[8,1,2,2,6], nc=5
Après: renverserChiffres(cs)
Alors: cs=[6,2,2,1,8], nc=5
(1 point) Déduisez une fonction kaprekarSucc(n) qui calcule et renvoie le suivant d’un
entier n selon l’algorithme de Kaprekar (cf. Analyse ci-avant).
(1 point) Écrivez une procédure test_kaprekarSucc qui demande un entier puis affiche
la suite des nombres générés selon l’algorithme de Kaprekar jusqu’à ce que l’utilisateur
tape 0 pour spécifier qu’il veut finir. Exemple :
Entier dans
1235648
--> 7419753
--> 8429652
--> 7619733
1.4
[1..999999999]? 1235648
(On continue 0==fin)? 1
(On continue 0==fin)? 1
(On continue 0==fin)? 0
Cas général (6 points)
(1 point) Sachant que la longueur du cycle est d’au plus une vingtaine d’entiers pour
une taille de dix chiffres, que faut-il faire pour traiter le cas général ?
Écrivez votre réponse comme suit dans votre programme :
/*
...ici votre réponse...
*/
(DOXYGEN, 5 points) Complétez votre programme selon votre analyse.
Exemple d’exécution :
Entier dans [1..999999999]? 1235648
1235648
--> 7419753
--> 8429652
--> 7619733
--> 8439552
--> 7509843
--> 9529641
Unisciel algoprog – Autour de Kaprekar [th07]
-->
-->
-->
-->
6
8719722
8649432
7519743
8429652
Dans cet exemple, l’entier 8429652 apparait dans la liste en tant que 5-ème élément.
2
Nombre de Kaprekar (7 points)
Nombre de Kaprekar
Un nombre de Kaprekar est un nombre qui, lorsqu’il est élevé au carré, peut être séparé
en deux parties de tailles quasi-égales telles que la somme donne le nombre initial.
Exemples
703 est un nombre de Kaprekar car 7032 = 494 209 et que 494 + 209 = 703.
De même 297 car 2972 = 88 209 et 88 + 209 = 297.
(3 points) Écrivez (en français) l’analyse du test.
(DOXYGEN, 4 points) Complétez votre programme afin de réaliser le test (nombre
de Kaprekar) et rechercher par force brute tous les nombres de Kaprekar compris
entre 1 et 9999.
Téléchargement