PSI* PSI Informatique Pour Tous, Lycée Kléber Elements de correction du TP 1 9 octobre 2014 Exercice 1 Rappels : Une chaîne est une suite éventuellement vide non modifiable de caractères : chaine = Je suis heureux d etre en cours chaine = "Je suis heureux d etre en cours" chaine = """Je suis heureux d etre en cours""" Une liste list est suite éventuellement modifiable de données numérotées de 0 à la longueur de la liste -1. Un tuple est une suite éventuellement vide non modifiable de données (éléments d un produit cartésien d ensembles). Un ensemble (set) est une collection éventuellement vide modifiable de données sans ordre défini et sans doublons (l ordre est choisi par l interpréteur). Un dictionnaire (dict) est une collection éventuellement vide modifiable d objets indexés par des objets de n importe quel type (objet : index) sans ordre défini et sans doublons d objets. Par exemple on peut associer la fréquence des lettres aux lettres de la chaine précédente : dico= { J :1, e :6, s :3, u :4, i :1, h :1, r : 3, x :1, d :1, t :1, n :1, c :1, o :1 } Utiliser la commande help() (par exemple help(ord)), pour voir le fonctionnement des primitives données dans l énoncé. 1. La primitive isinstance prend en argument un objet et une classe et renvoie True si l objet appartient à la classe donnée, False sinon. 2. Attention d effectuer une division dans les flottants : def s(n): return sum(float(len(str(k)))/(k*(k+1)) for k in range(1, n)) for i in range(1, 8): print(s(10**i)) La série converge vers 10 9. 3. De la même façon : def sigma(n): return sum(1./(k**2) for k in range(1,n) if 9 not in str(k)) On peut afficher des valeurs jusqu à obtenir une différence inférieure à une précision donnée entre des termes consécutfifs. Exercice 2 1. 1
2. q/p renvoie le couple (quotient, reste) de la division euclidienne des polynômes. 3. On obtient la base canonique de R 30 [X]. 4. On utilise la méthode integ def scalaire(p,q): pq = p*q PQ = pq.integ() primitive de p*q qui s annule en 0 return(pq(1.0)-pq(-1.0)) def norme(p): return(math.sqrt(scalaire(p,p))) 5. legendre = [] legendre.append(cano[0]/norme(cano[0])) for i in range(1,n+1): q = cano[i] for j in range(i): q = q - scalaire(cano[i],legendre[j])*legendre[j] legendre.append(q/norme(q)) Exercice 3 1. def lignes(m): return(len(m)) def cols(m): return(len(m[0])) 2. from copy import deepcopy def echange(m,i,j): S=deepcopy(M) S[i],S[j]=M[j],M[i] return(s) 3. def matrice_identite(n): M=[] L=[] for j in range(n): L.append(0) for i in range(n): M.append(deepcopy(L)) for i in range(n): for j in range(n): if i==j: M[i][j]=1 return(m) Ou bien def unite(n): return[[1 if i==j else 0 for j in range(n)] for i in range(n)] 4. 5. def GJ(M): U=matrice_identite(len(M)) return[m[i]+u[i] for i in range(lignes(m))] 6. def comb_ligne(ki,kj,m,i,j): S=deepcopy(M) Li=[ki*x for x in M[i]] Lj=[kj*x for x in M[j]] S[j]=[Li[k]+Lj[k] for k in range(cols(m))] return S 2
7. >>> S=GJ(M) >>> S=comb_ligne(0,0.5,S,0,0) >>> S=comb_ligne(-3,1,S,0,1) >>> S=comb_ligne(-4,1,S,0,2) >>> S=comb_ligne(0,2./3.,S,0,1) >>> S=comb_ligne(-0.5,1,S,1,0) >>> S=comb_ligne(-3,1,S,1,2) >>> S=comb_ligne(0,0.25,S,0,2) >>> S=comb_ligne(7./3.,1,S,2,0) >>> S=comb_ligne(-2./3.,1,S,2,1) >>> def JG(T): return[t[i][len(t):] for i in range(lignes(t))] >>> T=JG(S) >>> T [[1.5833333333333335, -1.5, 0.5833333333333334], [-1.1666666666666667, 1.0, -0.16666666666 >>> def affiche(m): for i in range(lignes(m)): print(m[i]) >>> affiche(t) [1.5833333333333335, -1.5, 0.5833333333333334] [-1.1666666666666667, 1.0, -0.16666666666666666] [0.25, -0.5, 0.25] [[1.5833333333333335, -1.5, 0.5833333333333334], [-1.1666666666666667, 1.0, -0.16666666666 8. >>> def inv_gauss(t): if lignes(t)!= cols(t): raise ExceprionMatrice("Cette matrice n est pas carrée") S=GJ(T) for NoColonne in range(lignes(t)): NoLigne=NoColonne while S[NoLigne][NoColonne] == 0: if NoLigne == len(t)-1: raise ExceptionMatrice("Cette matrice n est pas inversible") NoLigne += 1 S=echange(S,NoLigne,NoColonne) #On place l élément non nul sur la diagonale pivot=s[nocolonne][nocolonne] S=comb_ligne(0,float(1)/float(pivot),S,0,NoColonne) #On fait appara^ıtre un 1 E=set([k for k in range(lignes(t))]) - set([nocolonne]) # set permet la soustraction d ensembles for k in E: S=comb_ligne(-S[k][NoColonne],1,S,NoColonne,k) return JG(S) >>> M [[2, 1, -4], [3, 3, -5], [4, 5, -2]] >>> inv_gauss(m) 9. def det_gauss(t): if lignes(t)!= cols(t): raise ExceptionMatrice("cette matrice n est pas carrée") S=deepcopy(T) 3
i=1 for NoColonne in range(lignes(t)): NoLigne=NoColonne while (S[NoLigne][NoColonne]==0): if NoLigne == len(t)-1: return(0) NoLigne += 1 S=echange(S,NoLigne,NoColonne) i *= -1 #l échange multiplie le déterminant par -1 pivot=s[nocolonne][nocolonne] for k in range(noligne +1, len(t)): S=comb_ligne(-S[k][NoColonne],pivot,S,NoColonne,k) i *= -S[NoColonne][NoColonne] #la combinaison modifie le déterminant d=1 #initialisation du produit for k in range(lignes(s)): d *= S[k][k] #produit des termes diagonaux return (d/i) Exercice 4 1. def code(chaine): return([ord(x)-ord( @ ) for x in chaine]) 2. def decode(liste): chaine= for x in liste: chaine += chr( x+ ord( @ )) return(chaine) 3. def transpose(m): return[[m[i][j] for i in range(lignes(m))] for j in range(cols(m))] def paquets(l): i=0 J=[] while i+2 <len(l): J+=[[x for x in L[i:i+3]]] i +=3 if i == len(l)-1: J+=[[L[i],0,0]] if i == len(l)-2: J+=[[L[i],L[i+1],0]] return(transpose(j)) 4. def coeff_modulo(m,p): #retourne la matrice M avec coefficients modulo p return([[m[i][j] %p for j in range(cols(m))]for i in range(lignes(m))]) def mprod(a,b): if cols(a)!= lignes(b): return "les tailles ne sont pas compatibles" else: C=[[0 for i in range(cols(b))] for j in range(lignes(a))] for i in range(lignes(a)): for j in range(cols(b)): for k in range(lignes(b)): C[i][j]+=A[i][k]*B[k][j] return C 4
L=code( JE@SUIS@LA@PLUS@FORTE@EN@PYTHON ) J=paquets(L) A=[[1,22,25],[0,25,1],[25,3,1]] matcode=coeff_modulo(mprod(a,j),27) def mat_list(m): #convertit M en une liste L=[] for i in range(lignes(m)): L+=M[i] return L message_crypte=decode(mat_list(transpose(coeff_modulo(mprod(a,j),27)))) >>> message_crypte LQVDUGVLAWPNDDDUCFPSBADBETSDZZN@Z On peut vérifier que tout fonctionne en décodant ce message : LL=code(message_crypte) #crée la liste avec le message crypté crypte=paquets(ll) B=[[10, 2, 18], [4, 6, 2], [8, 13, 4]] #B est l inverse de A #crée la matrice de trois lignes associée clarifie=coeff_modulo(mprod(b,crypte),27) #utilise la matrice B inverse de A de décodage liste_clarifie=mat_list(transpose(clarifie)) #transforme le message en liste message_decode=decode(liste_clarifie) #pour rendre le message lisible avec des lettres >>> message_decode JE@SUIS@LA@PLUS@FORTE@EN@PYTHON@@ 5. La récompense : >>> messagecrypte2= NQR@SZEIMFX@WIZDLJQSQSBCJDBSMLKBNIWLE@Q >>> LL=code(messagecrypte2) >>> crypte=paquets(ll) >>> clarifie=coeff_modulo(mprod(b,crypte),27) >>> liste_clarifie=mat_list(transpose(clarifie)) >>> message_decode2=decode(liste_clarifie) >>> message_decode2 LE@TD@EST@FINI@A@LA@SEMAINE@PROCHAINE@@ 5