DS IPT n°2/22
Nicolas CHIREUX / Sylvain GAILLARD
On veillera à soigner la présentation, en particulier les indentations pour les programmes proposés :
toute indétermination due à une présentation laissant à désirer sera sanctionnée en étant considérée
comme fausse.
1 Analyse de code
1.1 Exercice 1
1. /1 A chaque itération la fonction stocke le résultat de la reste de la division de k par 3 et remplace k par son
quotient par 3. Nous avons donc pour le résultat de mystere(101) la liste [2, 0, 2, 0, 1]
2. /0.5 le tableau est la décomposition de n en base 3 : [a0 , . . . , am ] où n = a0 30 + a1 31 + . . . + am 3m
3. /1 il y a deux affections au départ puis à chaque tour de boucle 2 opérations élémentaire % et // et 2 affectations.
Sachant qu’il y aura ⌊log3 (n)⌋ + 1 itérations, il y a donc 2 + 4 ∗ (⌊log3 (n)⌋ + 1) opérations. La complexité est donc
en Θ(log(n))
1.2 Exercice 2
/1.5
• A la première itération le calcul de 7 + mystere2(7, 3) est en attente de mystere2(7, 3).
• Puis le calcul de 7 + mystere2(7, 2) est en attente de mystere2(7, 2).
• Puis le calcul de 7 + mystere2(7, 1) est en attente de mystere2(7, 1).
• Puis le calcul de 7 + mystere2(7, 0) est en attente de mystere2(7, 0) qui correspond ensuite au cas terminal donc
la fonction retourne 0.
• 7 + mystere2(7, 0) vaut alors 7 + 0 = 7.
• 7 + mystere2(7, 1) vaut alors 7 + 7 = 14.
• 7 + mystere2(7, 2) vaut alors 14 + 7 = 21.
• 7 + mystere2(7, 3) vaut alors 21 + 7 = 28.
Le résultat est donc 28. Cette fonction récursive multiplie n par p.
2 Récursivité
1. /1 Soit la suite définie par :
si n < 2
1
un =
sinon3.un−1 + un−2
(1)
Écrire une fonction récursive Suite_r(n) permettant de calculer le nieme terme de la suite.
1 def Suite_r ( n):
2 i f n <= 2:
3 return 1
4 return 3* S u i t e _ r ( n -1) + S u i t e _ r ( n -2)
2. /1 Rendre récursive la fonction suivante :
1 def somme (L) :
2 s = 0
3 for val in L :
4 s += val
5 return s
La version récursive est la suivante :
1 def somme_r ( L):
2 i f len ( L ) = = 0 :
3 return 0
4 else :
5 return L [ 0 ] + s o m m e _ r ( L [ 1 : ] )
1
3. /2 Soit un tableau T de N entiers, écrire une fonction récursive simple maximum_r(T ) permettant de déterminer
le maximum du tableau en se basant sur le principe de la recherche dichotomique.
1 def maximum_r (T ):
2 i f len ( T ) == 1:
3 return T [0]
4 # p r i n c i p e de la r e c h e r c h e dichotomique
5 m = len ( T ) //2
6 m a x 1 = m a x i m u m _ r ( T [: m ])
7 m a x 2 = m a x i m u m _ r ( T [ m :])
8 i f max1 > max2 :
9 return m a x 1
10 return m a x 2
3 Quelques jeux
3.1 Pile ou face
1. /1 La réponse est :
1 def face ( N):
2 n b r e =0
3 for i in range ( N ) :
4 i f r a n d i n t (0 ,1) :
5 n b r e +=1
6 return n b r e
2. /1 La réponse est :
1 def moyenne (M ,N ):
2 moy =0
3 for i in range ( M ) :
4 moy += f a c e ( N )
5 return ( moy / M )
Le résultat attendu est N/2 étant donné que les probabiltés des tirages sont égales à 1/2.
3.2 Jeu de dé
1. /1 La réponse est :
1 def gain ( alpha ) :
2 a , b = r a n d i n t (1 ,6) , r a n d i n t (1 ,6)
3 i f a>b:
4 return a - b
5 else :
6 return - a l p h a *( b - a +1)
2. /1 La réponse est :
1 def g a i n m o y e n ( alpha , N ) :
2 moy =0
3 for i in range ( N ) :
4 moy += g a i n ( a l p h a )
5 return moy / N
4 Décomposition sur la base factorielle
1. /2 La réponse est :
1 def factorielle (n) :
2 i f n <=1:
3 return 1
4 else :
5 return n * f a c t o r i e l l e ( n -1)
6
7 def decode (s ):
8 n b r e =0
9 for i in range ( len ( s ) ) :
10 n b r e += s [ i ]* f a c t o r i e l l e ( i )
11 return ( n b r e )
Optimisation Pour décoder l’expression d’un nombre décomposé sur la base factorielle, il suffit de maintenir
les invariants : uk = k! et vk = ak k! + . . . + a1 1! + a0. Ceux-ci se définissent par les relations : u0 = 1, v0 = a0 et
uk+1 = (k + 1)uk , vk+1 = vk + ak+1 uk+1 .
2
1 def decode (s ):
2 u , v = 1 , s [0]
3 for k in range (1 , len ( s ) ) :
4 u = u * k
5 v = v + u * s[k]
6 return v
2. /0.5 a0 = 0 puisque a0 ∈ [0, 1[
3. /2 Pour tout i ≥ 2, i! est divisible par 2 donc k − a1 est pair. Alors a1 = k mod 2
1
Pour tout i ≥ 3, i! est divisible par 3! = 6 donc 2!
(k − a2 2! − a1 1! − a0 ) est divisible par 3. Alors
1
a2 =
2!
(k − a0 − a1 .1!) mod 3 (2)
1
En généralisant k − j=0 aj j! ≡ ai mod (i + 1) Donc
Pi−1
i!
i−1
1
(3)
X
ai = k− aj .j! mod (i + 1)
i! j=0
4. /1.5 La réponse est :
1 def code (n , k):
2 a = [0]
3 for i in range (1 , n ) :
4 a . a p p e n d ( k % ( i +1) )
5 k = k // ( i +1)
6 return a
Vu que a0 =0, à la première itération comme i = 1, a1 = k mod 2 et k = k//2 soit
(n − 1)! (n − 2)! 3!
k = an−1 + an−2 + . . . + a3 + a2
2 2 2
A la deuxième itération comme i = 2, a2 = k mod 3 et k = k//3 soit
(n − 1)! (n − 2)! 4!
k = an−1 + an−2 + . . . + a4 + a3
3! 3! 3!
et ainsi de suite.
5. Application à la génération de permutations /3
La réponse est :
1 def permutation (n , k) :
2 a = code (n , k)
3 L = [ i for i in range ( n ) ]
4 s i g m a = []
5 for i in range ( n ) :
6 sigma . append ( L[a [n -i -1]])
7 del L [ a [ n - i - 1 ] ]
8 return s i g m a