TD7 Calcul numérique (avec Maple) Licence 1 SMS Math Info, Math Physique 2005-2006 Liste et liste de liste Question 1 : On appel nombres premiers jumeaux les couples (p, p+2) où p et p+2 sont premiers. 1- Ecrire une procédure, que l’on nommera twin, qui prend comme argument un entier x et qui retourne la liste de couple (liste de liste) de nombre premiers jumeaux inférieur ou égal à x. 2- Ecrire un procédure qui prend en paramètre une liste de couple (liste de liste) de nombre premiers jumeaux et qui l’affiche. restart; #Définition de la procédure twin twin := proc(x::posint) local i :: integer, suite :: exprseq; suite := NULL; for i from 1 to x-2 do if (isprime(i) and isprime(i+2)) then suite := suite, [i,i+2]; fi: od: return [suite]; end: N := 100 Couple Couple Couple Couple Couple Couple Couple Couple 1 2 3 4 5 6 7 8 de de de de de de de de jumeaux jumeaux jumeaux jumeaux jumeaux jumeaux jumeaux jumeaux : : : : : : : : (3, 5) (5, 7) (11, 13) (17, 19) (29, 31) (41, 43) (59, 61) (71, 73) #Définition de la procédure d'affichage afficheLstLst := proc (lstlst::list) local i::posint; for i from 1 to nops(lstlst) do printf("Couple %d de jumeaux : (%d, %d)\n", i, lstlst[i][1], lstlst[i][2]); od: end: #Appel de la procédure N:=100; afficheLstLst(twin(N)); Question 2 : Un nombre parfait est un nombre égal à la somme de tous ses diviseurs, par exemple 6 = 1+2+3. a) Ecrire une procédure qui détermine si un nombre entier positif donné est parfait ou non. La procédure prendra en paramètre le nombre n et retournera vrai si ce nombre est parfait. Pour tester la “divisibilité” de a par b, on utilisera l’expression booléenne suivante : a mod b = 0 ; Remarque : la commande mod donne le reste de la division euclidienne de a par b. b) Ecrire une procédure qui retourne la liste des nombres parfait sur l’intervalle [1, 1000]. #Procédure retournant vrai si le nombre n est parfait parfait := proc(n::posint) local somme::integer, i ::integer; somme := 0; for i from 1 to n-1 do if ((n mod i) = 0) then somme := somme+i; fi: od: return (evalb(somme = n)); end: #Procédure retournant la liste des nombres parfaits sur [1..N] listeNbParfait := proc(BSup::posint) local i ::integer, suite ::exprseq; suite:=NULL; for i from 1 to BSup do if (parfait(i)) then suite := suite, i; fi: od: return [suite]; end: #Appel de la procédure listeNbParfait(1000); Question 3 : a) Ecrire une procédure qui retourne le nombre de nombres premier sur un intervalle [a, b] b) Ecrire une procédure qui comptabilise le nombre de nombre premier sur les intervalle [0, 999], [1000, 1999], … . Cette procédure retournera une liste de couple (liste de liste) ou chaque couple est : - le numéro d’intervalle, - et l’entier comptabilisant le nombre de nombre premier sur l’intervalle. c) Ecrire la procédure prend en paramètre la liste de liste et qui affiche sur un graphique les points. > nbNbPremier := proc(binf::integer, bsup::integer) local somme::integer, i ::integer; somme:=0; for i from binf to bsup do if (isprime(i)) then somme:=somme+1; fi: od: return somme; end: > comptabiliseParIntervalle := proc(nbIntervalle::posint, taille::posint) local i ::integer, suite::exprseq; suite:=NULL; for i from 0 to nbIntervalle-1 do suite := suite, [i, nbNbPremier(i*taille, i*taille+taille-1)]; od: return [suite]; end: > listePoint:=comptabiliseParIntervalle(100,1000); > plot(listePoint, style=point); Question 4 : Le crible d’Erathostène est un algorithme permettant d’établir la liste des nombres premiers inférieurs à un entier donné n. Algorithme : A partir de la liste L des nombres entiers allant de 1 à n, on élimine itérativement les multiples de 2 (sauf 2), puis les multiples de 3 (sauf 3), etc. jusqu’aux multiples de n-1. Nous allons mettre en œuvre cet algorithme en utilisant MAPLE comme langage de programmation. Pour ce faire, nous considérons une liste MAPLE de n booléen initialement tous égaux à true. L’élimination des nombres multiples (évoqué précédemment) consiste à affecter les booléens correspondant à false. A la fin de l’algorithme seuls les nombres premiers seront marqués par un true. a) Ecrire une fonction crible qui retourne un tableau de n booléens tels que l’on ai vrai dans chaque case i du tableau si le nombre i est premier. Il faut bien entendu utiliser l’algorithme du Crible d’Erathostène. b) Ecrire une fonction qui prend en entrée le tableau précédent et affiche les nombres premiers (à partir du tableau). > buildTab := proc(n::posint) local tab::array, i ::integer; tab := array(1..n); for i from 1 to n do tab[i]:=true; od: return tab; end: crible := proc(n::posint) local tab::array, i ::integer, val::integer; #Construction du tableau initial tab := buildTab(n); for val from 2 to n do for i from val+1 to n do if ((i mod val) = 0) then tab[i] := false; fi od: od: return tab; end: > afficheTab := proc(tab::array) #Tableau de booléen en entrée local i ::integer, taille::integer, lst ::list; lst := convert(tab, 'list'); taille := nops(lst); #Le nops sur tab ne donnait 1 ?! for i from 1 to taille do if (tab[i]) then printf("%d, ", i); fi: od: printf("\n"); end: > tab := crible(100): afficheTab(tab); 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,