Info – Exercices 3 Tableaux et chaînes de caractères

Transcription

Info – Exercices 3 Tableaux et chaînes de caractères
Info – Exercices 3
Tableaux et chaînes de caractères
Tableaux et chaînes de caractères sous Python. Premiers émois algorithmiques.
3
Tableaux et chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
Indications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
2
6
7
PCSI2 \ 2014-2015
Laurent Kaczmarek
Les difficultés sont échelonnées de la manière suivante : aucune, ♪ , ♪♪ , ♪♪♪ et ♪♪♪♪. Certains énoncés
sont tirés des annales des concours (oral et écrit) ; leur provenance est le plus souvent précisée. Les
exercices notés ♪♪♪ et ♪♪♪♪ sont particulièrement délicats.
1. Tableaux
1 . [ Échange de deux éléments dans une liste ] ( ind )
Écrire une fonction echangeListe(t,i,j) réalisant l’échange de deux valeurs dans un tableau t. Cette
fonction recevra comme arguments un tableau et deux indices (distincts) correspondant à des positions
réelles dans ce tableau, et effectuera l’échange sans rien renvoyer.
2 . [ Algorithmes élémentaires sur les listes de nombres réels ] ( ind )
Écrire des fonctions appartient(t,x), maximum(t) et moyenne(t) renvoyant respectivement :
a) True si x figure dans le tableau t, False sinon ;
b) le plus grand élément de le tableau t ;
c) la moyenne des termes de le tableau t ;
Les deux dernières fonctions renverrons None si t est vide.
3 . [ Tableau des positions dans un tableau ] ( ind )
Écrire une fonction positions(x,t) calculant le tableau (éventuellement vide) des positions d’un objet x dans un tableau t. Par exemple,
>>> t=[1,2,3,1,5]
>>> positions(3,t)
>>> positions(6,t)
>>> positions(1,t)
[]
[0,3]
[2]
4 . [ Sommes cumulées d’une liste de nombres ] ( ind )
Écrire une fonction sommesCumulees(t) prenant en entrée un tableau t, et renvoyant le tableau des
sommes cumulées (depuis le premier terme). Par exemple, l’appel
t =[0 ,1 ,2 ,3 ,4 ,5 ,6 ,7]
sommesCumulees ( t )
doit renvoyer [0,1,3,6,10,15,21,28]. Évaluer le nombre d’additions réalisées, en fonction de la longueur n du tableau. Si ce nombre est de l’ordre de n 2 , essayer de réécrire le programme pour arriver à
un nombre de l’ordre de n.
5 . [ Tableaux croissants ] ( ind )
Écrire un programme renvoyant True si le tableau d’entiers donné en argument est croissant, et False
sinon.
LLG \ PCSI2
Info – Exercices 3 \ 2
PCSI2 \ 2014-2015
Laurent Kaczmarek
6 . [ Distance maximale dans une liste ] ( ind )
Écrire une fonction distanceMax(t) prenant en entrée un tableau t non vide, et renvoyant un triplet
(d , i , j ) tel que i É j et d = |t [i ] − t [ j ]| soit maximal.
7 . [ Présence d’un doublon dans un tableau ] ( ind )
Écrire une fonction Doublon(t) renvoyant, pour tout tableau t, False si tous les éléments de t sont
deux à deux distincts, True sinon.
8 . [ Doublons ] ( ind )
Écrire une fonction indicesDoublons(t) prenant en entrée un tableau t non vide, et renvoyant le
tableau (éventuellement vide) des couples (i , j ) tels que i < j et t [i ] = t [ j ].
9 . [ Les tricheurs ♪ ] ( ind )
Vous êtes employé dans un cinéma et votre patron décide de lancer une offre spéciale. Toute personne
possédant une carte de fidélité a le droit, pendant un mois, de voir un film gratuit par jour. Bien entendu
certaines personnes vont essayer de tricher en venant plusieurs fois au cinéma dans la même journée
et votre travail consiste à détecter ces tricheurs. Si vous trouvez un tricheur, vous devez laisser votre
caisse à un collègue, et emmener le tricheur chez votre patron qui lui confisquera sa carte. Votre fonction
tricheur prend en entrée la liste num des numéros de carte utilisés dans la journée et doit renvoyer le
numéro du premier tricheur (s’il y en a au moins un) ou None sinon. On garantit que les numéros sont
tous des entiers positifs « pas trop grands » (de sorte à pouvoir facilement être utilisés comme indices
d’une liste).
10 . [ Codage et décodage en base 2 ♪ ] ( ind )
Écrire une fonction codage(n) qui renvoie la liste des chiffres en base 2 d’un entier naturel n.
11 . [ Les deux plus grands termes d’une suite ♪ ] ( ind )
On souhaite trouver un algorithme renvoyant les deux plus grands termes d’un tableau t comportant
au moins deux éléments.
a) Écrire une fonction termesMax(t) prenant en entrée un tableau t possédant au moins deux éléments, et renvoyant les deux derniers termes de la liste t triée par ordre croissant. Par exemple :
>>> t=[5,-3,2,11]
>>> termesMax(t)
>>> t=[5,11,2,11]
>>> termesMax(t)
[5,11]
[11,11]
b) Écrire une fonction maxMax(t) prenant en entrée un tableau t possédant au moins deux éléments,
et renvoyant les deux plus grands éléments de l’ensemble des valeurs de t si t n’est pas constant,
et None sinon. Par exemple,
>>> t=[5,-3,2,11]
>>> maxMax(t)
>>> t=[5,11,2,11]
>>> maxMax(t)
>>> t=[1,1,1,1]
>>> termesMax(t)
[5,11]
[5,11]
None
LLG \ PCSI2
Info – Exercices 3 \ 3
PCSI2 \ 2014-2015
Laurent Kaczmarek
12 . [ Plus longue séquence de zéros dans un tableau de bits ♪ ] ( ind )
Soit un entier naturel n non nul et une liste t de longueur n dont les termes valent 0 ou 1. Le but de
cet exercice est de trouver le nombre maximal de 0 contigus dans t (c’est à dire figurant dans des cases
consécutives). Par exemple, le nombre maximal de zéros contigus du tableau t’ suivant vaut 4 :
i
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
t’[i] 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 1 0
a) Écrire une fonction nombreZeros(t,n,i), prenant en paramètres un tableau t, sa longueur n et
un indice i compris entre 0 et n − 1, et qui renvoie :
½
0, si t [i ] = 1
le nombre de zéros conséctifs qu’il y a dans t à partir de t[i] inclu, si t [i ] = 0
Par exemple, les appels nombreZeros(t’,18,4) et nombreZeros(t’,18,1) doivent renvoyer
respectivement 3 et 0.
b) Comment obtenir le nombre maximal de zéros contigus d’une liste t connaissant le tableau des
nombreZeros(t,n,i) pour i ∈ ‚0, n − 1ƒ ?
c) En déduire une fonction nombreZerosMax(t) qui renvoie le nombre maximal de 0 contigus d’une
liste t non vide et qui utilise nombreZeros.
d) Voyez-vous un moyen simple, toujours en utilisant la fonction nombreZeros, d’obtenir un algorithme plus performant ?
13 . [ Mimimum d’un tableau, valeur et occurrences ♪ ] ( ind )
a) Écrire une fonction minEtInd(t) qui renvoie un couple contenant le minimum d’un tableau t et l’indice de sa première occurrence. Par exemple, l’appel de fonction minEtInd([4,5,6,2,5,3,2]) doit renvoyer (2,3).
b) Écrire une fonction occsMin(t) qui renvoie le tableau des occurrences du minimum d’un tableau
t. Par exemple, occsMin([4,5,6,2,5,3,2] doit renvoyer [3,6].
14 . [ Amnistie et arithmétique, Elements of mathematics, 1975, St-Louis ♪♪ ] ( ind )
Dans la prison centrale de Sikinia, il y a 100 cellules numérotées 1, 2, 3, . . . , 30, toutes occupées. Les
portes des cellules peuvent être dans deux états : ouvertes ou fermées. On peut passer d’un état à l’autre
en faisant faire un demi-tour au bouton de la porte. Au moment où commence l’histoire, toutes les
portes sont fermées. Pour fêter le vingtième anniversaire de la république de Sikinia, le président décide
d’une amnistie. Il donne au directeur de la prison les ordres suivants :
. Tournez successivement d’un demi-tour les boutons de toutes les portes, puis d’une porte sur deux à
partir de la deuxième, puis d’une porte sur trois à partir de la troisième, puis d’une porte sur quatre à
partir de la quatrième, et ainsi de suite jusqu’à la dernière cellule.
. Libérez alors les prisonniers dont la porte de la cellule est ouverte.
a) Écrire un programme calculant la liste des prisonniers libérés ainsi que leur nombre.
b) Conjecturer puis démontrer le cas général où le nombre de cellules est n.
LLG \ PCSI2
Info – Exercices 3 \ 4
PCSI2 \ 2014-2015
Laurent Kaczmarek
15 . [ Crible d’Eratosthène ♪♪ ] ( ind )
Au IIIe siècle avant Jesus-Christ, Ératosthène, mathématicien, astronome et philosophe invente une méthode efficace pour énumérer tous les nombres premiers inférieurs à un entier donné n. Cette méthode
est connue sous le nom de crible d’Ératosthène, que nous allons décrire dans un langage moderne :
. On initialise un tableau t de n booléens à True. En k-ième case, le True s’interprète
comme : jusqu’ici, et jusqu’à preuve du contraire, k semble être premier.
. Tous les multiples stricts de 2 ne sont pas premiers : on passe donc à False tous les t[2i]
pour 4 É 2i É n.
. Tous les multiples stricts de 3 ne sont pas premiers : on passe donc à False tous les t[3i]
pour 9 É 3i É n.
. On constate que 4 n’est pas premier (t[4] a été mis à False lors du premier passage) :
inutile de rayer les multiples de 4, qui l’ont déjà été.
. Tous les multiples stricts de 5 ne sont pas premier : on passe donc à False tous les t[5i]
pour 25 É 5i É n.
. Ainsi de suite.
À la fin de l’algorithme, la k-ème case de t contient True si et seulement si k est premier.
a) Proposer un algorithme sous la forme d’un pseudo-code pour cette méthode de crible. On s’attachera à respecter l’esprit de cette technique, et en particulier à éviter divisions et racines carrées.
b) Écrire la fonction cribleEratosthene(n) qui renvoie la liste des nombres premiers compris
entre 1 et n.
16 . [ Fusion de deux listes triées ♪♪ ] ( ind )
Écrire une fonction fusion(t1,t2) prenant en argument deux tableaux de nombres triés dans l’ordre
croissant (t1,t2) et renvoyant le tableau trié résultant de la fusion de t1 et t2.
17 . [ La suite de Conway ♪♪ ] ( ind )
Le premier terme de la suite de Conway est égal à 1. Chaque terme de la suite se construit en annonçant le terme précédent, c’est-à-dire en indiquant combien de fois chacun de ses chiffres se répète. On
représente les termes de la suite par des listes. Ainsi, u 0 =[1]. Ce terme comporte juste un « 1 ». Par
conséquent, le terme suivant est u 1 =[1,1]. Celui-ci est composé de deux « 1 », on a donc u 2 = [2,1],
et, en poursuivant le procédé :

u 3 = [1,2,1,1]




 u 4 = [1,1,1,2,2,1]
u 5 = [3,1,2,2,1,1]



u = [1,3,1,1,2,2,2,1]

 6
etc.
a) Écrire une procédure suivantConway(t) renvoyant la liste obtenue en appliquant le procédé décrit ci-dessus à la liste t.
b) Afficher les dix premiers termes de la suite de Conway.
18 . [ The Josephus problem ♪♪ ] ( ind )
The problem is named after Flavius Josephus, a Jewish historian living in the 1st century. According to
Josephus’ account of the siege of Yodfat, he and his 40 comrade soldiers were trapped in a cave, the exit
of which was blocked by Romans. They chose suicide over capture and decided that they would form
a circle and start killing themselves using a step of three. Josephus states that by luck or maybe by the
hand of God, he and another man remained the last and gave up to the Romans. By writing a program,
calculate the positions of the two survivors in the initial circle.
LLG \ PCSI2
Info – Exercices 3 \ 5
PCSI2 \ 2014-2015
Laurent Kaczmarek
2. Chaînes de caractères
19 . [ Bégaiement ] ( ind )
Écrire une fonction begaie(L) qui prend en argument une liste de chaînes et qui affiche chaque caractère de chaque chaîne deux fois de suite. Par exemple, begaie([’tout’,’heure’]) doit renvoyer
[’ttoouutt’,’hheeuurree’].
20 . [ Le code de César ♪♪ ] ( ind )
Le code de César est le plus rudimentaire que l’on puisse imaginer. Il a été utilisé par Jules César pour
certaines de ses correspondances. Le principe est de décaler circulairement les lettres de l’alphabet vers
la droite d’un certain nombre d de lettres appartenant à ‚0, 25ƒ, appelé clé du code. Par exemple, en
choisissant d = 1, le caractère A se transforme en B, le B en C, . . . , et le Z en A. Le message "LOUIS LE
GRAND" est donc codé par "MPVJT MF HSBOE". Afin d’alléger le traitement des messages, ceux-ci, qu’il
soient codés ou décodés, sont enregistrés sous la forme de chaînes de caractères ne comportant que des
majuscules, aucun caractère accentué, aucune apostrophe, ni aucun signe de ponctuation ; de simples
espaces séparent les mots du message.
a) Codage et décodage d’un texte connaissant la clé.
i) Écrire une procédure codageCesar(M,d) prenant en argument une chaîne de caractères M et
un décalage d , et qui retourne le message M décalé de d lettres. On pourra utiliser la méthode
index de la classe str : si c est une chaîne de caractères et lettre une lettre de l’alphabet,
c.index(’l’) renvoie la position de la première apparition de la lettre lettre dans c (attention, la numérotation commence à 0).
ii) Que donne le codage de "ONLY GOD FORGIVES" pour un décalage de 12 lettres ?
iii) Écrire une procédure decodageCesarAvecCle(M,d) prenant les mêmes arguments et mais
qui réalise le décodage d’un message M.
b) « Casser » un code de César. Pour décoder un message, il faut connaître la clé d employée. L’approche
la plus couramment employée est de déterminer la fréquence d’apparition de chaque lettre de
l’alphabet dans le message crypté. La lettre E étant la plus fréquente dans un texte « suffisamment
long » en français, cette approche est statistiquement efficace.
i) Écrire une procédure frequences(M) qui prend en argument un message codé sous la forme
d’une chaîne de caractères M et qui retourne la liste de taille 26 dont le terme d’indice 0 É i É 25
contient le nombre d’occurrences de la (i + 1)-ième lettre de l’alphabet dans M.
ii) Écrire une procédure cle(M) qui prend en argument un message codé M et qui retourne la
valeur de la clé utilisée.
iii) Écrire une procédure decodageCesar(M) qui prend en argument un message codé M et qui
retourne le message décodé.
iv) Décoder le message suivant :
SL YVTHU ZWSLUKLBYZ LA TPZLYLZ KLZ
JVBYAPZHULZ LZA SH ZBPAL KLZ PSSBZPVUZ WLYKBLZ
21 . [ Constante de Champernowne ♪♪ ] ( ind )
La constante de Champernowne est le nombre obtenu en concaténant derrière la virgule les entiers
naturels consécutifs : 0.1234567891011121314151617181920212223 . . . On note d n la n-ième décimale
de ce nombre. Par exemple, d 1 = 1 et d 15 = 2.
a) Écrire une fonction d(n) renvoyant d n .
b) Vérifier que d 1 d 10 d 100 d 1000 d 10000 d 100000 d 1000000 = 210.
LLG \ PCSI2
Info – Exercices 3 \ 6
PCSI2 \ 2014-2015
Laurent Kaczmarek
3. Indications
1 . [ Échange de deux éléments dans une liste ]
Il suffit d’échanger par t[i],t[j]=t[j],t[i].
2 . [ Algorithmes élémentaires sur les listes de nombres réels ]
Effectuer des boucles for.
3 . [ Tableau des positions dans un tableau ]
Il suffit d’effectuer un parcours de t par une boucle for en ajoutant une position au tableau des indices
à chaque occurrence de x.
4 . [ Sommes cumulées d’une liste de nombres ]
Programmer une boucle for en n’utilisant que deux variables : tsommes contenant à la fin la liste des
sommes cumulées et s pour les valeurs successives de ces sommes.
5 . [ Tableaux croissants ]
Parcourir le tableau t à la recherche d’un indice i tel que t[i+1]>t[i] : s’il n’en existe pas, le tableau
est croissant, sinon il ne l’est pas.
6 . [ Distance maximale dans une liste ]
Effectuer deux boucles for imbriquées pour traquer le maximum. La valeur absolue d’un réel est obtenue par la fonction abs.
7 . [ Présence d’un doublon dans un tableau ]
Deux boucles for imbriquées.
8 . [ Doublons ]
Deux boucles for imbriquées.
9 . [ Les tricheurs ♪ ]
On crée la liste carte à valeurs boolénnes telle que carte[i] contient le nombre de fois que la carte
numérotée i a été utilisée. On parcourt ensuite cette liste pour détecter (s’il existe) le plus petit i tel que
t[i]>1.
10 . [ Codage et décodage en base 2 ♪ ]
Plutôt que d’utiliser une instruction du type t=[c]+t, il vaut mieux ajouter les chiffres à la fin avec
append et, à la fin, inverser le tableau. Le coût algorithmique de la première méthode est quadratique,
alors que la seconde a un coût linéaire.
11 . [ Les deux plus grands termes d’une suite ♪ ]
Deux idées pour le a) :
. Échanger deux termes consécutifs qui ne sont pas dans l’ordre croissant en commençant au début
de la liste, puis effectuer le même traitement une seconde fois : à la fin les deux derniers termes sont les
plus grands de la liste.
. Créer deux variables contenant initialement les deux premiers termes de la listes que l’on modifie en
parcourant la liste.
Au b), le second point de vue est adaptable.
LLG \ PCSI2
Info – Exercices 3 \ 7
PCSI2 \ 2014-2015
Laurent Kaczmarek
12 . [ Plus longue séquence de zéros dans un tableau de bits ♪ ]
Au d), il suffit de parcourir les cases qui sont le début d’une séquence de zéros et de trouver le maximum
des longueurs correspondantes.
13 . [ Mimimum d’un tableau, valeur et occurrences ♪ ]
Au b), effectuer deux parcours du tableau : un premier pour trouver le minimum, un second pour remplir
le tableau des occurrences.
14 . [ Amnistie et arithmétique, Elements of mathematics, 1975, St-Louis ♪♪ ]
a) Utiliser un tableau t de longueur 100 à valeurs booléennes (t[i] contenant la réponse à la question : « la cellule i+1 est ouverte »). Initialement t vaut [True]*100 puis on le modifie par une
boucle en suivant l’énoncé. Un simple parcours de t permet de conclure à la fin. On trouve :
La
La
La
La
La
La
cellule
cellule
cellule
cellule
cellule
cellule
1 est ouverte
4 est ouverte
9 est ouverte
16 est ouverte
25 est ouverte
36 est ouverte
La
La
La
La
Il
cellule 49 est ouverte
cellule 64 est ouverte
cellule 81 est ouverte
cellule 100 est ouverte
y a 10 cellules ouvertes
b) On prouve que la cellule i est ouverte si et seulement si i admet un nombre pair de diviseurs, ce
qui équivaut à i est un carré.
15 . [ Crible d’Eratosthène ♪♪ ]
Utiliser un tableau de booléen prime, initialisé à [True]*(n+1). Barrer un entier i revient à affecter
False à prime[i]. À la fin de l’algorithme, il suffit de parcourir prime et d’ajouter à une liste initialement vide tout les indices i supérieurs à deux tels que t[i] contienne True.
16 . [ Fusion de deux listes triées ♪♪ ]
On note n1 et n2 les longueurs respectives des tableaux t1 et t2. La future liste fusionnée t est initialement vide. Utiliser deux indices i1 et i2 de position dans les tableaux t1 et t2. Tant que i1<n1 et i2<n2,
ajouter à t le terme qui suit (faire un test). À la fin de cette boucle, une des deux listes est épuisée mais
pas nécessairement les deux : il faut donc ajouter à t les termes de la liste non épuisée.
17 . [ La suite de Conway ♪♪ ]
On parcourt la liste t une seule fois en remplissant au fur et à mesure au moyen d’un compteur la liste
suivante notée suivt.
18 . [ The Josephus problem ♪♪ ]
Les soldats sont repésentés par la liste t=[0,1,2,...,40]. Le premier soldat à suicider est t[0], puis
vient le tour de t[3], . . . , t[39]. La liste des survivants est t après délétion de t[0:41:3]. On recommence un tour : le premier suicidé est cette fois-ci t[1], etc. Automatiser cela au moyen d’une boucle.
LLG \ PCSI2
Info – Exercices 3 \ 8
PCSI2 \ 2014-2015
Laurent Kaczmarek
19 . [ Bégaiement ]
À chaque itération d’une boucle for sur L, initialiser une chaîne vide qui sera remplie en parcourant la
chaîne courante de L.
20 . [ Le code de César ♪♪ ]
Créer la chaîne alpha="ABCD · · · Z". Pour un décalage de d , la lettre ’R’ sera remplacée par
alpha[(alpha.index(’R’)+d)% 26].
21 . [ Constante de Champernowne ♪♪ ]
On note c la constante de Champernowne. Les décimales de c s’obtiennent facilement par concaténation. On pourrait utiliser des listes mais les chaînes de caractères sont plus faciles à manier ici.
LLG \ PCSI2
Info – Exercices 3 \ 9