I Nombres premiers Question 1: recherche naïve Question 2: liste

publicité
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 )
Téléchargement