You are on page 1of 8

Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 1/ 16 Licence 1 — FLIN101 TPs — Ph.

icence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 2/ 16

1 Préambule > double(77);doubleBis(22);


Vous pouvez également à l’aide du menu File sauvegarder une feuille maple dans un fichier ou
Vous êtes connecté sur une machine du réseau UFR. Recopiez le fichier .mapleinit qui se trouve encore l’imprimer.
dans le répertoire

/commun/l1/flin101 3 Expressions et affectation


Attention c’est un fichier caché. Son nom commence par un point. La destination de la copie doit 3.1 Expressions
être votre répertoire d’accueil (« home directory »), pas le bureau ou « Desktop »). Le nom reste
le même : .mapleinit. Comme ce nom commence par un point, le fichier restera « caché » lors de Si la valeur d’une expression est un entier maple affiche cet entier. Évaluez par exemple :
l’exécution de nombreuses commandes de visualisation des répertoires. > 72/9 ; sin(Pi/2); sqrt(3)^2 ; 1/2 + 3/2; 21 mod 2;
Ce fichier influera sur le comportement par défaut de maple. Il contient aussi la définition de la
procédure taille que nous utiliserons dans la manipulation des tableaux. Si la valeur d’une expression n’est pas entière, la valeur affichée par maple est une expression
simplifiée de même valeur. Évaluez :
> 38/4 ; 1/2 + 1/3; sin(Pi/4) + sqrt(3+4);
2 L’interpréteur maple
Pour obtenir une approximation réelle (en nombre flottant) d’une expression on peut utiliser la
Après avoir démarré maple 9, vous obtenez une fenêtre avec le signe > qui est l’invite (ou prompt) fonction evalf (évaluation en nombre flottant). Évaluez :
maple indiquant que l’interpréteur maple attend que vous saisissiez une commande. Lorsque vous
tapez une commande, maple l’exécute, affiche éventuellement un résultat et attend une nouvelle > evalf(38/4) ; evalf(sin(Pi/4) + sqrt(3+4));
commande. Les principales commandes sont : Si une expression est à valeur booléenne maple affiche ce booléen :
Invoquer l’aide. Pour obtenir des explications sur une fonction, instruction, ... il suffit de saisir
son nom précédé d’un point d’interrogation. Par exemple pour obtenir des explications sur la > (5 mod 3 =2) and double(11)=22;
fonction iquo tapez (sans le >) :
Pour certaines expressions le résultat affiché n’est pas un booléen mais une expression de même
> ?iquo
valeur :
Une fenêtre contenant une description des fonctions iquo et irem s’affiche.
Évaluer une expression. L’expression doit être terminée par un point virgule. maple évalue > 1 +1/2 =1.5 ; 5 mod 3 = 2; 3/2 <= 2;
l’expression et affiche sa valeur. Tapez
On peut obtenir la valeur booléenne d’une expression avec la fonction evalb (évaluation booléenne) :
> 2*(5-3);
On peut également terminer une expression par le caractère :. Dans ce cas l’expression est évaluée > evalb(1 +1/2 =1.5); evalb(5 mod 3 = 2); evalb(3/2 <= 2);
mais sa valeur n’est pas affichée.
> 2+5-3: Ainsi la procédure vérifiant si l’entier a est multiple de l’entier b s’écrit :
Une expression peut tenir sur plusieurs lignes et une ligne peut contenir plusieurs expressions. > multiple?:= proc(a::integer,b ::integer)::boolean;
Tapez par exemple : return evalb(a mod b = 0); end proc;
> 2+3;iquo(83,5);5*
> 8-1; Testez :
Pour passer à la ligne sans que maple n’évalue la ligne courante, tapez à la fois sur les touches > multiple?(666,8); multiple?(98,3);
Entrée et Majuscule.
Exécuter une instruction. Comme pour les expressions les instructions sont terminées par un des
caractères ; ou : et sont réparties de manière quelconque sur les lignes. Une ligne peut contenir
3.2 L’affectation
des expressions et des instructions. En maple certains noms ont une valeur prédéfinie. C’est la cas de la constante Pi ou de la fonction
> a:=5;b:=6;a+b; iquo. Nous appelons environnement initial l’ensemble de ces associations nom-valeur prédéfi-
Définir un algorithme. Par exemple l’algorithme double renvoyant le double d’un entier peut nies.
s’écrire : Attention : les symboles non prédéfinis ont comme valeur par défaut, leur nom. Par
> double := proc(e ::integer)::integer; exemple, le nom ccc qui n’appartient pas à l’environnement initial a pour valeur le
description "renvoie 2*e"; nom ccc lui-même. Ceci est contraire à ce qui a été dit en cours, comme quoi les
return 2*e; variables n’ont pas de valeur par défaut. Nous n’utiliserons par pour le moment cette
end proc; spécificité de maple. Lorsque dans une expression une variable n’a pas de valeur dans
On aurait pu également écrire : l’environnement courant, nous considèrerons que c’est une erreur.
> doubleBis := (e::integer) -> 2*e; Quelles sont les valeurs des variables c, d , e après la séquence d’affectations c:= 23 : d:=
L’exécution d’un algorithme s’écrit comme l’application d’une fonction : c+3 : e:= 2*d :. Pour cela tapez la commande :
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 3/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 4/ 16

> c:= 23: d:= c+3: e:= 2*d: c; d; e; 2. Définissez une procédure pour la fonction booléenne
Attention : maple fait la distinction entre majuscule et minuscule : ouExclusif : Booleen × Booleen −→ Booleen 
true si parmi a et b, un seul des 2 est true
> g := 33: g; G; a, b 7−→
false sinon
On affecte à présent l’expression 2*d à la variable e. Quelles sont les nouvelles valeurs de c,d,e Il existe en maple un opérateur xor pour le ou exclusif. Bien sûr on vous demande ici de
dans le nouvel environnement. Tapez la commande : ne pas l’utiliser.
Écrivez une procédure maple pour la fonction :
> e:= 2*d: c; d; e;
mul2ou3 ? : N −→ Booleen

Puis la commande : true si n est multiple de 2 ou de trois mais pas de 6
n 7−→
false sinon
> c:= c+d: c:= c+d: c; d; e;
On peut défaire toutes les associations nom-valeur et revenir ainsi à l’environnement initial avec la
commande restart. Tapez
5 Instructions conditionnelles
> restart: Pi; c; d; e; multiple? ; Soit un jeu de roulette simple : on mise une somme sur un numéro. Le gain est calculé en fonction
du numéro sorti selon la règle suivante :
Attention : avec maple il n’y a presque pas de typage. C’est bien dommage. Pour – Si les numéros sortis et joués sont identiques on remporte 20 fois la mise
l’instant, le type d’une variable est ... défini par sa valeur, et peut, hélas, changer au – Si les numéros sortis et joués sont dans la même dizaine on remporte 5 fois la mise
gré des affectations. Nous considérons que c’est une erreur grave, et forcerons maple – Si les numéros sortis et misés sont de même parité, on remporte 2 fois la mise
à se comporter « honorablement » dans l’écriture et l’utilisation des proc. – Sinon on ne gagne rien
On peut donc écrire la suite d’instructions : Dans une première version, on ne cumule pas les gains. Par exemple avec une mise de 10 e, le
> restart : c := 7 : d := 2* c: numéro misé 12, le numéro sorti 18, on gagne 5 fois la mise, donc 50 e, car les numéros sont dans
la même dizaine, mais on ne cumule pas avec la règle de même parité.
Recherchez les valeurs de c et d dans l’environnment courant. Visiblement le type de ces variables Écrivez une fonction vérifiant si 2 entiers naturels sont dans la même dizaine. C’est le cas par
est actuellement Entier. exemple de 38 et 33 ou encore de 922 et 929, mais pas 128 et 325. La fonction iquo peut servir.
Exécutez alors : Regardez l’aide de cette fonction.
c := evalb(c = d): Complétez la procédure ci-dessous calculant le gain au jeu de roulette :
Quels sont le type et la valeur de c ? > gainRoulette := proc(mise:: integer, numJoue:: integer, numSorti :: integer):: integer;
Cette suite d’instruction est considérée comme une erreur grave dans la majorité des langages de description "calcule la somme remportée au jeu de roulette en fonction de la
programmation raisonnables. mise, du numéro joué et du numéro sorti";
local gain :: integer;
...
4 Algorithmes, procédures, conditionnelles return gain;
end proc;
1. Vous commencerez par tester la fonction maple max. Regardez l’aide. Cette fonction admet
un nombre variable quelconque d’arguments numériques. Testez. Testez votre procédure en évaluant gainRoulette(100,675,500), gainRoulette(100,675,672)
Écrivez ensuite une procédure maple pour calculer chacune des fonctions suivantes. Vous
testerez votre procédure avec différents arguments. et gainRoulette(100,675,675)
triangleEquilat ? : N × N × N −→ Booleen Écrivez une deuxième version gainRoulette2 dans laquelle on cumule les cas de gain. Par exemple

true si a, b et c sont les longueurs des cotés d’un triangle avec une mise de 10 e, le numéro misé 12, le numéro sorti 18, on gagne 7 fois la mise, donc 70 e,
a, b, c 7−→ car les numéros sont dans la même dizaine, et en plus ils sont de même parité.
renvoie false sinon
Attention, il ne s’agit pas de changer les règles ! On garde les mêmes règles, mais on change
triangle ? : N × N × N −→ Booleen
 leur interprétation. Donc on change probablement l’ordre et/ou l’imbrication et/ou la mise en
 true si a, b et c sont les longueurs des cotés d’un triangle séquence des conditionnelles. Peut-être même change-t-on l’instruction gain := 5 * mise en
a, b, c 7−→ (chaque longueur est inférieure à la somme des 2 autres), gain := gain + 5 * mise ....

renvoie false sinon
triangleIsocele ? : N × N × N −→ Booleen

 true si a, b et c sont les longueurs des cotés d’un triangle iso
6 Itération
a, b, c 7−→ (2 cotés ont même longueur), 1. Écrivez une procédure somPair qui étant donné un entier n renvoie la somme des n premiers

renvoie false sinon entiers pairs non nuls. Par exemple somPair(5)=2+4+6+8+10=30.
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 5/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 6/ 16

Attention, on veut une programmation de ce calcul utilisant une itération, pas l’utilisation > for i to 10 do coordalea(); end do;
d’une formule qui définiraitt le résultat en fonction de n. Écrivez une procédure estDansLeCercle? qui étant 2 coordonnées x et y dans l’intervalle réel [0, 1]
2. Écrivez une procédure somImpair qui étant donné un entier n renvoie la somme des n premiers teste si le point de coordonnées (x, y) est à l’intérieur du quart de cercle de rayon 1.
entiers impairs. Par exemple somImpair(5)=1+3+5+7+9=25. En utilisant coordalea et estDansLeCercle?, écrivez la procédure monteCarlo de paramètre N
Évaluez la commande : renvoyant une approximation de Π, en complétant le texte ci-dessous.
monteCarlo:=proc(N::integer)::float;
> for i from 1 to 15 do
local x::float,y::float,Nint::integer, ...;
somImpair(i);
Nint:=0;
end do;
...
Que constatez-vous ? return ...;
3. Écrivez une procédure pour la fonction : end proc:
èmeMult : N −→ N Testez cette procédure :
n 7−→ le nème nombre multiple soit de 2 soit de 3 (mais pas de 2 et 3 en même temps) > monteCarlo(10);monteCarlo(50);monteCarlo(100);monteCarlo(1000);monteCarlo(10000);
Par exemple èmeMult(5)=9.
8 Tableaux
7 Méthode Monté Carlo Attention à bien avoir téléchargé le fichier .mapleinit nécessaire à la bonne exécution de ce TP.
Voir TP 1
Les méthodes Monté Carlo consistent en des simulations de problèmes mathématiques ou phy- Soit le T un tableau de 10 éléments déclarés comme suit :
siques basées sur la génération aléatoire de nombres. Ce principe peut être utilisé pour trouver une
approximation du nombre Π. > T := array(1..10);
Soit un carré de coté 1 et un quart de cercle, de rayon 1, inscrit dans ce carré comme le montre la On rappelle que la valeur de T est alors son nom. Pour obtenir ses éléments il faut évaluer eval(T).
figure ci-dessous. Testez :
> T; eval(T);
1
Testez que vous avez bien la fonction taille dans votre environnement :

01
> taille(T);
y P
Si maple ne répond pas 10, vous n’avez pas recopié le fichier .mapleinit, ou pas au bon endroit.
Recommencez, relancez maple.
Les éléments d’un tableau n’ayant pas de valeur sont notés ?. En utilisant l’index d’un élément, on
peut lui affecter une valeur, accéder à cette valeur comme pour les variables :
> T[4]:= 9: T[6]:= 2*T[4]: T[3]:= T[4]+T[6]: eval(T);
On rappelle que cet indice doit appartenir à l’intervalle d’entiers défini lors la déclaration du tableau
0 x 1 et que la fonction taille renvoie le nombre d’éléments d’un tableau :
> taille(T); T[20];
On peut lors de la déclaration d’un tableau initialiser ses éléments :
Le rapport entre la surface du quart de cercle et la surface du carré est Π
4
. On peut estimer cette
valeur en tirant uniformément N points à l’intérieur du carré et en comptant le nombre N int de > S := array(1..4,[2,9,13,8]); S[3];
points appartenant au quart de cercle : NNint est une approximation de Π4 d’autant meilleure que N Attention maple autorise l’affection de tableaux :
est grand.
Pour tirer aléatoirement un point à l’intérieur du carré il suffit de tirer deux coordonnées x et y > P:=S: eval(P);
dans l’intervalle réel [0, 1]. La procédure coordalea ci-dessous retourne un réel entre 0 et 1. > U:=array(1..4,[2,9,13,8]);
coordalea:=proc()::float;
Mais il s’agit là d’une affectation du nom du tableau et non des valeurs. L’utilisation d’une telle
local alea::procedure;
affectation est délicate. Sur l’exemple les tableaux S,U,P ont même valeur. Mais, S et P ne sont
alea:=rand(0..10^5);
pas indépendants : lorsqu’on modifie un élément de T, P est modifié, U ne l’est pas.
return evalf(alea()/10^5);
end proc; > eval(S);eval(U);eval(P);S[2]:=1111; eval(S);eval(U);eval(P);
Testez cette procédure en évaluant
Dans la suite on s’interdira d’utiliser une telle affectation.
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 7/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 8/ 16

9 Algorithmes sur les tableaux (b) Quelle expression permet de calculer le chiffre des unités d’un entier n ? Comment obtenir
le chiffre des dizaines, ... En déduire une procédure calculant l’écriture décimale d’un
1. Écrivez une procédure testant si 2 tableaux sont égaux, c’est à dire s’ils ont même taille et entier n.
mêmes éléments :
ecritureDecimale:=proc(n::integer)::array(integer);
> tabEgaux := proc(A::array(integer),B::array(integer))::boolean; description "renvoie dans un tableau l’écriture décimale de n";
description "teste l’égalité de 2 tableaux"; ...
local i::integer; (c) On souhaite à présent obtenir l’écriture en base k d’un entier naturel n. En gardant
... comme convention que T [1] est le chiffre de poids fort, T [2] le second chiffre de poids
end proc: fort, ... le tableau T est l’écriture en base k de l’entier n ssi :
Testez votre code : ∀i ∈ [1..taille(T )], T [i] ∈ [0..k − 1]
taille(T )−1
> A:=array(1..3,[1,2,3]): B:=array(1..3,[1,2,3]): C:=array(1..3,[1,2,2]): X
et n = T [taille(T ) − i] × k i
> tabEgaux(A,B); tabEgaux(A,C);
i=0
2. Écrivez une procédure pour la fonction : 1 2 3 4 1 2 3
Ainsi 48 s’écrit en base 3 : , en base 5 : . Généralisez la procédure
tabCarrés : N −→ array 1 2 1 0 1 4 3

n 7−→ Un tableau T de taille n tel que ∀ i ∈ [1..n], T [i] = i2 précédente en passant en paramètre la base k en plus de l’entier n.
Pour cela complétez ce qui suit :
> tabCarrés := proc(n::integer)::array(integer); 10 L’algorithme de tri par insertion
local i::integer, t::array;
t:=array(1..n); Le tri par insertion, consiste à chaque étape, à prendre un élément non trié et à l’insérer à sa place
... parmi les éléments triés. Commencez par écrire la procédure d’insertion dans un tableau trié vue
return eval(t); en TD :
end proc; Algorithme : insereTab
Données : e un entier, A un tableau d’entiers trié
De la même façon, écrivez une procédure tabSuite qui étant donné un entier n renvoie un Résultat : un nouveau tableau résultant de l’insertion de l’élément e dans le tableau A,
tableau de taille n contenant les n premiers termes de la suite (Uk )k N∗ . c’est à dire un tableau trié de taille taille(A) + 1 contenant les éléments de A

U1 =1 plus l’élément e.
Uk+1 = Uk + 2k + 1 pour k N∗ 1 2 3 4 5
Testez votre procédure et comparez le résultat avec celui de la procédure tabCarrés : Par exemple si e = 7 et A le tableau , la procédure d’insertion doit renvoyer le
3 5 8 11 20
> tabSuite(6); 1 2 3 4 5 6
nouveau tableau : Testez votre procédure : > T:=array(1..5,[3,5,8,11,20]): in
> tabEgaux(tabCarrés(15),tabSuite(15)); 3 5 7 8 11 20
3. Écrivez une procédure qui, étant donné un tableau d’entiers T , calcule son nombre de "maxi- Utilisez insereTab pour écrire une procédure de tri par insertion. La procédure que vous devez
mum local". Un élément T [i] est un maximum local si les éléments d’indice i − 1 et i + 1, s’ils écrire admet en paramètre un tableau d’entiers T et renvoie un nouveau tableau N T tel que N T
existent, sont inférieurs à T [i]. Par exemple les "maximum local" de [2, 6, 1, 3, 4, 8, 12, 7, 9, 11, 3, 2, 7, 21] est trié et contient les mêmes éléments que T .
sont 6,12,11,21. Pour ce tableau la procédure doit donc retourner la valeur 4. Cette procédure doit s’inspirer du schéma suivant :
4. Codez et testez la procédure qui écrit en base k un entier naturel n. Cet algorithme a déjà > T:=array([9,8,1,7,5,8]):NT:=array(1..1,[T[1]]);
été écrit en TD. En revoici le texte : On s’intéresse à l’écriture en base 10 d’un entier naturel > NT:= insereTab(T[2],NT); > NT:= insereTab(T[3],NT); ...
n. Cette écriture sera représentée par un tableau T de chiffres (∈ [0..9]) : T [taille(T )] est le
chiffre de poids faible (des unités), T [taille(T ) − 1] le second chiffre (chiffre des dizaines)... Vous allez donc écrire quelque chose comme :
taille(T )−1
X
Plus précisément n = T [taille(T ) − i] × 10i où taille(T ) est le nombre de chiffres de triInsertion:=proc(T::array(integer))::array(integer);
i=0 local NT::array, ...;
l’écriture décimale de n. NT:=array(1..1,[T[1]] );
1 2 ...
Par exemple l’écriture en base 10 de 48 est le tableau :
4 8 return(eval(NT));
Vous aurez besoin des fonctions fournissant respectivement le reste et le quotient de la division end proc:
entière.
(a) Écrivez une procédure renvoyant le nombre de chiffres de l’écriture décimale d’un entier
n.
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 9/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 10/ 16

11 Listes (g) (***) En utilisant TabOccur, écrivez un algorithme TriListe qui a pour paramètre une
liste L dont on sait à l’avance que les éléments sont des entiers entre 1 et 999, et qui
Dans cette section vous devez utiliser le type Liste, ses constructeurs Vide, consL et ses accesseurs renvoie la liste dont les éléments sont ceux de L mais triés dans l’ordre croissant.
succ, first, EstVide. Testez avec TriListe( [4,1,2,1,999] ) qui doit renvoyer la liste [1,1,2,999].
1. Utilisez la fonction alea qui a 0 paramètres et renvoie un entier aléatoire (ou plutôt pseudo- Testez avec TriListe( Lex )
aléatoire) compris entre 1 et 999 :
(h) Dans l’algorithme InverserListe qui a pour paramètre une liste L, vous avez utilisé un
alea := rand(1..999): balayage séquentiel des éléments de L, pour créer et renvoyer la liste dont les éléments
Testez avec une itération qui renvoie 50 nombres « aléatoires » compris entre 1 et 999. sont ceux de L mais dans l’ordre inverse.
2. Déclarez deux variables Lex1 :: Liste; Lex2 :: Liste, puis modifiez la valeur de Lex1 de Vous allez utiliser le même principe. En supposant deux listes L1 et L2, on peut balayer
façon qu’elle contienne 10 000 entiers aléatoires entre 1 et 999. Même chose avec Lex2 qui la suite des éléments de L1, puis la liste des éléments de L2 pour créer une seule liste L3
contiendra seulement 10 entiers aléatoires entre 1 et 999. Ces listes Lex1, Lex2 vont servir à dont les éléments sont ceux de la « mise bout à bout » ou concaténation de L1 et L2.
tester les algorithmes suivants, que vous écrirez : Qu’obtient–on si on applique InverserListe à L3 ?
(a) DerListe qui renvoie le dernier élément de sa liste paramètre. Écrivez l’algorithme Concat qui renvoie la liste concaténation (mise bout à bout) de ses
(b) InverserListe qui renvoie la liste dont les éléments sont ceux de la liste paramètre mais deux listes paramètres.
dans l’ordre inverse. (i) Reprenez et testez les algorithmes vus en TD : EcritureBase et ValeurDecimale.
(c) ExtraireListe qui a une liste paramètre L et qui renvoie la liste extraite de L dont les Utilisez ces deux algorithmes pour écrire l’algorithme ConversionBase qui a pour para-
éléments sont des nombres entiers premiers. mètres une liste L de « chiffres », une base b1 et une base b2, telles que L est l’écriture
Vous pourrez utiliser la fonction Maple isprime. Testez isprime(5); puis isprime(12); en base b1 d’un nompre dont vous allez calculer et renvoyer l’écriture en base b2.
ExtraireListe([2,11,4,7,8,11]); doit renvoyer la liste [2,11,7,11]; Exemple : ConversionBase([1,0,1,0,1],2,5) doit renvoyer [4,1].
(d) Maple fournit la fonction plot pour tracer un graphique. Le graphique passé en paramètre
peut être défini de plusieurs façons. L’une d’entre elles consiste à passer comme paramètre 12 Récursivité
un nuage de points, qui en dimension 2, est représenté par une liste de liste à deux
éléments : 12.1 Récurrences vues en TD
Nuage := [[x1,y1],[x2,y2],...,[xp,yp]]
On souhaite tracer les points de coordonnées [i,somDiv(i)] pour chaque entier i de 1. L’exponentiation : on calcule ab où a est un réel (float) positif, et b est un entier positif.
compris entre 1 à 500, où somDiv(i) est la somme des diviseurs de i. (a) Écrivez la procédure expolent qui réalise une suite de b multiplications pour obtenir son
i. Écrivez l’algorithme SomDiv qui a pour paramètre un entier strictement positif et résultat.
qui renvoie la somme des diviseurs de cet entier. Testez expolent avec b très grand, au moins 105 , en essayant d’aller aux limites de votre
machine. En gros, débrouillez vous pour que ce calcul soit extrêmement long, de l’ordre
ii. Construisez la liste nuage de points :
de 10 secondes de temps humain.
N uage = [[1, somDiv(1)], [2, somDiv(2)], ..., [500, somDiv(500)]].
Pour être certain du temps mis par votre « machine » pour réaliser ce calcul, exécutez
iii. Dessinez ce nuage avec l’option style=point (consultez l’aide pour connaître l’en- time(expolent(1.5, ... )); .
semble des options de plot) : exécutez l’instruction :
(b) Écrivez la procédure exporapide vue en TD.
[> plot(Nuage, style=point, symbol=point); Testez exporapide avec les mêmes arguments. Comparez les temps pour vérifier cette
iv. Qels sont les points du nuage situés sur la droite y = x + 1 ? fameuse « rapidité ».
v. Vérifiez en extrayant de la liste Nuage les éléments qui sont des listes [x,y], telles Si on suppose que la puissance est b = 67108864 = 226 , et si on suppose que Maple exé-
que y = x + 1. cute 106 multiplications par secondes, quel est le temps de calcul estimé pour expolent(1.5,
(e) OccurListe qui a deux paramètres : un entier x et une liste L, et qui renvoie le nombre 67108864) ? Et quel est celui de exporapide(1.5,67108864) ?
d’occurrences de x dans L. 2. Donnez une version récursive de la concaténation de deux listes.
Combien de 1 dans Lex ? concat := (L1::Liste,L2::Liste) ->
(f) TabOccur qui a pour paramètre une liste L dont on sait à l’avance que les éléments sont if ...
des entiers entre 1 et 999, et qui renvoie un tableau d’entiers T de taille 999, tel que T[i] then ...
est le nombre d’occurrences de i dans L. else consL(...,concat(...,...)) end if;
Testez avec TabOccur( [4,1,2,1,999] ) qui doit renvoyer le tableau de taille 999 dont Testez.
la valeur affichée par Maple est [2,1,0,1,0,0,0,...,0,1].
3. Donnez une version récursive de l’égalité de deux listes.
Testez avec TabOccur( Lex )
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 11/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 12/ 16

egalesL := (L1::Liste,L2::Liste) -> [> lapin2:=proc(R::float,n::integer)::integer;


if EstVide(...) description "nombre de lapins version 2";
then ... if n=0 then return 500
elif EstVide(...) else return floor(R* lapin2(R,n-1)*(1- lapin2(R,n-1)/10^5))
then ... end if; end proc:
else ( first(...) = ... ) and egalesL( succ(...) , ...) Cette procédure pour calculer lapin(R,n) calcule 2 fois v(R,n-1), donc 4 fois v(R,n-2)
end if; ..., donc 2i fois v(R,n-i) ! Évaluez time(lapin2(1.5,16)) pour obtenir le temps (proces-
Testez avec egalesL([2,3],[2,3,4]), puis avec egalesL([2,3,4,5],[2,3,4]), enfin avec seur) de calcul de v(1.5,16). Comment éviter ces calculs inutiles ? Corrigez la procédure
egalesL([2,3,4],[2,3,4]) lapin2 et évaluez son temps de calcul.
(b) Comme précédemment, représentez graphiquement l’évolution de la population sur 100
12.2 Des lapins et des lynx ans, de 10 en 10, pour différentes valeurs du paramètre R. Essayez de localiser les valeurs
de R pour lesquelles la suite (vn )n∈N change de nature.
Cette partie est inspirée d’un exercice de La Recherche, 296.
Lapins sans prédateurs Lapins et lynx
Pour stabiliser le nombre de lapins, l’homme introduisit 200 prédateurs : des lynx, qui, se nourrissent
1. Dans un grand continent, où l’espèce était absente jusque là, on introduit des lapins. Ceux– exclusivement de lapins. L’année de l’introduction des lynx, il y avait 38 195 lapins.
ci s’ébattent librement et la nourriture est si abondante que les premières années le taux L’évolution de la population des lapins, décrite par la suite (wn )n∈N , dépend donc de la valeur de
d’accroissement de leur population est égal à une constante R comprise entre 1 et 4. Soit la suite (yn )n∈N , donnant le nombre de lynx au bout de n années. Cette loi est donnée par :
(un )n∈N la suite définie par ∀n > 1 : un = ⌊R un−1 ⌋, un est le nombre de lapins au bout de n
années.
w0 = 38 195,
(a) Écrire une procédure récursive lapin1(R, n) où R est un flottant et n un entier calculant le
wn−1 yn−1
nième terme de la suite réelle (un )n∈N . On suppose que la population initiale est u0 = 500. ∀n > 0 :wn = max(0, ⌊R wn−1 (1 − − )⌋) (2)
a b
La fonction maple, pour obtenir la partie entière, classique ou par valeurs inférieures,
où R ∈]1; 4[, a = 10 et où b = 5000
5
d’un nombre est floor.
(b) Écrivez une fonction genNuage qui pour un taux de croissance, génère le nuage de points Et, parallèlement, le nombre de lynx suit la loi :
correspondant aux populations de lapins après 1,2,..,10 années, c’est à dire la liste des
yn−1 wn−1
listes [i,lapin(R,i)] pour i ∈ [1..10]. Cette liste doit être ordonnée : y0 = 200, ∀n > 0 : yn = ⌊0.25 yn−1 (1 − + min(4, ))⌋; (3)
25000 1000
[[1,lapin1(R,1)],[2,lapin1(R,2)],...]
1. Écrivez les fonctions lapin3 et lynx ayant comme précédemment R et n comme paramètres et
[> genNuage:=proc (R::float)::Liste;
calculant la population des lapins et des lynx au bout de n années. Évaluez time(lapin3(2.5,15));
local i::integer, L :: Liste;
Là encore, la traduction directe des suites (wn )n∈N et (yn )n∈N conduit à une procédure répétant
for i from .... do
des calculs inutiles : wn calcule 2 fois wn−2 (une fois par wn−1 , une autre par yn−1 ). On peut
L := consL( ....);
paramètrer maple afin qu’il mémorise les calculs effectués pour éviter de les reproduire. Pour
end do;
cela il faut placer l’option remember en début de procédure :
return L;
end proc; [> lapin3:=proc(R::float,n::integer)::integer;
description "nombre de lapins version 3";
La fonction plot permet de superposer plusieurs graphiques en passant comme paramètre option remember;
une liste de nuages de points (donc une liste de listes de listes de longueur 2). Définissez ...
listeNuages la liste des nuages pour les taux de croissance 1.5, 2., 2.5,3.5. Affichez ces end proc:
4 courbes en évaluant plot(listeNuages);.
2. Tracez l’évolution des populations sur 100 ans, quand R vaut successivement 1.1, 1.6, 2.1 et
2. Au bout de quelques années, la population augmentant sensiblement, les ressources en nour-
2.5.
riture diminuent. Finalement les statisticiens lapins affinent leur modèle et proposent la loi :
vn−1
v0 = 500, ∀n > 0, vn = ⌊R vn−1 (1 − )⌋ où R ∈]1; 4[ et où a = 105 (1) 12.3 Fractale
a
12.3.1 Tracé de N triangles emboités
Dans ce modèle, plus vn se rapproche de l’effectif 105 , plus le taux de croissance diminue.
Il s’agit de tracer la figure (a), composée de n = 5 triangles équilatéraux de coté c et de point
(a) La procédure lapin2 calculant la suite (vn )n∈N peut s’écrire :
d’origine PO :
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 13/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 14/ 16
P1
P1 12.3.3 Généralisation : polygones emboités
c P4 P5

P0 P0 P2 P0
P3
P2 Il s’agit de généraliser le tracé de triangles du 12.3.1 et le tracé de carrés vu en cours : dessiner n
(a) (b) (c) polygones réguliers à k cotés de longueur c comme sur la figure et sans repasser par un même trait :
Comme pour le tracé des carrés emboités traité en cours, la ligne polygonale à construire ne doit
pas repasser par un même trait. À l’ordre 1, cette figure (b) est un triangle équilatéral (P0 , P1 , P2 ). 11
00 11
00
O
11
00
11
00 11
00 11
00
À l’ordre 2, la figure (c) est composée de 2 triangles (P0 , P1 , P2 ) et (P3 , P4 , P5 ). R 3Π/k

– Un point est représenté par une liste de 2 coordonnées cartésiennes. Par exemple le point de
Π/k
P 00
11

coordonnées réelles (0., 0.) est défini par la liste [0., 0.].
[> P0:=[0.,0.]: c:=2. : Soit par exemple k:=7: c=2.:P:=[0.,0.]: Définissez à partir de k, c et P : O le centre du polygone
Définissez en fonction du point P0 et de la longueur c les points P1 et P2 . Pour tracer une ligne poly- et R son rayon.
gonale on peut passer à la fonction plot la liste des points : plot([P0,P1,P2,P0],axes=none); Définissez à présent la liste des points du polygone.
– Définissez la fonction milieu qui étant donné 2 points A et B calcule leur milieu. Définissez la procédure
[> milieu := (A:list,B::list)-> ...; dessinPolygone(n::integer,k::integer,P::list,c::float)::list;
Définissez P3 , P4 , P5 les milieux respectifs de (P0 , P2 ), (P0 , P1 ), (P1 , P2 ). Tracez la figure à l’ordre construisant la ligne polygonale des n polygones réguliers à k cotés de longueur c et d’origine P .
2.
– La figure à l’ordre n est la concaténation de 3 lignes polygonales comme l’indique la figure ci–
dessous : P
13 Encodage et décodage
1

13.1 Les foncions encode et decode


P4 P5

Q Q
P0 P2
P3 P P3
Suivant les principes vus en TD, on veut encoder des chaînes de caractères ou décoder des entiers, en
Définissez le point Q en fonction des points précédents. utilisant un alphabet. Dans le cas très improbable où vous auriez oublié ces principes, voici quelques
On rappelle que la concaténation de 2 listes L1 , L2 a été vue auparavant. rappels :
Testez par exemple : – l’alphabet est représenté par une chaîne de caractères (string), par exemple "abcd". Le code
[> L1:=[P0,P1,P2,P3,P6]: L2:=[P4,P5,P3,P0]: d’un caractère est son rang dans cette chaîne. L’ensemble des codes est représenté par une table.
plot(L1);plot(L2);plot(concat(L1, L2)); Donnez l’instruction définissant cette table code pour l’alphabet alphab1:="abcd".
Définissez la fonction dessinTriangles dont les paramètres sont un entier n, 1 point (une liste) length(ch)
X
P0 et un flottant c, qui renvoie la ligne polygonale pour le tracé de n triangles équilatéraux de Le code d’une chaîne ch est alors code[ch[i]].(ta + 1)i−1 où ta est la taille de l’alphabet.
coté c et d’origine P0 . i=1
Évaluez plot(dessinTriangles(7,[0.,0.],4.),axes=none); Quel est le code de la chaîne "bac" dans l’aphabet alphab1 ? Écrivez alors la procédure encode :
[> encode := proc( ch::string, alpha::string )::integer;
12.3.2 Flocons de Koch description "renvoie le code de la chaine ch ecrite dans l’alphabet alpha";
...
Soit un segment [A,E]. À l’ordre 0 le flocon est le segment [A,E]. À l’ordre 1 le flocon est composé – Pour décoder un nombre nb issu d’un encodage à partir d’un alphabet alpha, on prend l’écriture
de 4 segments : de nb en base length(alpha)+1. Pour l’obtenir on peut utiliser la fonction prédéfinie convert.
C Essayez convert(6,base,2) pour obtenir l’écriture de 6 en base 2. La liste des chiffres obtenue
est ordonnée par poids croissant.
A B D E Soit lch:=convert(58,base,5); Comment, à l’aide de l’itérateur seq inverser l’ordre des élé-
ments de lch ? Soit lchbis la liste lch inversée (vous devez obtenir la liste [2, 1, 3]).
Pour obtenir le flocon d’ordre 2, on applique la même transformation aux 4 segments. Les coordon- Chaque élément de lchbis est le code d’un caractère de l’alphabet alphab1. Comment obtenir,
2xA +xE  xA +2xE 
nées des points B et D sont fonction de celles de A et E : B 2yA3+yE D yA +2y3
E
. Les coordonnées toujours avec seq, la suite des caractères lcar correspondant à la liste lchbis (c’est à dire la
xB +xD


3
(y −y ) 
3 3
suite "b","a","c") ?
du point C sont C √3 2 2 D
yB +yD
B
Pour concaténer ces caractères, évaluer cat(lchar);
2
(xD −xB )+ 2
Définissez à présent la fonction flocon : Vous pouvez à présent écrire la procédure decode :
decode := proc( nb::integer, alphabet::string )::string;
[> flocon:= proc(n::integer,A::list,E::list)::list; description "réciproque de encode";
description "ligne polygonale correspondant au flocon",
"d’ordre n et de points extremes A et E";
... 13.2 Tests et taille de message
Tracez les flocon d’ordre 2,3,4 dont les extrémités sont les points [1, 1] et [2, 2]. – Soit la chaîne de caractères ch définie par
Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 15/ 16 Licence 1 — FLIN101 TPs — Ph. Janssen & J.F. Vilarem Novembre 2010 p. 16/ 16

ch := "C’est un grand jour: Définir une chaîne, coder par un


nombre, et décoder ce nombre. Telles sont mes activités."; x3 := 686924027052470707990894951570363610013979066394495596408242144809901035175875520511
Donnez-vous un alphabet alphab2 suffisant pour coder/décoder ch. Il devra contenir les minus- 1692641264872915406:
cules, les majuscules, quelques lettres accentuées, des séparateurs comme l’espace, des ponctua-
tions. – Soit alors ch1, ch2 les décodages respectifs des entiers respectifs x1,x2 en utilisant alphabetSol.
– Testez l’encodage de ch (et d’autres chaînes de caractères). – Ces chaînes contiennent des expressions Maple. On peut faire exécuter par Maple le contenu
– Testez le décodage des nombres produits par l’étape précédente, avec le même alphabet évidem- d’une chaîne, quand c’est celui d’une expression valide en utilisant l’instruction :
ment. parse(chaineContenantLinstruction, statement);
– Soit ta la longueur de votre alphabet. Exécutez parse(ch1, statement);, idem avec ch2.
1. Exécutez x := (ta + 1)3 + (ta + 1);. Que renvoie decode(x,alphab2); ? Expliquez. Testez le résultat.
– Décodez x3 en utilisant alphabetSol, et interprétez son contenu.
2. (***) Quelle est, en fonction de n, la valeur du plus grand codage d’une chaîne de caractères
de longueur n, qui utilise un alphabet de taille ta ?
Soit alors MaxChiffres défini par MaxChiffres := kernelopts(maxdigits); le nombre 13.4 Schéma de Horner
maximum de chiffres d’un entier en base 10 avec Maple. Écrivez une fonction Horner qui a pour paramètres une liste [an , an−1 , ..., a0 ] de coefficients entiers
Exprimez en fonction de MaxChiffres et de ta, la longueur maximum d’une chaîne qu’on X n

peut encoder avec l’alphabet de taille ta. et un entier c et qui calcule la valeur P (c) avec P : x −→ ak x k
k=0
Quelle est la valeur de cette limite sur votre machine ? Testez votre fonction pour calculer P (c) avec :
X 20  
20 k
13.3 Code magique 1. P : x −→ x et c = 1, puis c = 3.
k=0
k
On va tester vos fonctions sur les exemples qui suivent. Attention, il faut respecter strictement les Le résultat est une fonction simple de c. Laquelle ?
définitions. Il n’est donc pas question de « recopier ». Le fichier qui contient les définitions Maple 20
X
ci–dessous est dans le répertoire 2. P : x −→ xk et c = 3, puis c = 4.
k=0
/commun/l1/flin101 Le résultat est une fonction simple de c. Laquelle ?
alphabetSol:="éè’ !\"()*+,-./0123456789:;<=>ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_‘abcdefghijklmn Modifiez la fonction encode en utilisant la procédure Horner.
uvwxyz{}";

x1 :=7648580813716444955253485086953476596785345347278592480263873119932060584365181210282
094966565020225262737748720031567309021838228694831094383224388196612865191969583951421347
983432457231267962637999717117652799147110578004693565951894734654166560117247554323599200
452023166825868390525180388920777425486015223997276801602063232530373014187868208413400990
964776888096880965578298120113927666672503249396957730881725461927115352554768010465960837
044643256410096178800569189352770782579359228035940180494429840705376644148504775235305198
368246575892734875127391586118342107233979275027910136591713307729526150446953498433988504
271173859562364071822186188368300695982881118498232382411915427376423275041148093523115011
644535921442646485855725606901695257801618571009473535447955512401550077528014989869674132
638831221040384392170356680966364250445961429368235197133670185837096003849295650549742979
782470747504241878434190382081876435484270436339697511042255514448487674607497106437683541
115190480431196125694509797906384163778450789534404174411536510049700849548880206639768816
3970103785764435645518217398587655584296301937993339240117602824153461657994544607025:

x2 := 117883769638596825320303774244184795099019791710400161088277921789513715888744585373
780599650632911408518035184616057690345609416352659065598369731653659948583066830626881942
185353048104620217679493755419055526731558849974589085726927650263198289247893308517041090
347422914373177585675984269936821555623679412159348366131631476582301802067052113132744503
706774298093685521035838187288913517787242432630509120780425145534069519061122595034432900
634522679011887070391732126085119472477921139917594384360483688850655327337430067499386017
209671060107899917401585814921180731534:

You might also like