I Nombres premiers Question 1: recherche naïve On teste simplement la divisibilté éventuelle de l'entier n par tous les entiers p compris entre 2 et n-1. Le test retourne 1 si l'entier est premis. > estPremier:=proc(n) local test, k; test:=1; for k from 2 to n-1 do if n mod k =0 then test:= 0; fi; od; test; end: Question 2: liste des nombres premiers On teste la primalité de tous les entiers de 2 à n et on conserve dans un tableau ceux qui sont premiers. La variable compt est augementée de 1 à chaque rencontre d'un nombre premier. > petitsPremiers:=proc(n) local k, compt; global premier; compt:=0; for k from 2 to n do if estPremier(k)=1 then compt:=compt +1; premier[compt]:=k; fi;od; compt; end: > Z:=petitsPremiers(100): > seq(premier[r],r=1..Z); 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 Question 3: seconde liste en limitant les calculs Le test de primalité est plus rapide car, pour un entier n donné, si on a deux diviseurs p et q tels que pq=n, p>1, q>1, il y a obligatoiremnt un des deux entiers inférieur ou égal à racine carrée de n. Il n'est donc pas nécessaire de faire les tests de divisibilité pour p > racine carrée (n). > petitsPremiers2:=proc(n) local k,test,r,compt; global premier; premier[1]:=2;k:=3; compt:=1;if n > 2 then while k <= n do test:=1; r:=3;while r^2 <= k do if k mod r = 0 then test:= 0 fi; r:=r+2;od; if test=1 then compt:=compt+1; premier[compt]:=k;fi; k:=k+2; od; fi; compt; end: > Z:=petitsPremiers2(500): > seq(premier[i],i=1..Z); 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, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 Question 4: Crible d'Erathostène La procédure proposée suit exactement le principe du crible d'Erathostène. On met en évidence les multiples d'un entier r donné (qui ne sont donc pas premiers) en affectant la valeur 1 à Tab[ir]. > petitsPremiers3:=proc(n) local Tab,k,i,r,s ; global premier; Tab:=array[2..n];for k from 2 to n do Tab[k]:=0;od; # initialisation du tableau i:=1; while i <= n do s:=i+1; while Tab[s]=1 do s:=s+1;od; # Recherche de l'entier premier suivant i i:=s; r:=2; while i*r<= n do Tab[i*r]:=1; r:=r+1;od; # suppression des multiples de i od; s:=1; for k from 2 to n do if Tab[k]=0 then premier[s]:=k; s:=s+1;fi;od; s-1;end: > Z:=petitsPremiers3(200): > seq(premier[k],k=1..Z); 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, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199 Question 5: Factorisation d'un entier Mise en place de l'algorithme proposé dans l'énoncé. > factoriser:=proc(n) local N,i,j,p,m; global premier, facteur; petitsPremiers3(n); m:=n; i:=0;j:=0; while m > 1 do i:=i+1; p:=premier[i]; while(irem(m,p)=0) do j:=j+1; facteur[j]:=p;m:=iquo(m,p); od; od; j;end: > factoriser(2520): > seq(facteur[i],i=1..7);2, 2, 2, 3, 3, 5, 7 Question 6: factoriser sans table de nombres premiers La procédure reprend exactement la calcul fait "à la main" pour décomposer un entier en facteurs premiers. > factoriser2:=proc(n) local m,j,q; global facteur; m:=n;j:=0; while (irem(m,2)=0) do j:=j+1; m:=iquo(m,2); facteur[j]:=2; od; # On effectue les divisions successives de n par 2 q:=1; while m>1 do q:=q+2; if q^2> m then j:=j+1; facteur[j]:=m;m:=1; else while ( irem (m,q)=0) do j:=j+1; facteur[j]:=q; m:=iquo(m,q); od;fi; od; j; end: > Z:=factoriser2(2205336): > seq(facteur[k],k=1..Z); 2, 2, 2, 3, 7, 13127 II Reconnaître les puissances Question 7: comptage des multiplicités On reprend l'algorithme précédent en comptant le nombre de répétitions de chaque facteur premier. > calculerAlpha:=proc(n) local m,k,q,s; global alpha; m:=n; s:=0; k:=0; while irem(m,2)=0 do s:=s+1; m:=iquo(m,2); od; if s> 0 then k:=k+1; alpha[k]:=s; fi; # recherche des puissances éventuelles de 2 q:=1; while m>1 do q:=q+2; if q^2 > m then k:=k+1; alpha[k]:=1; m:=1; else s:=0; while(irem(m,q)=0) do s:=s+1;m:=iquo(m,q); od; if s>0 then k:=k+1; alpha[k]:=s; fi; fi; od; k; end: > Z:=calculerAlpha(14286*9*25):seq(alpha[k],k=1..Z); 1, 3, 2, 1 Question 8: Recherche des nombres de la forme a^b On détermine les multiplicités des facteurs premiers de n et on vérifie si elles sont ou non multiples de b. > estPuissance:=proc(n,b) local N, i, test ; global alpha; N:=calculerAlpha(n); i:=1; while i<=N and ( irem(alpha[i],b)=0) do i:=i+1; od; if i>N then test:=1 else test:=0; fi; test; end: > estPuissance (1016255020032,5); 1 Question 9: Recherche de carrés (b=2) Soit n un entier donné, n>1. On peut rechercher le plus grand entier p tel que p^2 soit inférieur ou égal à n. Puis on regarde si p^2=n. > estCarre:= proc(n) local i,test; i:=2; while i^2<=n do i:=i+1;od; if (i-1)^2=n then test:=1 else test:=0; fi; test; end; estCarre := proc(n) local i, test; i := 2; while i^2 ≤ n do i := i + 1 end do ; if ( i − 1 )^2 = n then test := 1 else test := 0 end if ; test end proc > estCarre(225); 1 III. Nombres de Carmichaël Question 10: Tester si un entier est un nombre de Carmichael On effectue la factorisation de n et on vérifie la condition de définition. On reprend l'algorithme vu en question 6. > estCarmichael:=proc(c) local test,m,q; test:=1; m:=c; if irem (n,2)=0 then test:=0 fi; q:=1; while (m>1) and test =1 do q:=q+2; if q^2 > m then if m=c then test :=0 else if (irem(c-1,m-1)<>0) then test:=0 fi; m:=1;fi; elif irem(m,q)=0 then m:=iquo(m,q); if irem(m,q)=0 or (irem(c-1,q-1)<>0) then test:=0; fi: fi; od; test; end: > estCarmichael(1105); 1 Question 11: recherche des nombres de Carmichael produit de trois facteurs premiers. On suit les indications de l'énoncé. On détermine les nombres premiers inférieurs à n, on effectue les produits de trois premiers distincts et on vérifie si on a un nombre de Carmichael. > calculerCarmichael3:=proc(n) local Z,s,i,j,k ,C,p,q,r; global premier, carmichael; Z:=petitsPremiers2(n); s:=0; for i from 2 to Z-2 do p:=premier[i]; for j from i+1 to Z-1 do q:=premier[j]; for k from j+1 to Z do r:=premier[k]; C:=p*q*r; if C<=n and irem(C-1,p-1)=0 and irem(C-1,q-1)=0 and irem(C-1,r-1)=0 then s:=s+1; carmichael[s]:=C; fi; od;od;od; s;end: > Z:=calculerCarmichael3(3000); Z := 5 > seq(carmichael[k],k=1..Z); 561, 1105, 2465, 1729, 2821 Question 12: calcul avec criblage > calculerCarmichael:=proc(n) local Z,t,i,k,pas,p ; global premier, carmichael; Z:=petitsPremiers2(floor(sqrt(n))-1); for i from 1 to n do t[i]:=i; od; for k from 2 to Z do p:=premier[k]; pas:=p*(p-1); i:=p+pas; while i<= n do t[i]:=iquo(t[i],p); i:=i+pas; od; od; k:=0; for i from 2 to n do if t[i]=1 then k:=k+1; carmichael[k]:=i; fi; od; k; end: > H:=calculerCarmichael(100000); H := 16 > seq(carmichael[k],k=1..H); 561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973, 75361 > ifactor(63973); ( 7 ) ( 13 ) ( 19 ) ( 37 ) > ifactor(63972); ( 2 )2 ( 3 )2 ( 1777 )