Spirale d'Ulam.

Cette page fait suite à une demande sur la liste AmiTeX. Le nombre de départ est paramétrable à la ligne

k:=41

En changeant le 15 de la ligne

for l=1 upto 15:

on augmente ou on diminue la longueur de la spirale.

spiraleulam.mp [ source brut ]

 prologues:=2;
 input TEX;
 
Conversion au format PDF de spiraleulam.1
 beginfig(1);
 k:=41;
 label(TEX(""&decimal(k)&""),(0,0));
 pair ptd;
 ptd:=(0,0);
 u:=8mm;
 for l=1 upto 15:
   if (l mod 2)=1:
     for j=1 upto l:
       k:=k+1;
       label(TEX(""&decimal(k)&""),ptd+u*(0,j));
     endfor;
     ptd:=ptd+u*(0,l);
     for j=1 upto l:
       k:=k+1;
       label(TEX(""&decimal(k)&""),ptd+u*(j,0));
     endfor;
     ptd:=ptd+u*(l,0);
   fi;
   if (l mod 2)=0:
     for j=1 upto l:
       k:=k+1;
       label(TEX(""&decimal(k)&""),ptd+u*(0,-j));
     endfor;
     ptd:=ptd+u*(0,-l);
     for j=1 upto l:
       k:=k+1;
       label(TEX(""&decimal(k)&""),ptd+u*(-j,0));
     endfor;
     ptd:=ptd+u*(-l,0);
   fi;
 endfor;
 endfig;
 end
 

Cette spirale peut être également construite en indiquant que les nombres premiers.

spiulam2.mp [ source brut ]

 prologues:=2;
 
 vardef pgcd(expr A,B) = 
     save a,b,r;
     numeric a,b,r;
     a := A; b := B;
     forever: 
         r := a mod b;
         a := b; b := r;
         exitunless r > 0;
     endfor;
     a
 enddef;
 
 vardef prem(expr P)=
   boolean reponse;
   reponse=false;
   numeric div;
   div=0;
   if P=1:
     div:=1;
   else:
     for g=2 upto P-1:
       if (pgcd(P,g)<>1):
 	div:=div+1;
       fi;
     endfor;
   fi;
   if div=0:
     reponse:=true;
   fi;
   reponse
 enddef;
 
 vardef ulam(expr nb,pas)=
   save $;
   picture $;
   $=image(
     if prem(nb)=true:
       label(TEX(""&decimal(nb)&""),(0,0));
     else:
       label(btex $\star$ etex,(0,0));
     fi;
     pair ptd;
     ptd=(0,0);
     u:=8mm;
     k:=nb;
     for l=1 upto pas:
       if (l mod 2)=1:
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    label(TEX(""&decimal(k)&""),ptd+u*(0,j));
 	  else:
 	    label(btex $\star$ etex,ptd+u*(0,j));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(0,l);
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    label(TEX(""&decimal(k)&""),ptd+u*(j,0));
 	  else:
 	    label(btex $\star$ etex,ptd+u*(j,0));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(l,0);
       fi;
       if (l mod 2)=0:
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    label(TEX(""&decimal(k)&""),ptd+u*(0,-j));
 	  else:
 	    label(btex $\star$ etex,ptd+u*(0,-j));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(0,-l);
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    label(TEX(""&decimal(k)&""),ptd+u*(-j,0));
 	  else:
 	    label(btex $\star$ etex,ptd+u*(-j,0));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(-l,0);
       fi;
     endfor;
     );
   $
 enddef;
 
 input TEX;
 
 
Conversion au format PDF de spiulam2.1
 beginfig(1);
   draw ulam(1,10);
 endfig;
 
 
Conversion au format PDF de spiulam2.2
 beginfig(2);
   draw ulam(41,15);
 endfig;
 end
 

Une légère amélioration : la coloration des nombres premiers et du nombre de départ. J'ai ajouté également, en indice, le nombre de diviseurs autre que 1 et le nombre lui-même.

spiulam3.mp [ source brut ]

 vardef pgcd(expr A,B) = 
     save a,b,r;
     numeric a,b,r;
     a := A; b := B;
     forever: 
         r := a mod b;
         a := b; b := r;
         exitunless r > 0;
     endfor;
     a
 enddef;
 
 vardef prem(expr P)=
   boolean reponse;
   reponse=false;
   numeric Div,DIV;%DIV pour compter le nombre de diviseurs
   Div=0;DIV=0;
   if P=1:
     Div:=1;
   else:
     for g=2 upto P-1:
       if (pgcd(P,g)<>1):
 	Div:=Div+1;
 	if (P mod g)=0:
 	  DIV:=DIV+1;
 	fi;
       fi;
     endfor;
   fi;
   if Div=0:
     reponse:=true;
   fi;
   reponse
 enddef;
 
 vardef ulam(expr nb,pas)=
   save $;
   picture $;
   $=image(
     if prem(nb)=true:
       fill fullcircle scaled 7mm withcolor 0.9green;
       label(TEX(""&decimal(nb)&""),(0,0));
     else:
       label(TEX(""&decimal(nb)&""),(0,0)) withcolor 0.9green;
     fi;
     pair ptd;
     ptd=(0,0);
     u:=8mm;
     k:=nb;
     for l=1 upto pas:
       if (l mod 2)=1:
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    fill fullcircle scaled 7mm shifted (ptd+u*(0,j)) withcolor 0.9white;
 	    label(TEX(""&decimal(k)&""),ptd+u*(0,j));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),ptd+u*(0,j));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(0,l);
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    fill fullcircle scaled 7mm shifted (ptd+u*(j,0)) withcolor 0.9white;
 	    label(TEX(""&decimal(k)&""),ptd+u*(j,0));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),ptd+u*(j,0));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(l,0);
       fi;
       if (l mod 2)=0:
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    fill fullcircle scaled 7mm shifted (ptd+u*(0,-j)) withcolor 0.9white;
 	    label(TEX(""&decimal(k)&""),ptd+u*(0,-j));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),ptd+u*(0,-j));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(0,-l);
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    fill fullcircle scaled 7mm shifted (ptd+u*(-j,0)) withcolor 0.9white;
 	    label(TEX(""&decimal(k)&""),ptd+u*(-j,0));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),ptd+u*(-j,0));
 	  fi;
 	endfor;
 	ptd:=ptd+u*(-l,0);
       fi;
     endfor;
     );
   $
 enddef;
 
 input TEX;
 
 
Conversion au format PDF de spiulam3.1
 beginfig(1);
   draw ulam(1,6);
 endfig;
 
 
Conversion au format PDF de spiulam3.2
 beginfig(2);
   draw ulam(41,15);
 endfig;
 end
 

Suite à un exemple de Guillaume Conan, une représentation en 3D

spiulam4.mp [ source brut ]

 input geometriesyr16;
 input TEX;
 
 vardef pgcd(expr A,B) = 
     save a,b,r;
     numeric a,b,r;
     a := A; b := B;
     forever: 
         r := a mod b;
         a := b; b := r;
         exitunless r > 0;
     endfor;
     a
 enddef;
 
 vardef prem(expr P)=
   boolean reponse;
   reponse=false;
   numeric Div,DIV;%DIV pour compter le nombre de diviseurs
   Div=0;DIV=0;
   if P=1:
     Div:=1;
   else:
     for g=2 upto P-1:
       if (pgcd(P,g)<>1):
 	Div:=Div+1;
 	if (P mod g)=0:
 	  DIV:=DIV+1;
 	fi;
       fi;
     endfor;
   fi;
   if Div=0:
     reponse:=true;
   fi;
   reponse
 enddef;
 
 vardef ulam(expr nb,pas)=
   save spiulam;
   picture spiulam;
   spiulam=image(
     if prem(nb)=true:
       trace cercles((0,0,0),(0.1,0,0),(0,0,0),(1,0,0),(0,1,0)) dashed evenly;
       label(TEX(""&decimal(nb)&""),Projette((0,0,0)));
     else:
       label(TEX(""&decimal(nb)&""),Projette((0,0,0))) withcolor 0.9green;
     fi;
     color ptd;
     ptd=(0,0,0);
     coef:=0.25;
     k:=nb;
     for l=1 upto pas:
       if (l mod 2)=1:
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    trace cercles(ptd+coef*(0,j,0),ptd+coef*(0,j,0)+(0.1,0,0),(0,0,0),(1,0,0),(0,1,0)) dashed evenly;% withcolor 0.9green;
 	    label(TEX(""&decimal(k)&""),Projette(ptd+coef*(0,j,0)));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),Projette(ptd+coef*(0,j,0)));
 	  fi;
 	endfor;
 	ptd:=ptd+coef*(0,l,0);
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    trace cercles(ptd+coef*(j,0,0),ptd+coef*(j,0,0)+(0.1,0,0),(0,0,0),(1,0,0),(0,1,0)) dashed evenly;%withcolor 0.9green;
 	    label(TEX(""&decimal(k)&""),Projette(ptd+coef*(j,0,0)));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),Projette(ptd+coef*(j,0,0)));
 	  fi;
 	endfor;
 	ptd:=ptd+coef*(l,0,0);
       fi;
       if (l mod 2)=0:
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    trace cercles(ptd+coef*(0,-j,0),ptd+coef*(0,-j,0)+(0.1,0,0),(0,0,0),(1,0,0),(0,1,0)) dashed evenly;%withcolor 0.9green;
 	    label(TEX(""&decimal(k)&""),Projette(ptd+coef*(0,-j,0)));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),Projette(ptd+coef*(0,-j,0)));
 	  fi;
 	endfor;
 	ptd:=ptd+coef*(0,-l,0);
 	for j=1 upto l:
 	  k:=k+1;
 	  if prem(k)=true:
 	    trace cercles(ptd+coef*(-j,0,0),ptd+coef*(-j,0,0)+(0.1,0,0),(0,0,0),(1,0,0),(0,1,0)) dashed evenly;%withcolor 0.9green;
 	    label(TEX(""&decimal(k)&""),Projette(ptd+coef*(-j,0,0)));
 	  else:
 	    label(TEX(""&decimal(k)&"$_{"&decimal(DIV)&"}$"),Projette(ptd+coef*(-j,0,0)));
 	  fi;
 	endfor;
 	ptd:=ptd+coef*(-l,0,0);
       fi;
     endfor;
     );
   spiulam
 enddef;
 
 
Conversion au format PDF de spiulam4.1
 figureespace(-11u,-11u,11u,11u);
 Initialisation(5,30,20,1000);
 draw ulam(1,9);
 finespace;
 
 
Conversion au format PDF de spiulam4.2
 figureespace(-10u,-10u,10u,10u);
 Initialisation(5,30,20,1000);
 draw ulam(41,7);
 finespace;
 end