BCPST2
5
0 1 Mise en route
©Exercice 1: Recherche du maximum On considère une listeL
1◦) Ecrire une fonction qui recherche le maximum de la liste.
Solution:
def maxi ( L ) : M = L [ 0 ]
f o r x in L : i f x>M :
M = x return M
2◦) Ecrire une fonction qui recherche le maximum de la liste et renvoie tous les indices où ce maximum est atteint.
Solution:
def maxi_et_rang ( L ) : M = L [ 0 ]
rang = [ 0 ]
f o r k in range ( len ( L ) ) : i f L [ k ] > M :
M = L [ k ] rang = [ k ] e l i f L [ k ] == M :
rang . append ( k ) return M , rang
©Exercice 2: Recherche d'un motif
On considère une listeLet une autre listeM, que l'on appellera motif.
1◦) Ecrire une fonction qui recherche si le motif est présent dans la suiteL, c'est-à-dire, queM est une sous-liste deL.
Solution:
Avec le slicing def est_present ( L , M ) :
m = len ( M ) l = len ( L ) k = 0
f o r i in range ( l−m+1) : i f L [ i : i+m ] == M :
return True return False
Sans le slicing def est_present ( L , M ) :
trouve = False #i n d i q u er a s i on a trouve ou non l e motif m = len ( M )
l = len ( L )
k = 0 #i n d i c e de parcours de L while not trouve and k < l :
i = 0 #i n d i c e de parcours de M fini = False
# a r r e t e r a l a boucle s i l e motif ne correspond pas à l a p a r t i e de L examinee
while not trouve and not fini : i f k+i <l :
i f i< m and L [ k+i ] == M [ i ] : i += 1
e l i f i == m :
trouve = True e l s e :
fini = True k += 1 return trouve
2014-2015 page 2 sur 12 TSVP
2◦) Ecrire une fonction qui recherche combien de fois le motif est présent dans la liste et renvoie les rang où celui-ci apparait.
On considèrera qu'un élément de la liste peut appartenir à plusieurs motifs.
Solution:
avec le slicing def est_present ( L , M ) :
m = len ( M ) l = len ( L ) k = 0
f o r i in range ( l−m+1) : i f L [ i : i+m ] == M :
return True return False
sans le slicing def nombre_rang_presence ( L , M ) :
m = len ( M ) l = len ( L )
k = 0 #i n d i c e de parcours de L nb = 0
rang = [ ]
while k+m <= l :
i = 0 #i n d i c e de parcours de M fini = False
while not fini : i f i == m :
fini = True rang . append ( k ) nb += 1
k +=1
e l i f L [ k+i ] == M [ i ] : i += 1
e l s e :
fini = True k += 1 return rang , nb
En une seule ligne ! def nombre_presence ( L , M ) :
return [ i f o r i in range ( len ( L )−len ( M ) +1) i f L [ i : i+len ( M ) ] == M ]
©Exercice 3: Liste et nombre
1◦) Ecrire une fonction qui donne la liste des chires d'un entiern.
Solution:
def liste ( N ) : L = [ ] while N>0:
u = N%10 N = N//10
L . append ( u ) # Les nombres de p e t i t s poids sont à gauche L . reverse ( ) # Pour remettre dans l ' ordre d ' é c r i t u r e
return L
2◦) Ecrire une fonction qui transforme une liste de chires en l'entier correspondant.
Solution:
def chiffre ( L ) :
# on suppose que l a l i s t e e s t dans l ' ordre de l ' é c r i t u r e . L . reverse ( )
N = 0
f o r i in range ( len ( L ) ) : N += L [ i ]∗10∗ ∗i return N
2014-2015 page 4 sur 12 TSVP
©Exercice 4: Un petit graphique
1◦) Tracer sur un même graphique la fonction sinus et ses développements limités d'ordres1,3,5.
Solution:
import numpy
from math import ∗
# On cr é e l e s v a l e u r s de x
listx = numpy . arange (−3 . 1 4 , 3 . 1 4 , . 1 ) def DLsin ( x , n ) :
#r e n v o i e l e dl de s i n à l ' ordre 2n+1 c a l c u l é en x S= xf o r i in range (1 , n ) :
S = S + (−1)∗∗i∗x∗ ∗(2∗i+1)/factorial (2∗i+1) return S
# remplit l a l i s t e pour l e graphe de s i n listsin =[sin ( x ) f o r x in listx ]
# remplit l a l i s t e pour l e graphe du DL de s i n à l ' ordre 2 i +1 listDLsin =[[ DLsin ( x , i ) f o r x in listx ] f o r i in range (3) ] graphSin = plt . plot ( listx , listsin )
plt . setp ( graphSin , linewidth = 5 , label=' s i n ', color=' pink ') marque = [ ' , ' , ' . ' , '+' , '∗',' o ']
#marker =1 2 3 etc e s t a u s s i reconnu f o r i in range ( 3) :
graphDLSin = plt . plot ( listx , listDLsin [ i ] ) s='DL '+ str (2∗i+1)
plt . setp ( graphDLSin , label=s , linestyle=' ' , marker=marque [ i ] , markevery=3,ms=8)
plt . title (' s i n et s e s DL ') plt . xlabel (' x ')
plt . axhline ( color=" black ") plt . axvline ( color=" black ") plt . legend ( loc=' upper l e f t ') plt . show ( )
4 3 2 1 0x 1 2 3 4
4 3 2 1 0 1 2 3
4 sin et ses DL
sinDL1 DL3DL5
2◦) Créer une fonction qui prend en argumentnet renvoie le graphique contenant la fonction sinus et ses développements limités d'ordre1, . . . ,2n+ 1
Solution:
listx = numpy . arange (−3 . 1 4 , 3 . 1 4 , . 1 ) listsin =[sin ( x ) f o r x in listx ] graphSin = plt . plot ( listx , listsin )
plt . setp ( graphSin , linewidth = 5 , label=' s i n ', color=' pink ') listDLsin =[[ DLsin ( x , i ) f o r x in listx ] f o r i in range ( n ) ] f o r i in range ( n ) :
graphDLSin = plt . plot ( listx , listDLsin [ i ] ) s='DL '+ str (2∗i+1)
plt . setp ( graphDLSin , label=s , linestyle='−') plt . title (' s i n et s e s DL ')
plt . xlabel (' x ')
plt . axhline ( color=" black ") plt . axvline ( color=" black ") plt . legend ( loc=' upper l e f t ') plt . show ( )
2014-2015 page 6 sur 12 TSVP
©Exercice 5: Une suite On considère la suite dénie par :
u0= 1, ∀n≥0, un+1= 1 (n+ 1)2
n
X
k=0
(nk+ 1)uk
1◦) Ecrire une fonction qui calcule l'élément d'indicende cette suite.
Solution:
def un_terme ( L , n ) :
#A p a r t i r de l a l i s t e des termes de l a s u i t e , c a l c u l e l e terme suivant
s = 0 .
f o r i in range ( n + 1) : s += ( n∗i+1)∗L [ i ] s = s / (( n+1)∗ ∗2)
L . append ( s ) def suite ( n ) :
# Calcul l a l i s t e des termes un à un . L =[1]
f o r i in range ( n ) : un_terme ( L , i ) return L
2◦) Placer sur un graphe les points(k, uk)pourk∈J0, nK.
Solution:
def graphe ( n ) :
ListX = range ( n+1) ListY = suite ( n ) plt . plot ( ListX , ListY ) plt . show ( )
©Exercice 6: Syracuse On réalise le procédé suivant :
âOn choisit un entiernsupérieur strictement à1. âSinest pair, on le divise par2.
âSinest impair, on le multiplie par3et on ajoute1. âOn recommence jusqu'à arriver à1.
Exemple :5−16−8−4−2−1
Une conjecture, non démontrée, arme qu'on arrive toujours à1.
1◦) Ecrire une fonction qui à partir d'un entiernrenvoie la liste des itérations et le nombre d'étapes pour arriver à1.
Pour5, on aura donc en sortie :[5,16,8,4,2,1],5
Solution:
import matplotlib . pyplot as plt def syracuse ( n ) :
itera = 0 L=[n ] while n>1:
itera +=1 i f n%2 == 0 :
n = n/2 e l s e:
n = 3∗n+1 L . append ( n ) return L , itera
2◦) Tracer un graphe qui trace le nombre d'itérations suivant le nombre de départ.
Solution:
def graphe_syracuse ( n ) : ListX = range ( n ) ListY = [ ]
f o r x in ListX :
( l , itera ) = syracuse ( x ) ListY . append ( itera )
plt . plot ( ListX , ListY , linestyle='−', marker=' o ') plt . show ( )
2014-2015 page 8 sur 12 TSVP
©Exercice 7: Parenthésage
On s'intéresse à des expressions contenant des parenthèses, et en particulier, aux expressions qui sont bien parenthésées : Pour cela, on va coder la suite des parenthèses dans une liste de la façon suivante :
âune parenthèse ouvrante est codée1. âune parenthèse fermante est codée−1.
Ainsi à l'expression :(a+b)∗(c+d)est associée :[1,−1,1,−1]. Remarque:
Soit une listeLde longueurldu type précédent, que représente
i
X
k=0
L[k]pouri∈J0, lJ? En déduire un test simple pour tester qu'une liste représente un bon parenthésage.
1◦) Ecrire une fonction est_valide qui prend en argument d'entrée une listeLet qui renvoieT ruesi la liste correspond à un bon parenthésage etF alsesinon.
Solution:
from time import time
import matplotlib . pyplot as plt ouv = 1
fer = −1
def est_valide ( L ) : m = len ( L ) compteur = 0 i = 0
while i< m and compteur >=0 :
#On s ' a rr ê te s i l e compteur devient né g a t i f ,
#c ' e s t à d i r e qu ' i l y a trop de fermantes compteur += L [ i ]
i += 1 i f i == m :
valide = ( compteur == 0)
#On d e r n i e r rang , i l faut que c e l a s o i t parfaitement é q u i l i b r é
e l s e :
valide = False return valide
2◦) On cherche à écrire toutes les listes possibles de longueur2nbien parenthésées.
2.a Ecrire toutes les listes de longueurs de2ncontenant des1et des−1.
Pour cela, remarquer que si on remplace−1par0on obtient la liste des chires d'un nombre écrit en binaire.
Solution:
â On écrit la décomposition d'un nombre en binaire (decompose(n)) â On remplace les 0 par des−1 d'une liste L (transforme(L))
â On utilise ce qui précède pour obtenir toutes les listes (il y a en a 22n). On prend soin de compléter les listes qui ne sont pas assez longues.
def decompose ( n ) : L =[]
while n>0:
u = n%2 n = n//2 L . append ( u ) return L
def transforme ( L ) : n = len ( L )
f o r i in range ( n ) : i f L [ i ] == 0 :
L [ i ] = −1
def toutes_les_expressions ( n ) : T =[]
f o r i in range (2∗ ∗(2∗n ) ) : D = decompose ( i ) s = len ( D )
F = [ 0 ]∗( 2∗n−s ) L=D+F
transforme ( L ) T . append ( L ) return T
2.b Ecrire une fonction liste_parenthésage qui prendnen argument et qui renvoie la liste de toutes les listes de longueurs2n bien parenthésées en sélectionner parmi toutes les listes celles qui sont bien parenthésées.
Solution:
def liste_parenthesage ( n ) :
T = toutes_les_expressions ( n ) Liste = [ ]
f o r L in T :
i f est_valide ( L ) :
Liste . append ( L )#On garde que c e l l e s qui conviennent return Liste
2014-2015 page 10 sur 12 TSVP
3◦) Une autre méthode : Remarque:
Une liste de longueur2nbien parenthésée est constituée de 1, Ld,−1, Lf
où
â 1est la parenthèse ouvrante initiale
â −1est la parenthèse fermant la parentèse initiale : elle se situe à la place2i+ 1aveci∈J0, nJ (avec une numérotation qui bien sur commence à0)
â Ldest une liste bien parenthésée de longueur2i(vide sii= 0)
â Lf est une liste bien parenthésée de longueur2n−2i−2(vide sii=n−1)
On va construire une listeT de longueurntelle queT[i]est la liste de toutes les listes bien parenthésées de longueur2i. Ainsi : â Pourn= 0,T = [[ ]]
â Pourn= 1,T = [[ ], [[1,−1]]]
â Pourn= 2,T = [[ ], [[1,−1]],[[1,1,−1,−1],[1,−1,1,−1]]]
3.a Ecrire une fonction liste_suivante qui prendT en argument et qui rajoute la ligne suivante.
Solution:
def liste_suivante ( T ) :
n = len ( T ) # On a dé j à l e s l i s t e s de longueurs 2n − 2 et on veut p a s s e r à 2n
L =[]
f o r i in range ( n ) : #cas où l a premi è re parenth è se se referme à l a place 2 i−1
f o r Ld in T [ i ] :
f o r Lf in T [ n−i−1]:
L . append ([1]+ Ld+ [−1] +Lf ) T . append ( L )
3.b Ecrire une liste_parenthesage_bis qui prendnen argument et qui renvoie la liste de toutes les listes de longueurs2nbien parenthésées.
Solution:
def liste_parenthesage_bis ( n ) : T = [ [ [ ] ] ]
f o r i in range ( n ) : liste_suivante ( T ) return T [ n ]
4◦) A l'aide de la fonction time du package time, faire un graphique qui compare le temps mis par les deux méthodes pourn∈J0,5K.
Tracer également le temps mis par la deuxième méthode uniquement pourn∈J0,15K.
Importer la fonction time from time import time
Solution:
def comparaison_temps ( n ) : L = [ [ ] , [ ] ]
fonc =[liste_parenthesage , liste_parenthesage_bis ] f o r i in range ( n ) :
f o r k in range ( 2) : t0 = time ( ) fonc [ k ] ( i )
L [ k ] . append ( time ( )−t0 ) plt . plot ( range ( n ) , L [ 0 ] )
plt . plot ( range ( n ) , L [ 1 ] ) plt . show ( )
return L def temps ( n ) :
L =[]
f o r i in range ( n ) : t0 = time ( )
liste_parenthesage_bis ( i ) L . append ( time ( )−t0 )
plt . plot ( range ( n ) , L ) plt . show ( )
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0
0.0000 0.0005 0.0010 0.0015 0.0020 0.0025 0.0030 0.0035 0.0040
0.0045 comparaison des 2 methodes
methode 1 methode 2
0 2 4 6 8 10 12 14
0 2 4 6 8 10
12 Deuxieme methode
2014-2015 page 12 sur 12 FIN