Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

IPT MPSI DS3 Corrige

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 10

Lycée Malherbe Année scolaire 2018-2019 MPSI - Informatique pour tous

Devoir surveillé no3 Corrigé

Date : samedi 30 mars 2019 Durée : 2 heures


total sur 59 points + 4 points de bonus
(barême donné à titre indicatif, susceptible d’être modifié)

‚ Les programmes demandés seront écrits en langage Python. Prière de faire figurer clairement les
niveaux d’indentation à l’aide de barres verticales comme expliqué en cours.
‚ Plus généralement, la clarté du raisonnement, la rédaction, la précision du discours, la mise en
page, la présentation, le soin et l’orthographe seront pris en compte. Laissez une marge à gauche !
‚ Questions dans l’ordre et bien numérotées.
‚ Les calculatrices et téléphones portables sont interdits durant l’épreuve.
‚ Je voudrais vous corriger en rouge, donc n’utilisez pas cette couleur sur votre copie.
Les parties du devoir sont complètement indépendantes.

1 Tableaux numpy (6 points)


Pour toute cette partie, on suppose que le module numpy a été importé avec
import numpy as np

1 (4 points) Compléter les réponses de la console marquées de xxxxxxxxx (ces réponses peuvent
s’étaler sur plusieurs lignes. . . )
1 >>> A = np.random.randint(-10,11,(8,8))
2 >>> print(A)
3 [[ -8 -10 -10 2 4 -8 -9 -9]
4 [ 10 -7 1 -8 10 10 -9 -4]
5 [-10 8 -9 -8 9 9 1 8]
6 [ -9 9 0 7 -5 2 -9 -2]
7 [ 0 -1 -3 6 10 1 -8 10]
8 [ 7 -8 3 3 -9 3 7 3]
9 [ -9 4 -1 -5 -9 -7 -7 -3]
10 [ -8 -3 -1 7 3 6 -7 6]]
11 >>> print(A[1:3,2:4])
12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
13 >>> print(A[-4:,:7])
14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
15 >>> print(A[6:7,6:7])
16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
17 >>> print(A[6,6:7])
18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
19 >>> print(A[6:7,6])
20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1
21 >>> print(A[6,6])
22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
23 >>> print(A[:,-1:])
24 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
25 >>> print([ [A[i][j] for j in range(8) if i+j>7 ] for i in range(8) if i
%3==0 ])
26 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1 >>> A = np.random.randint(-10,11,(8,8))
2 >>> print(A)
3 [[ -8 -10 -10 2 4 -8 -9 -9]
4 [ 10 -7 1 -8 10 10 -9 -4]
5 [-10 8 -9 -8 9 9 1 8]
6 [ -9 9 0 7 -5 2 -9 -2]
7 [ 0 -1 -3 6 10 1 -8 10]
8 [ 7 -8 3 3 -9 3 7 3]
9 [ -9 4 -1 -5 -9 -7 -7 -3]
10 [ -8 -3 -1 7 3 6 -7 6]]
11 >>> print(A[1:3,2:4])
12 [[ 1 -8]
13 [-9 -8]]
14 >>> print(A[-4:,:7])
15 [[ 0 -1 -3 6 10 1 -8]
16 [ 7 -8 3 3 -9 3 7]
17 [-9 4 -1 -5 -9 -7 -7]
18 [-8 -3 -1 7 3 6 -7]]
19 >>> print(A[6:7,6:7])
20 [[-7]]
21 >>> print(A[6,6:7])
22 [-7]
23 >>> print(A[6:7,6])
24 [-7]
25 >>> print(A[6,6])
26 -7
27 >>> print(A[:,-1:])
28 [[-9]
29 [-4]
30 [ 8]
31 [-2]
32 [10]
33 [ 3]
34 [-3]
35 [ 6]]
36 >>> print([ [A[i][j] for j in range(8) if i+j>7 ] for i in range(8) if i
%3==0 ])
37 [[], [2, -9, -2], [-1, -5, -9, -7, -7, -3]]

2 (2 points) Ecrire la matrice représentée par le tableau numpy affichée par le court programme
suivant (abs, c’est la valeur absolue. . . ).


2
1 import numpy as np
2 print(np.array( [[ abs(i-j)+1 for j in range(4) ] for i in range(4) ] ))
 

1 [[1 2 3 4]
2 [2 1 2 3]
3 [3 2 1 2]
4 [4 3 2 1]]
donc ¨ ˛
1 2 3 4
˚ 2 1 2 3 ‹
˚ ‹.
˝ 3 2 1 2 ‚
4 3 2 1

2 Algorithme de Bézout (7 points)

3 (3 points) Ecrire une fonction bezout(a,b) renvoyant un triplet (u,v,d), où d “ PGCDpa, bq, et
au ` bv “ d (a, b ě 0, pa, bq ‰ p0, 0q).

1 def algo14(a,b):
2 (r1,u1,v1,r2,u2,v2)=(a,1,0,b,0,1)
3 while r2!=0:
4 q=r1//r2
5 (r1,u1,v1,r2,u2,v2)=(r2,u2,v2,r1-q*r2,u1-q*u2,v1-q*v2)
6 return r1,u1,v1
7
8 a,b=87,19
9 d,u,v=algo14(a,b) # on vient de déconstruire un tuple
10 print(a*u+b*v==d)
11 print("coeffs trouvés:",u,v)
 

Le théorème de Bézout assure l’existence d’une solution pu0 , v0 , dq. On peut alors montrer que les
solutions sont exactement les triplets de la forme

pu0 ` kb1 , v0 ´ ka1 , dq où a1 d “ a, b1 d “ b et k P Z.

C’est pourquoi le programme suivant, très mauvais en terme de complexité, fonctionne.



1 def pgcd(a,b):
2 while b!=0:
3 a,b=b,a%b
4 return a
5 def bezout(a,b):
6 d=pgcd(a,b)
7 bp=b//d
8 for u in range(-bp,bp):
9 if (d-a*u) % b ==0:
10 return u,(d-a*u)//b,d
11
12 a=783754
13 b=23875

3
14 u,v,d=bezout(a,b)
15 print(a*u+b*v==d)
 

4 (2 points) Expliquez soigneusement pourquoi la fonction écrite termine.


voir cours

5 (2 points) Proposez un invariant de boucle permettant de montrer la correction de cet algorithme


(on ne demande pas de preuve).
$
&PGCDpr1 , r2 q “ d

au1 ` bv1 “ r1

au2 ` bv2 “ r2
%

3 Exponentiation rapide (24 points)


On considère la fonction suivante. On suppose que x est un flottant, et que N est un entier naturel
non nul.

1 def puissance(x,N):
2 r=1
3 while N!=0:
4 if N%2==1:
5 r=x*r
6 N=N//2
7 x=x*x
8 return r
 

6 (2 points) Montrer que la fonction puissance termine.


Chaque tour de boucle contient un nombre fini d’instructions. Il s’agit donc de vérifier que la condition
de sortie de la boucle while est atteinte au bout d’un moment.
On utilise encore le principe de descente infinie.
Partant
Z d’une
^ valeur de N ‰ 0 au début d’un tour de boucle, la valeur N p à la fin du tour de boucle
p “ N ď N ă N . De plus, toutes les valeurs de N sont entières.
est N
2 2
Donc la suite des valeurs de N est une suite d’entiers strictement décroissante, donc finit par atteindre
la valeur 0, et on finit par sortir de la boucle.

7 (3 points) Reproduire et compléter le tableau suivant qui donne les valeurs des variables utilisées
tout au long du déroulement de l’algorithme pour N “ 13 et x “ 3.

i r N x
0 1 13 3
1
.. .. .. ..
. . . .

La variable i est l’indice de l’itération : les valeurs des variables pour i “ 0 sont celles avant le premier
tour de boucle, puis pour i “ 1 à la fin du premier tour, pour i “ 2 à la fin du deuxième tour, etc.
Votre tableau comportera autant de lignes que nécessaires.

4
Entourez le résultat renvoyé par l’algorithme.

i r N x
0 1 13 3
1
1 3 “3 6 32
2 31 “ 3 3 34
3 31 ˆ 34 “ 243 1 38

4 31 ˆ 34 ˆ 38 “ 1 594 323 0 316

Remarquons que si on décompose 13 en binaire en parallèle, les calculs sont les mêmes :

13 “2ˆ6`1
6 “2ˆ3`0
3 “2ˆ1`1
1 “1ˆ1`0

L’action de multiplier r ou non dépend de la présence d’un 1 ou d’un 0 dans l’écriture en binaire, et x
`
contient les puissances 3p2 q successives.

8 (2 points) Expliquez pourquoi le quotient de N dans la division euclidienne par 2 est N {2 si N est
pair et pN ´ 1q{2 si N est impair.
Si N est pair, alors N “ 2k, avec k “ N {2 le quotient recherché.
Si N est impair, alors N “ 2k ` 1, avec k “ pN ´ 1q{2 le quotient recherché.

9 (2 points) On note N “ ran´1 , an´2 , ¨ ¨ ¨ , a1 , a0 s l’écriture de N en base 2. Donner l’écriture en


base 2 du quotient de N dans la division euclidienne par 2.
Par définition, on a N “ a0 ` 2a1 ` 4a2 ` ¨ ¨ ¨ ` 2n´2 an´2 ` 2n´1 an´1 .
On applique alors la question précédente.
— Si N est pair, alors a0 “ 0, et le quotient est

N {2 “ 2a1 ` 4a2 ` ¨ ¨ ¨ ` 2n´2 an´2 ` 2n´1 an´1 “ ran´1 , an´2 , .., a1 s

— et si N est impair, alors a0 “ 1, et le quotient est pN ´ 1q{2, encore égal à la même chose.
Donc la réponse est toujours : ran´1 , an´2 , .., a1 s .

En fait, pour diviser par 2, on supprime le dernier chiffre binaire. Pour comprendre : de la même
manière, prendre le quotient dans la division euclidienne par 10 revient à supprimer le dernier chiffre
décimal.
— Le quotient dans la division euclidienne de 1011102 par 2 est 10111.
— Le quotient dans la division euclidienne de 17893810 par 10 est 17893.

10 (5 points) Montrer que puissance(x,N) renvoie xN .


On pourra prouver l’invariant de boucle suivant :

x̃Ñ “ r ˆ xN ,

5
où x, N et r sont les valeurs courantes des variables x et N et r, et x̃ et Ñ sont les valeurs initiales
(c’est-à-dire les valeurs passées en argument à la fonction).
Il s’agit de l’algorithme d’exponentiation rapide, qui utilise le paradigme de programmation “diviser
pour régner”. Il s’agit d’un algorithme beaucoup plus astucieux que la méthode naı̈ve pour le calcul des
puissances.
En MP, et en option informatique en MPSI, on donnera une version récursive plus “naturelle” de cet
algorithme.
Avant le premier tour de boucle, x̃Ñ “ 1 ˆ xN , ce qui initialise la récurrence.
Notons r, x, N les valeurs des variables locales à la fin d’un tour de boucle, pour lesquelles la proposition
est vérifiée, et rp, x
p, N
p les valeurs à la fin du tour de boucle suivant.
N ´1
Si N est impair, alors N//2 “ et
2
` ˘p N ´1 q
rp ˆ x pN “ xr x2 2 “ rxN “ x̃Ñ .
p

N
Et N est pair, alors N//2 “ et
2
` ˘p N q
pN “ r x2 2 “ rxN “ x̃Ñ .
rp ˆ x
p

Concluons : à la fin du dernier tour, N “ 0, donc r “ x̃Ñ . C’est donc que r à la fin de l’algorithme
est égal à x̃Ñ .

11 (3 points) Montrer que le nombre de bits n de N est équivalent à log2 pN q lorsque N tend vers
l’infini.
N a n chiffres en base b ssi bn´1 ď N ă bn ô n ´ 1 ď logb N ă n.
Donc n „ logb pN q.
En particulier, le nombre de bits de N est équivalent à log2 N .

12 (3 points) Etudier la complexité de l’algorithme d’exponentiation rapide. On donnera une évaluation


asymptotique en fonction du nombre n de bits de N .
A chaque tour de boucle, l’algorithme effectue une ou deux multiplications. Pour évaluer la complexité,
comptons donc le nombre de tours de boucle.
Or, à chaque division euclidienne par 2, N perd un bit. Donc il y a autant de tours de boucle que de
bits de N . Donc complexité en Θpnq .
Ainsi donc, l’exponentiation “naı̈ve” est en Θp2n q (complexité exponentielle) et l’exponentiation rapide
est en Θpnq (complexité linéaire). Sans surprise, la complexité de l’exponentiation rapide est bien meilleure
que celle de l’exponentiation naı̈ve (d’où le nom !).

Si on veut être plus précis (mais ce n’est pas demandé), à chaque tour de boucle, 2 multiplications
sont effectuées si N est impair, et 1 seule si N est pair. Ainsi, le nombre de produits faits par l’algorithme
d’exponentiation rapide est
n´1
ÿ
f pN q “ n ` ak .
k“0
Autrement dit, en notant #1 le nombre de 1 dans l’écriture binaire de N , et #0 le nombre de 0, le
nombre de multiplications est
#0 ` 2 ¨ #1 “ n ` #1.
On obtient donc n ` 1 ď f pN q ď 2n.

13 (4 points) Etudiez le pire et le meilleur cas. Donner une valeur de N à n bits pour le meilleur cas ;
et pour le pire cas.

6
— Le pire cas (le plus grand nombre de multiplications) avec N à n bits correspond à N “ r1, 1, 1 ¨ ¨ ¨ , 1s2 “
2n ´ 1, et 2n multiplications sont alors effectuées (n multiplications par x et n carrés ; plus
précisément, n appels récursifs avec N ą 0, et à chacun de ces appels, 1 multiplication par x
et 1 carré).
— Le meilleur cas (le plus petit nombre de multiplications) avec N à n bits correspond à N “
r1, 0, ¨ ¨ ¨ , 0s2 “ 2n´1 . et n`1 multiplications sont alors effectuées (n carrés et 1 seule multiplication
par x ; plus précisément, n appels récursifs avec N ą 0, et à chacun de ces appels 1 carré, et 1
multiplication par x au dernier appel).

Exemple : On peut utiliser l’algorithme d’exponentiation rapide pour x P Z{mZ.


Par exemple, si on veut calculer le reste de la division euclidienne de 187289 par 44.
Les règles de calcul des moduli nous permettent de réduire tout au long du calcul, et non pas seulement
à la fin.
7289 “ 11100011110012 “ 1 ` 8 ` 16 ` 32 ` 64 ` 1024 ` 2048 ` 4096.
i r N x
0 1 7289 18
2
1 18 3644 18 ” 16
2 18 1822 184 ” 36
3 18 911 188 ” 20
4 18 ˆ 188 455 1816 ” 4
5 18 ˆ 188 ˆ 1816 227 1832 ” 16
6 18 ˆ 188 ˆ 1816 ˆ 1832 113 1864 ” 36
7 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 56 18128 ” 20
8 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 28 18256 ” 4
9 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 14 18512 ” 16
10 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 7 181024 ” 36
11 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 ˆ 181024 3 182048 ” 20
12 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 ˆ 181024 ˆ 182048 1 184096 ” 4
13 18 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 ˆ 181024 ˆ 182048 ˆ 184096 0 ...
On calcule successivement modulo 44 :
$

’ 181 ” 18

182 ” 324 ” 16








’ 184 ” 256 ” 36 ” ´8

’188

’ ” 64 ” 20

1816



’ ” 400 ” 4

’1832


& ” 16
1864 ” 256 ” ´8

’18128

’ ” 20





’ 18256 ”4

’18512

’ ” 16

181024



’ ” ´8

’182048


’ ” 20

% 4096
18 ”4
Et donc 187289 ” 181 ˆ 188 ˆ 1816 ˆ 1832 ˆ 1864 ˆ 181024 ˆ 182048 ˆ 184096 ” 18 ˆ 20 ˆ 4 ˆ 16 ˆ p´8q ˆ
p´8q ˆ 20 ˆ 4 ” 8.
Le reste recherché est 8 (en fait on a appliqué l’exponentiation rapide dans l’anneau Z{44Z).

7
4 Une équation différentielle (22 points)
On s’intéresse à l’équation différentielle : pEq y 1 “ ´y 2 .
Soit I un intervalle ouvert de R, et a P I.
Soit ϕ une solution de pEq sur I telle que ϕpaq “ 0.
Soit t P I, t ě a. On pose M “ supra,ts |ϕ| (M dépend de t).
żt
14 (3 points) Montrer que |ϕptq| ď M |ϕpxq|dx.
a
Une solution ϕ sur I est dérivable sur I, donc continue sur I, donc ϕ1 “ ´ϕ2 est continue.
Donc d’après le théorème fondamental de l’analyse :
żt żt
ϕptq “ 1
ϕ “ ´ϕ2
a a

On conclut avec l’inégalité triangulaire :


żt żt żt
|ϕptq| ď |ϕ| ¨ |ϕ| ď M |ϕpxq|dx “ M |ϕpxq|dx.
a a a

pM pt ´ aqqn
15 (3 points) Montrer que pour tout n P N, |ϕptq| ď M .
n!
Par récurrence sur N.
— La proposition au rang 0 découle de la définition de M .
— Supposons que pour un certain n P N, la proposition à démontrer soit vraie.
En injectant dans l’inégalité de la question précédente, on obtient :

M pM px ´ aqqn pM pt ´ aqqn`1
żt
|ϕptq| ď M dx “ M ,
a n! pn ` 1q!
donc la proposition à démontrer est vraie au rang n ` 1.
Finalement, la proposition à démontrer est vraie pour tout n P N.
An
16 (3 points) Montrer que pour tout A P R, ÝÑ 0.
n! nÑ`8
Soit N P N tel que N ą |A|.
Pour tout n ě N , on a :
ˆ ˙ˆ ˙
An AA A A A A
“ ¨¨¨ ¨¨¨
n! 1 2 N ´1 N N `1 n

Donc ˇ nˇ ˇ ˇn´N `1
ˇA ˇ N ´1 ˇ
|A| ˇAˇ
ˇ
ˇ ˇď
ˇ n! ˇ pN ´ 1q! ˇ N ˇ ,
ˇ ˇ ˇ ˇn
ˇAˇ ˇAˇ
et comme ˇˇ ˇˇ ă 1, ˇ ˇ ÝÑ 0, ce qui permet de conclure.
N ˇ N ˇ nÑ`8

17 (2 points) En déduire que ϕ est la fonction identiquement nulle sur I.


On peut établir une inégalité analogue pour t ď a, et finalement, pour tout t P I, il existe M (qui
pM |t ´ a|qn
dépend de t) tel que |ϕptq| ď M .
n!
On conclut en faisant tendre n vers `8, que ϕptq “ 0.

8
18 (3 points) Montrer que sur l’intervalle r0, 5s, il existe une unique solution f de E telle que f p0q “ 1
et en donner une expression.
Cette solution ne s’annule pas en 0, donc ne s’annule pas du tout (d’après la question précédente).
On obtient alors
f 1 ptq
´ “1
f ptq2
donc
1
“t`K
f ptq
où K est constante, c’est-à-dire encore :
1
f ptq “ .
t`K
Avec la condition initiale, on trouve K “ 1, donc
1
f ptq “ .
t`1

19 (2 points) Ecrire la formule donnant les points ptk q0ďkďn d’une subdivision régulière de r0, 5s en n
sous-intervalles.
5 5
Pour k P v0, nw, tk “ kh “ k (on a posé h “ le pas de la subdivision).
n n
On désire calculer une valeur de f (on suppose qu’on ne connaı̂t pas son expression !) aux points tk .
On notera yk la valeur approchée de f ptk q obtenue avec la méthode d’Euler classique vue en cours.

20 (2 points) Donner la formule de récurrence pour calculer les yk . On ne demande pas de justification.
y0 “ 1, et pour tout k P v0, n ´ 1w, yk`1 “ yk ´ hyk2 “ yk p1 ´ hyk q, où h a été donné à la réponse
précédente.

21 (4 points) Ecrivez un programme Python pour calculer les tk et les yk (que vous stockerez dans
des listes ou dans des tableaux numpy).

1 def Euler(n):
2 h=5/n
3 Lt = [ k * h for k in range(n+1) ]
4 Ly = [1]
5 for k in range(n):
6 yk=Ly[-1]
7 Ly.append( yk - h * yk**2)
8 return Lt,Ly
9
10 import matplotlib.pyplot as plt
11 for n in [5,7,10,30,40]:
12 Lt,Ly=Euler(n)
13 plt.plot(Lt,Ly,label="méthode d’Euler avec n="+str(n)+" intervalles",linewidth
=3)
14
15 import numpy as np
16 Lt=np.linspace(0,5)
17 plt.plot(Lt,1/(1+Lt), linewidth=4,label=’solution exacte’)

9
18
19 plt.legend()
20 plt.show()
 

5 Bonus (4 points)

22 Sauriez-vous dire ce que calcule le petit programme suivant ?



1 def puissance4(n):
2 return sum(int(c)**4 for c in str(n))
3
4 def nombre_sympa(n):
5 return puissance4(n)==n
6
7 print([ n for n in range(10000) if nombre_sympa(n) ])
 

(On ne demande pas le résultat renvoyé. . . mais si vous le trouvez à la main, chapeau !)
Il affiche la liste des nombres entre 0 et 9999 égaux à la somme des puissances quatrièmes de leurs
chiffres décimaux. Python trouve en une fraction de seconde les solutions : 0, 1, 1634, 8208 et 9474.
1 [0, 1, 1634, 8208, 9474]

10

Vous aimerez peut-être aussi