Solution de Listes de puissances - Sujet 06 - EP NSI 2025
Énoncé du problème
Exercice 1
EXERCICE 1 (10 points)
On rappelle que :
- le nombre a^n est le nombre a × a × a × ⋯ × a, où le facteur a apparaît n fois,
- en langage Python, l’instruction
t[-1]permet d’accéder au dernier élément du tableaut.
Dans cet exercice, l’opérateur ** et la fonction pow ne sont pas autorisés.
Programmer en langage Python une fonction liste_puissances qui prend en argument un nombre entier a, un entier strictement positif n et qui renvoie la liste de ses puissances
[a^1, a^2, …, a^n].
Programmer également une fonction liste_puissances_borne qui prend en argument un nombre entier a supérieur ou égal à 2 et un entier borne, et qui renvoie la liste de ses puissances, à l’exclusion de a^0, strictement inférieures à borne.
Exemples :
>>> liste_puissances(3, 5)
[3, 9, 27, 81, 243]
>>> liste_puissances(-2, 4)
[-2, 4, -8, 16]
>>> liste_puissances_borne(2, 16)
[2, 4, 8]
>>> liste_puissances_borne(2, 17)
[2, 4, 8, 16]
>>> liste_puissances_borne(5, 5)
[]
Exercice 2
EXERCICE 2 (10 points)
On affecte à chaque lettre de l’alphabet un code selon le tableau ci-dessous :
| A | B | C | D | E | F | G | H | I | J | K | L | M |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
Cette table de correspondance est stockée dans un dictionnaire dico où les clés sont les lettres de l’alphabet et les valeurs les codes correspondants.
dico = {"A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6,
"G": 7, "H": 8, "I": 9, "J": 10, "K": 11, "L": 12,
"M": 13, "N": 14, "O": 15, "P": 16, "Q": 17,
"R": 18, "S": 19, "T": 20, "U": 21, "V": 22,
"W": 23, "X": 24, "Y": 25, "Z": 26}
Pour un mot donné, on détermine d’une part son code alphabétique concaténé, obtenu par la juxtaposition des codes de chacun de ses caractères, et d’autre part, son code additionné, qui est la somme des codes de chacun de ses caractères.
Par ailleurs, on dit que ce mot est « parfait » si le code additionné divise le code concaténé.
Exemples :
- Pour le mot
"PAUL", le code concaténé est la chaîne'1612112', soit l’entier 1 612 112. Son code additionné est l’entier 50 car 16 + 1 + 21 + 12 = 50. 50 ne divise pas l’entier 1 612 112. Ainsi, le mot"PAUL"n’est pas parfait. - Pour le mot
"ALAIN", le code concaténé est la chaîne'1121914', soit l’entier 1 121 914. Le code additionné est l’entier 37 car 1 + 12 + 1 + 9 + 14 = 37. 37 divise l’entier 1 121 914. Ainsi, le mot"ALAIN"est parfait.
Compléter la fonction codes_parfait située à la page suivante et qui prend en paramètre un mot en majuscule et renvoie un triplet constitué du code additionné, du code concaténé et d’un booléen indiquant si le mot est parfait ou non.
On rappelle que pour tester si un entier b divise un entier a, on utilise l’opérateur modulo a % b qui renvoie le reste de la division euclidienne de a par b. Si a % b vaut 0, alors b divise a.
def codes_parfait(mot):
"""Renvoie un triplet
(code_additionne, code_concatene, mot_est_parfait) où :
- code_additionne est la somme des codes des lettres du mot ;
- code_concatene est le code des lettres du mot concaténées ;
- mot_est_parfait est un booléen indiquant si le mot est parfait."""
code_concatene = ""
code_additionne = ...
for c in mot:
code_concatene = code_concatene + ...
code_additionne = code_additionne + ...
code_concatene = int(code_concatene)
mot_est_parfait = ...
return code_additionne, code_concatene, mot_est_parfait
Exemples :
>>> codes_parfait("PAUL")
(50, 1612112, False)
>>> codes_parfait("ALAIN")
(37, 1121914, True)
Les contraintes ci-dessous sont ajoutées par la plateforme et ne font pas partie du sujet.
Exercice 1
Contraintes :
- Pour
liste_puissances(a, n):aest un entier,-10^3 <= a <= 10^3(apeut être négatif, nul ou positif) nest un entier strictement positif,1 <= n <= 20; la liste renvoyée contient donc exactementnéléments et n’est jamais vide- Pour
liste_puissances_borne(a, borne):aest un entier avec2 <= a <= 10^3,borneest un entier avec-10^9 <= borne <= 10^9 - La puissance a^0 = 1 est toujours exclue du résultat, même lorsque
borneest strictement supérieure à 1 - Lorsque
borne <= a, la liste renvoyée est vide
Exercice 2
Contraintes :
motest une chaîne de caractères non vide,1 <= len(mot) <= 30motest composé uniquement de lettres majuscules deAàZ(pas d’accent, pas d’espace, pas de chiffre, pas de ponctuation)- Chaque lettre est une clé du dictionnaire
dicofourni, de valeur comprise entre1et26 - La fonction renvoie un triplet
(code_additionne, code_concatene, mot_est_parfait)où les deux premiers éléments sont des entiers et le troisième un booléen
Solution
Solution - Sujet 06
Exercice 1 - listes de puissances
L’idée. L’énoncé interdit ** et pow : il faut donc fabriquer les puissances une par une. On part de 1 et, à chaque tour de boucle, on multiplie par a : on obtient ainsi a^1, puis a^2, puis a^3, et ainsi de suite. Il suffit de ranger chaque valeur obtenue dans une liste.
Un petit exemple. Pour a = 3 et n = 5 : 1 x 3 = 3, puis 3 x 3 = 9, puis 9 x 3 = 27, puis 81, puis 243. On s’arrête après 5 multiplications et la liste vaut [3, 9, 27, 81, 243].
def liste_puissances(a, n):
resultat = []
puissance = 1
# On part de 1 et on multiplie par a a chaque tour : a^1, puis a^2, etc.
for i in range(n):
puissance = puissance * a
resultat.append(puissance)
return resultat
puissance retient la puissance en cours de construction. Elle vaut 1 avant la boucle pour que le premier tour donne bien a^1 (et non a^2). La boucle tourne exactement n fois, donc la liste contient exactement n éléments. Le signe se gère tout seul : pour a = -2, les multiplications successives donnent -2, 4, -8, 16.
La deuxième fonction. Même mécanique, mais cette fois on ne sait pas à l’avance combien de valeurs on va produire : on utilise donc une boucle while au lieu d’une boucle for. On s’arrête dès que la puissance courante atteint ou dépasse borne.
def liste_puissances_borne(a, borne):
resultat = []
puissance = a
# a >= 2, donc chaque multiplication fait grandir la puissance : la boucle s'arrete
while puissance < borne:
resultat.append(puissance)
puissance = puissance * a
return resultat
On démarre à a et non à 1, parce que a^0 = 1 est exclu du résultat. Le test est < et non <= car on veut les puissances strictement inférieures à borne : c’est ce qui distingue liste_puissances_borne(2, 16), qui vaut [2, 4, 8], de liste_puissances_borne(2, 17), qui vaut [2, 4, 8, 16]. Et si borne est petite, la boucle ne s’exécute pas du tout : liste_puissances_borne(5, 5) renvoie [], puisque 5 n’est pas strictement inférieur à 5.
Exercice 2 - mots parfaits
L’idée. On parcourt les lettres du mot une par une. Pour chaque lettre c, dico[c] donne son code. On accumule deux choses en même temps pendant ce parcours : d’un côté une chaîne de caractères, où l’on colle les codes les uns derrière les autres, de l’autre un entier, où on les additionne. À la fin, on transforme la chaîne en entier et on teste si le code additionné divise le code concaténé.
Un petit exemple. Pour "PAUL", les codes sont 16, 1, 21, 12. Collés bout à bout : "16" + "1" + "21" + "12" donne la chaîne "1612112", soit l’entier 1612112. Additionnés : 16 + 1 + 21 + 12 = 50. Comme 1612112 % 50 ne vaut pas 0, le mot n’est pas parfait.
def codes_parfait(mot):
"""Renvoie un triplet
(code_additionne, code_concatene, mot_est_parfait) où :
- code_additionne est la somme des codes des lettres du mot ;
- code_concatene est le code des lettres du mot concaténées ;
- mot_est_parfait est un booléen indiquant si le mot est parfait."""
code_concatene = ""
code_additionne = 0
for c in mot:
code_concatene = code_concatene + str(dico[c])
code_additionne = code_additionne + dico[c]
code_concatene = int(code_concatene)
# Le mot est parfait quand le code additionne divise le code concatene
mot_est_parfait = code_concatene % code_additionne == 0
return code_additionne, code_concatene, mot_est_parfait
Le point délicat est la différence de nature entre les deux accumulateurs. code_concatene démarre à "", la chaîne vide, parce qu’on y colle du texte : il faut donc écrire str(dico[c]) pour transformer le code en caractères avant de le coller. code_additionne démarre à 0 parce qu’on y ajoute des nombres : on y met directement dico[c]. La ligne code_concatene = int(code_concatene) convertit ensuite la chaîne complète en entier, une seule fois, à la fin.
Enfin, code_concatene % code_additionne == 0 est déjà un booléen : pas besoin d’écrire un if qui renverrait True ou False.