Devoir Surveillé 
“Calcul Symbolique”
Licence 2 Informatique
Mardi 15 décembre 2015

Durée 2 heures. Le barème est donné de manière purement indicative. Il est demandé d’écrire les solutions dans ce document, n’hésitez pas à utiliser le format texte pour expliquer votre démarche.

I. Paradigmes de programmation (6 points)

Ecrire une fonction Entre[liste,a,b] qui extrait d’une liste  tous  les nombres entiers  qui sont compris au sens large entre a et b. On demande d’écrire 4 versions de cette fonction, une version itérative, une autre récursive, une version fonctionnelle et enfin une dernière utilisant les patterns.

Entre1[liste_,a_,b_]:=Block[{res={},i,x},
For[i=1,i≤Length[liste],i++,
x=liste[[i]];
If[IntegerQ[x]&&a≤x≤b,res=Append[res,x]]];
Return[res]]

Entre2[{}]={};
Entre2[liste_,a_,b_]:=Block[{x=First[liste],l1=Entre[Drop[liste,1],a,b]},
If[IntegerQ[x]&&a≤x≤b,Prepend[l1,x],l1]]

Entre3[liste_,a_,b_]:=Select[liste,IntegerQ[#]&&a≤#≤b&]

Entre4[liste_,a_,b_]:=Cases[liste,n_Integer/;a≤n≤b]

liste={a,2,3,Pi,7/2,5,6.1,7,10,12};
Entre1[liste,2,5]
Entre2[liste,2,5]
Entre3[liste,2,5]
Entre4[liste,2,5]

II. Jeux de dés (8 points)

On jette 5 dés (à six faces) et on observe le résultat du lancer qui est une suite croissante de nombres entre 1 et 6.

1. Ecrire une  procédure Lancer[] qui retourne une suite croissante de nombres entiers entre 1 et 6. (2 points)

Lancer[]:=Sort[RandomInteger[{1,6},5]]

Lancer[]

2. Ecrire une fonction CarreQ[lancer] qui teste si un lancer contient un carré, c’est à dire 4 valeurs égales.(2 points)

CarreQ[lancer_]:=MemberQ[Map[Length,Split[lancer]],4]

CarreQ[{1,2,2,2,2}]
CarreQ[Lancer[]]

3. Ecrire une fonction BrelanQ[lancer] qui teste si un lancer contient un brelan, c’est à dire 3 valeurs égales d’une part et 3 valeurs égales de l’autre. (2 points)

BrelanQ[lancer_]:=Sort[Map[Length,Split[lancer]]]=={2,3}

BrelanQ[{2,2,2,3,3}]
BrelanQ[Lancer[]]

3. Ecrire une fonction SuiteQ[lancer] qui teste si un lancer contient une suite, c’est à dire 5 valeurs consécutives (2 points)

SuiteQ[lancer_]:=lancer==Range[5]||lancer==1+Range[5]

SuiteQ[Range[5]]
SuiteQ[1+Range[5]]
BrelanQ[Lancer[]]

II. Nuages de points sur (([0,1])^2) (16 points)

1. Génération (2 points)

Ecrire une fonction CreerNuage[n] qui génère n points à l’intérieur du carré [0,1]x[0,1].

CreerNuage[n_]:=RandomReal[1,{n,2}]

nuage=CreerNuage[10]

2. Représentation Graphique (4 points)

Ecrire une fonction DessinerNuage[n] qui représente les  n points.  
Représentez chaque point par autre chose qu’un cercle.

DessinerNuage[nuage_]:=ListPlot[nuage]
DessinerNuage[nuage_,car_,color_]:=ListPlot[nuage,PlotStyle->color,PlotMarkers->{car}]

DessinerNuage[nuage]
DessinerNuage[nuage,✶,Red]

3. Ordre (2 points)

Ecrire une fonction OrdonnerNuageX (resp. OrdonnerNuageY) qui ordonne un nuage de points selon les abscisses croissants (resp. ordonnées croissantes)

OrdonnerNuageX[nuage]:=Sort[nuage,First[#1]<First[#2]&]
OrdonnerNuageY[nuage]:=Sort[nuage,Last[#1]<Last[#2]&]

OrdonnerNuageX[nuage]
OrdonnerNuageY[nuage]

4. Distance minimale et point le plus proche (6 points)

4.1. Ecrire une fonction  DistanceMin[nuage,P]  qui retourne la distance minimale non nulle entre le point P et les points du nuage. Autrement dit, on retourne la distance de P à son plus proche voisin.

DistanceMin[nuage_,P_]:=Min[Map[EuclideanDistance[#,P]&,Complement[nuage,{P}]]]

4.2. Ecrire une fonction PlusProcheVoisin[nuage,P]  qui retourne le point du nuage à  distance minimale non nulle avec le point P.

PlusProcheVoisin[nuage_,P_]:=Select[nuage, EuclideanDistance[#,P]==DistanceMin[nuage,P]&]

4.3. Illustrer ces fonctions en représentant graphiquement le nuage, le point P et le disque centré en P de rayon DistanceMin[nuage,P].

IllustrationDistanceMinimale[nuage_,P_]:=Show[{DessinerNuage[nuage,✶,Red],
Graphics[{LightRed,Disk[P,DistanceMin[nuage,P]]}],
Graphics[{PointSize[Large],Green,Point[P]}]
}, AspectRatio->1]

P={.5,.5};
DistanceMin[nuage,P]
PlusProcheVoisin[nuage,P]
IllustrationDistanceMinimale[nuage,P]

5. Ecrire un programme (de complexité quadratique) qui calcule la distance minimale des paires de points dans un nuage. (2 points)

DistanceMin[nuage_]:=Min[Map[DistanceMin[nuage,#]&,nuage]]

DistanceMin[nuage]