ASPECTS FONCTIONNELS DE CAML

publicité
TD
2
ASPECTS FONCTIONNELS DE CAML
1 Retour sur les fonctions
Exercice 1
Une suite réelle correspond en Caml à une fonction de type int -> float.
1. Écrire une fonction somme : (int -> float) -> (int -> float) -> int -> float associant à
deux suites u et v la suite u + v.
2. Écrire une fonction arith : float -> float -> int -> float telle que arith a b soit la suite
arithmétique u de raison a et de terme initial u0 = b.
Exercice 2
1. Écrire une fonction puis : (’a -> ’a -> ’a) -> ’a -> ’a -> int -> ’a telle que
puis mul neutre x n calcule xn au sens de la multiplication définie par la fonction mul et l’élément
neutre neutre. Cette fonction procédera par exponentiation rapide.
2. Définir à l’aide d’une application partielle de puis l’exponentiation rapide sur les entiers.
3. On décide de représenter une matrice ac db ∈ M2 (Z) par (a,b,c,d) : int * int * int * int a .
On définit donc le type matrice = int * int * int * int.
a. Écrire une fonction matr_mul : int -> matrice -> matrice -> matrice
telle que matr_mul p x y calcule le produit de x et y modulo p (c’est-à-dire considérées comme
Z
des éléments de M2 pZ
).
109
Z
.
b. Calculer 01 11
dans 12345Z
c. Si ( fn ) désigne la suite de Fibonacci, combien vaut f109 mod 12345 ? Combien de multiplications
(approximativement, ou exactement si possible) a-t-on effectuées pour le calculer ?
a. Ce n’est pas la bonne manière, mais ça fera l’affaire ici.
2 Listes
Exercice 3
Écrire une fonction croissante : ’a list -> bool qui détermine si les éléments d’une liste sont rangés
par ordre croissant.
Exercice 4
1. OCaml fournit un opérateur infixe @ permettant de concaténer deux listes :
# [1;2] @ [7;8];;
Lycée du Parc –MPSI option informatique
1
TD 2 – Aspects fonctionnels de Caml
- : int list = [1; 2; 7; 8]
# [] @ [3.; 4.2];;
- : float list = [3.; 4.2]
a. Ré-implémenter cet opérateur sous la forme d’une fonction
concat : ’a list -> ’a list -> ’a list.
b. Lorsqu’on utilise cette fonction pour concaténer deux listes de longueurs respectives p et q, combien
y a-t-il d’appels au constructeur :: ?
2. On souhaite écrire a une fonction reverse : ’a list -> ’a list qui "renverse" son argument (par
exemple, reverse [1; 2; 3; 3] = [3; 3; 2; 1]).
a. Écrire une version «naïve» de la fonction reverse en s’aidant de la fonction concat. Combien
d’appels à :: cette fonction effectue-t-elle pour renverser une liste de longueur n ?
b. Écrire une fonction aux : ’a list -> ’a list -> ’a list telle que
aux l1 l2 = (reverse l1) @ l2.
On n’utilisera pas la fonction concat (ni @) et l’on fera en sorte que le nombre d’appels de aux à
:: soit de l’ordre de la longueur de l1.
c. En déduire une version efficace de reverse.
a. Cette fonction existe déjà en Caml : c’est List.rev.
Exercice 5
1. Écrire une fonction indice : ’a list -> a -> int telle que indice l x renvoie l’indice de la
première occurrence de x dans la liste l. Ainsi, si l = [2; 4; 3; 4; 1], indice l 4 renverra 1,
indice l 1 renverra 4 et indice l 17 renverra une erreur (via failwith).
2. Écrire une fonction indices : ’a list -> a -> int list telle que indices l x renvoie la liste
des occurrences de x dans l. Avec le l de la question précédente, on aura donc indices l 4 = [3; 1]
et indices l 17 = [].
On pourra utiliser une fonction auxiliaire de type ’a list -> ’a -> int list -> int -> int list.
3 Définitions de types
Exercice 6
On définit l’ensemble Z = Z ∪ {−∞, +∞} auquel on étend les opérations usuelles (ainsi que l’ordre) sur Z.
1. Définir un type etendu permettant de représenter les éléments de Z.
2. Écrire une fonction inf : etendu -> etendu -> bool renvoyant true si son premier argument est
inférieur ou égal au deuxième, false sinon.
3.
a. Écrire une fonction somme : etendu -> etendu -> etendu faisant ce que son nom indique. On
utilisera failwith pour traiter les cas indéterminés.
b. Définir un type etendu_2 en ajoutant à etendu un constructeur NaN (Not a Number) et écrire
une fonction somme_2 : etendu_2 -> etendu_2 -> etendu_2 qui traite correctement les cas
indéterminés.
4. Écrire la fonction produit : etendu_2 -> etendu_2 -> etendu_2.
5. On s’intéresse dans cette question aux intervalles de Z. On ne s’autorise donc pas les intervalles du type
~−∞, b (par exemple).
a. Définir un type intervalle permettant de représenter un tel intervalle. On pourra commencer par
définir un type borne à partir du type int .
b. Écrire une fonction inter : intervalle list -> intervalle calculant l’intersection d’une
liste d’intervalles. Il est fortement conseillé de commencer par écrire une ou plusieurs fonctions
auxiliaires.
Lycée du Parc – MPSI option informatique
2
Téléchargement