0% ont trouvé ce document utile (0 vote)
45 vues2 pages

Fonctions et arbres en OCaml

Transféré par

mohamomo4321
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
45 vues2 pages

Fonctions et arbres en OCaml

Transféré par

mohamomo4321
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

COMPOSITION D’INFORMATIQUE (Option) n°1

Durée : 2h
???

Exercice 1

1. Écrire une fonction minimum : ’a array -> ’a qui renvoie l’élément minimum dans un tableau.
On considèrera qu’on ne fera d’appel à la fonction que pour des tableaux non vides et on ne
demande pas de vérifier cette condition.
2. Écrire une fonction sous_chaine : string -> int -> int -> string telle que si on pose
s = c0 c1 . . . cn−1 , i ∈ N et j ∈ N, alors sous_chaine s i j renvoie la sous-chaîne de carac-
tères ci ci+1 . . . cj−2 cj−1 . On considèrera que n > 0 et que i, j ∈ [[0, n]], i < j et on ne demande pas
de vérifier ces conditions.

Exercice 2
1. On donne la fonction suivante :
let rec mystere lst n = match lst, n with
| [], _ -> [], []
| _, 0 -> [], lst
| x :: q, _ -> let lst1, lst2 = mystere q (n - 1) in x :: lst1, lst2;;

Déterminer la signature de la fonction mystere et donner une description de ce qu’elle fait.


2. Écrire une fonction avant_dernier : ’a list -> ’a qui renvoie l’avant-dernier élément d’une
liste. On écrira un message d’erreur si nécessaire.

Problème
On définit les arbres (binaires entiers) de la façon suivante :
- Une feuille est un arbre.
- Si g et d sont deux arbres, le couple (g, d) est un arbre.
Un arbre de la forme (g, d) est un nœud interne, dont g est le fils gauche et d le fils droit. Par la suite, on note
An l’ensemble des arbres possédant n feuilles (n ≥ 1). Les feuilles d’un arbre de An sont numérotées de 1 à n
dans l’ordre d’un parcours postfixe (dit aussi en profondeur d’abord) et de gauche à droite.

Un flot f de taille n est une suite de n entiers égaux à 1, 2 ou 3. Pour un arbre a de An fixé, cette suite
définit une fonction des sous-arbres de a dans les entiers, également notée f .
La fonction f associe le i-ème entier du flot f à la i-ème feuille de l’arbre a, et elle s’étend récursivement aux
nœuds internes, par la formule :
f ((g, d)) = f (g) + f (d) (modulo 4),
c’est-à-dire que si a = (g, d), alors f (a) est le reste de la division euclidienne par 4 de la somme f (g) + f (d).
On note Fn l’ensemble des flots de taille n. Un flot f de Fn est dit compatible avec un arbre a de An si, pour
tout nœud interne x de a, on a : f (x) 6= 0. La figure suivante représente un arbre a à 5 feuilles (dont les nœuds
internes sont désignés par x1 , . . . , x4 ), et deux flots. On notera que le premier flot est compatible avec a, tandis
que le second ne l’est pas, car f2 (x3 ) = 0.

x4 3 1

x1 x3 2 1 1 0

x2 3 1
3 3 2 2 3 3

1 2 3 2
f1 = [3, 3, 1, 2, 2] f2 = [2, 3, 3, 2, 3]

1
Les arbres sont représentés en machine par la structure de donnée usuelle :
type arbre =
| Feuille
| Interne of arbre * arbre;;

1. Écrire une fonction compte_feuilles : arbre -> n qui prend un arbre en argument et renvoie le
nombre de ses feuilles.
2. Dans cette question, a désigne un arbre de An et f un flot de Fn .
(a) Montrer que a possède n − 1 nœuds internes.
(b) On suppose que a n’est pas réduit à une feuille et on écrit a = (g, d). Soit f un flot compatible avec
a. En fonction des valeurs possibles de f (a), donner les valeurs possibles que peut prendre le couple
(f (g), f (d)).
(c) On pose F (a, v) le nombre de flots compatibles avec a tels que f (a) = v, pour v ∈ {1, 2, 3}. Montrer
par récurrence que F (a, v) ne dépend que de a et que F (a, v) = 2n−1 . En déduire le nombre de flots
compatibles avec a.
3. Un flot sera représenté par le type suivant :

type flot = int array;;

On cherche à écrire une fonction compatible : flot -> arbre -> bool qui teste la compatibilité d’un
flot avec un arbre. On complètera, avec des explications, la fonction écrite ci-dessous (qu’on ne demande
pas de réécrire complètement) :

let compatible f a =
let num_feuille = ref (-1) in
let b = ref true in
let rec image_par_f = function
| Feuille -> incr num_feuille; f.(!num_feuille)
| Interne(g, d) -> (* Partie à compléter *)
in let fa = image_par_f a in
!b;;

4. On représente maintenant un flot de la manière suivante :

type flot = int list;;

(difficile) Écrire une fonction compatible : flot -> arbre -> bool qui teste la compatibilité d’un
flot avec un arbre. On interdira l’usage de références et de boucles dans cette fonction.
5. On pose Cn = Card(An ) le nombre d’arbres à n feuilles.
(a) Déterminer une formule de récurrence permettant de calculer Cn en faisant intervenir tous les Ck ,
pour k ∈ [[1; n − 1]].
(b) En déduire une fonction catalan : int -> int array telle que catalan n renvoie un tableau t
de taille n tel que c.(i) vaut Ci pour tout i ∈ [[1, n − 1]].
(c) Déterminer le nombre de multiplications effectuées par la fonction précédente.
6. (très difficile) Écrire une fonction genere_arbre : int -> int -> arbre qui prend en argument un
entier n et un nombre m compris entre 0 et Cn − 1 et renvoie un arbre de An . Deux entiers différents
doivent renvoyer un arbre différent. On supposera pour cette question que le tableau donné par la fonction
catalan a été enregistré dans une variable globale c de taille suffisante et ne sera plus modifié.
Indication : On commencera par réfléchir à la numérotation des arbres de An et on considèrera une
partition adéquate de [[0, Cn − 1]].

???

Vous aimerez peut-être aussi