Télécharger - La PSI* du Lycée d`Arsonval

Transcription

Télécharger - La PSI* du Lycée d`Arsonval
CORRIGÉ DS INFO 01/2017
PSI* 16-17
CORRIGÉ DS INFO 01/2017 (d’après X 2017 MP/PC)
1
# DS Info TPC-PSI 2016
2
3
4
5
##############
# Question 1 #
##############
6
7
8
9
10
11
12
def transforme(texte):
# version basique
t = []
for car in texte:
t.append(ord(car))
return t
13
14
15
16
def transforme2(texte):
# version plus compacte
return list(map(ord, texte))
17
18
19
# la fonction transforme fait autant d'opérations élémentaires que la longueur
# n du texte; sa complexité est donc O(n)
20
21
22
23
##############
# Question 2 #
##############
24
25
26
27
28
29
def occurrences(t):
occ = [0]*256
for car in t:
occ[car] += 1
return occ
30
31
32
# cette fonction se contente de parcourit le tableau t de longueur n
# sa complexité est donc O(n)
33
34
35
36
##############
# Question 3 #
##############
37
38
39
40
41
42
43
44
def mini(t):
occ = occurrences(t)
mu = 0
for k in range(1, len(occ)): # len(occ) = 256!
if occ[k] < occ[mu]:
mu = k
return mu
45
46
47
48
##############
# Question 4 #
##############
49
50
51
52
53
54
55
56
57
def compresse(t):
n = len(t)
mu = mini(t)
t0 = [mu]
i, j = 0, 0
# i = indice du caractère en train d'être examiné
# les éléments entre t[i] et t[j] inclus sont tous égaux
while i < n:
Informatique PSI* – © T.LEGAY – Lycée d’Arsonval
1/5
15 janvier 2017
CORRIGÉ DS INFO 01/2017
58
59
60
61
62
63
64
65
66
PSI* 16-17
x = t[i] # pour éviter de l'appeler plusieurs fois
while j < n and t[j] == x:
j += 1
if j - i <= 3:
t0.extend([x]*(j-i))
else:
t0.extend([mu, j - i - 1, x])
i = j
return t0
67
68
69
70
##############
# Question 5 #
##############
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def decompresse(t0):
n = len(t0)
mu = t0[0]
t = []
i = 1
while i < n:
if t0[i] != mu:
t.append(t0[i])
i += 1
else:
t.extend((t0[i+1]+1)*[t0[i+2]])
i += 3
return(t)
85
86
87
88
##############
# Question 6 #
##############
89
90
91
# on remarque que rot[i] est formée de la fin de la liste à partir du caractère
# d'indice i à laquelle on a concaténé le début de cette liste
92
93
94
95
96
97
98
99
100
101
102
103
def comparerRotations1(t, i, j):
# cette version a le défaut de créer 2 listes supplémentaires
# pour stocker les rotations d'indices i et j
rot_i = t[i:] + t[0:i]
rot_j = t[j:] + t[0:j]
for k in range(len(t)):
if rot_i[k] > rot_j[k]:
return 1
if rot_i[k] < rot_j[k]:
return -1
return 0
104
105
106
107
108
109
110
111
112
113
114
115
116
def comparerRotations(t, i, j):
# bien meilleure
n = len(t)
for k in range(len(t)):
# k-ième caractère des chaines obtenues après rotation
rot_i_k = t[(i+k)%n]
rot_j_k = t[(j+k)%n]
if rot_i_k > rot_j_k:
return 1
if rot_i_k < rot_j_k:
return -1
return 0
117
118
def triRotations(t):
Informatique PSI* – © T.LEGAY – Lycée d’Arsonval
2/5
15 janvier 2017
CORRIGÉ DS INFO 01/2017
PSI* 16-17
# trie les rotations comme dans l'énoncé, mais on a utilisé ici pour
# simplifier un tri par insertion, de complexité O(nˆ2)
# Il faudrait utiliser un tri fusion ou un tri rapide pour avoir
# une complexité en O(n ln(n))
n = len(t)
r = [i for i in range(n)]
#la liste r contient les numéros des rotations
for i in range(1,n):
x = r[i]
j = i-1
while (j >= 0) and (comparerRotations(t, r[j], x) == 1):
j -= 1
r[j+2:i+1] = r[j+1:i]
r[j+1] = x
return r
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
##############
# Question 7 #
##############
138
139
140
141
142
# on remarque que la dernière lettre de rot[i] est en fait t[i-1]
#(vrai même si i=0!)
# Pour la clé, on remarque que c'est le dernier caractère du mot obtenu
# après la rotation numéro 1
143
144
145
146
147
148
149
150
151
def codageBW(t):
t0 = []
r = triRotations(t)
for i in range(len(r)):
if r[i] == 1:
cle = i
t0.append(t[r[i]-1])
return t0, cle
152
153
154
155
156
#
#
#
#
La fonction triRotations effectue O(n ln(n)) appels à la procédure
comparerRotations qui est, elle, de complexité O(n). Elle est donc de
de complexité O(nˆ2 ln(n)), et il en est de même de la fonction codageBW
puisque celle-ci effectue en plus seulement n boucles.
157
158
159
160
##############
# Question 8 #
##############
161
162
# la fonction frequences est identique à la fonction occurrences !
163
164
165
166
167
168
169
def frequences(t0):
t = t0[:len(t0)]
freq = [0]*256
for car in t:
freq[car] += 1
return freq
170
171
172
173
##############
# Question 9 #
##############
174
175
176
177
178
179
def triCarsDe(t0):
triCars = []
freq = frequences(t0)
for i in range(256):
if freq[i] != 0:
Informatique PSI* – © T.LEGAY – Lycée d’Arsonval
3/5
15 janvier 2017
CORRIGÉ DS INFO 01/2017
180
181
PSI* 16-17
triCars.extend(freq[i]*[i])
return triCars
182
183
184
185
###############
# Question 10 #
###############
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def trouverIndices(t0):
n = len(t0)
freq = frequences(t0)
triCars = triCarsDe(t0)
i = 0
indices = []
while i < n:
k = 0 # indice qui va servir à parcourir le tableau t0
car = triCars[i]
m = freq[car]
compteur = 0
j = 1
while j <= m:
#on cherche ici la j-ième apparition de triCars[i] dans t0
while k < n and compteur < j:
if t0[k] == car:
compteur += 1
if compteur == j:
indices.append(k)
k += 1
j += 1
i += m
return indices
210
211
212
213
214
215
216
217
218
219
220
def trouverIndices2(t0):
# version plus compacte, proposée par un élève
t = triCarsDe(t0)
indices = []
for x in t:
i = 0
while (x != t0[i] or i in indices):
i += 1
indices.append(i)
return indices
221
222
223
224
# Si n=len(t0), la boucle extérieure est faite n fois et à chaque fois
# il faut parcourir le tableau t0 .
# La complexité de la procédure est donc O(nˆ2)
225
226
227
228
###############
# Question 11 #
###############
229
230
231
232
233
234
235
236
237
def decodageBW(t0, cle):
indices = trouverIndices2(t0)
pos = cle
t = []
for k in range(len(t0)):
t.append(t0[pos])
pos = indices[pos]
return t
238
239
240
# Cettefonction fait appel à la fonction trouverIndices,
# puis fait ensuite une boucle de longueur n. Elle est donc aussi
Informatique PSI* – © T.LEGAY – Lycée d’Arsonval
4/5
15 janvier 2017
CORRIGÉ DS INFO 01/2017
241
PSI* 16-17
# de complexité O(nˆ2)
242
243
244
# L'ensemble du processus compression/décompression sera donc de complexité
# O(n) + O(nˆ2) + O(nˆ2 ln(n)) = O(n ln(n))
245
246
# On exécute alors toutes les procédures précédentes pour vérifier!
247
248
249
250
251
# Une procédure utile
def list_to_str(liste):
# Convertit une liste d'entiers entre 0 et 255 en chaine
return "".join(chr(i) for i in liste)
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
texte = 'Ô mathématiques sévères, je ne vous ai pas oubliées, depuis que \
vos savantes leçons, plus douces que le miel, filtrèrent \
dans mon coeur, comme une onde rafraı̂chissante.\n' +\
'J\'aspirais instinctivement, dès le berceau, à boire à votre source, \
plus ancienne que le soleil, et je continue encore de fouler le parvis \
sacré de votre temple solennel, moi, le plus fidèle de vos initiés.\n' + \
'Il y avait du vague dans mon esprit, un je ne sais quoi épais comme de \
la fumée ; mais, je sus franchir religieusement les degrés qui mènent à votre \
autel, et vous avez chassé ce voile obscur, comme le vent chasse le damier.\n' +\
'Vous avez mis, à la place, une froideur excessive, une prudence consommée\
et une logique implacable.\n' +\
'À l\'aide de votre lait fortifiant, mon intelligence s\'est rapidement \
développée, et a pris des proportions immenses, au milieu de cette clarté \
ravissante dont vous faites présent, avec prodigalité, à ceux qui \
vous aiment d\'un sincère amour.\n'+\
'Arithmétique! algèbre! géométrie! trinité grandiose! triangle lumineux! \
Celui qui ne vous a pas connues est un insensé !\n'+\
'Il mériterait l\'épreuve des plus grands suplices ; car, il y a du mépris \
aveugle dans son insouciance ignorante; mais, celui qui vous connaı̂t et vous \
apprécie ne veut plus rien des biens de la terre ; se contente de vos \
jouissances magiques; et, porté sur vos ailes sombres, ne désire plus \
que de s\'élever, d\'un vol léger, en construisant une hélice ascendante, \
vers la voûte sphérique des cieux.\n'+\
'La terre ne lui montre que des illusions et des fantasmagories morales; \
mais vous, ô mathématiques concises, par l\'enchaı̂nement rigoureux de vos \
propositions tenaces et la constance de vos lois de fer, vous faites luire, \
aux yeux éblouis, un reflet puissant de cette vérité suprême dont on \
remarque l\'empreinte dans l\'ordre de l\'univers.\n\n'+\
'Comte de Lautréamont, Les Chants de Maldoror, Chant 10, Strophe 2.'
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# tranformation du texte en liste de caractères puis de nombres
t = transforme(list(texte))
# transformation de BW
t0, cle = codageBW(t)
# compression
t_compresse = compresse(t0)
# comparaison des longueurs des textes
print('Longueur texte initial: ',len(t))
print('Longueur texte compressé: ', len(t_compresse),'\n')
# décompression
t0 = decompresse(t_compresse)
# transformation de BW inverse
t = decodageBW(t0, cle)
# on transforme la liste de nombres en chaı̂ne
texte_retrouve = list_to_str(t)
# et on affiche
print(texte_retrouve)
Informatique PSI* – © T.LEGAY – Lycée d’Arsonval
5/5
15 janvier 2017
CORRIGÉ DS INFO 01/2017
PSI* 16-17
Longueur texte initial: 1865
Longueur texte compressé: 1746
Ô mathématiques sévères, je ne vous ai pas oubliées, depuis que vos savantes leçons, plus douces qu
J'aspirais instinctivement, dès le berceau, à boire à votre source, plus ancienne que le soleil, et
Il y avait du vague dans mon esprit, un je ne sais quoi épais comme de la fumée ; mais, je sus fran
Vous avez mis, à la place, une froideur excessive, une prudence consomméeet une logique implacable.
À l'aide de votre lait fortifiant, mon intelligence s'est rapidement développée, et a pris des prop
Arithmétique! algèbre! géométrie! trinité grandiose! triangle lumineux! Celui qui ne vous a pas con
Il mériterait l'épreuve des plus grands suplices ; car, il y a du mépris aveugle dans son insoucian
La terre ne lui montre que des illusions et des fantasmagories morales; mais vous, ô mathématiques
Comte de Lautréamont, Les Chants de Maldoror, Chant 10, Strophe 2.
Informatique PSI* – © T.LEGAY – Lycée d’Arsonval
6/5
15 janvier 2017