TD 1, corrigé de l'exercice 4
1 Version avec des chaînes de caractères
On utilisera ici la fonction sous_chaîne
vue en cours.
Question 1.1
#let rec calc_préfixe = function str ->
if str = "" then 0 else
if string_length str = 1 then 1 else
if str.[0] = str.[2] then 1 + (calc_préfixe (sous_chaîne str 2)) else 1;;
calc_préfixe : string -> int = <fun>
Question 1.2
#let rec genere_ligne = function str ->
if str = "" then "" else
let nb = calc_préfixe str in
(string_of_int nb) ^ " " ^ (sub_string str 0 2) ^
(genere_ligne (sous_chaîne str (2 * nb)));;
genere_ligne : string -> string = <fun>
Question 1.3
#let rec do_it = function p -> function str ->
if p = 0 then str ^ " \n" else
let str2 = genere_ligne str in str ^ " \n" ^ (do_it (p-1) str2);;
do_it : int -> string -> string = <fun>
#
let genere = function k ->
if k <= 0 then failwith "k doit etre strictement positif"
else do_it (k-1) "1 ";;
genere : int -> string = <fun>
Question 1.4
#let ecrit_suite = function k -> print_string (genere k);;
ecrit_suite : int -> unit = <fun>
Remarques :
-
Pour une version efficace de ces fonctions, il faudrait par
exemple passer les longueurs de chaîne argument en paramètre et la
tenir à jour au fur et à mesure des appels récursifs pour éviter de
re-parcourir la chaîne à chaque appel.
- La fonction
calc_préfixe
n'a pas besoin d'être récursive
puisqu'il n'y aura jamais de suite de chiffres identiques de longueur
supérieure à 3, mais une version non récursive n'est pas valable sans
la démonstration de la propriété sur laquelle elle s'appuie.
2 Version avec des listes
Question 2.1
#let rec calc_préfixe = function lst ->
match lst with
| [] -> 0
| [x] -> 1
| x1::x2::l -> if x1 = x2 then 1 + (calc_préfixe (x2::l)) else 1;;
calc_préfixe : 'a list -> int = <fun>
Question 2.2
#let rec génère_ligne = function lst ->
if lst = [] then [] else
let nb = calc_préfixe lst in
nb::(hd lst)::(génère_ligne (iter nb tl lst));;
génère_ligne : int list -> int list = <fun>
Remarque : Les fonctions hd et tl sont les
noms prédéfinis des fonctions tête et reste du
cours; iter est la fonction d'itération définie dans le cours
sur l'ordre supérieur; iter n tl lst est la liste
lst privée de ses n premiers éléments. On aurait pu
écrire directement cette fonction de la façon suivante :
#let rec reste_n = function n -> function lst ->
if n = 0 then [] else reste_n (n-1) (tl lst);;
reste_n : int -> 'a list -> 'b list = <fun>
Question 2.3
#let rec génère = function k ->
if k = 1 then [[1]] else
let res = génère (k-1) in
(génère_ligne (hd res))::res;;
génère : int -> int list list = <fun>
Question 2.4
On utilise ici la séquence dénotée par le point virgule « ; »,
les fonctions print_int
et print_string
et
l'itérateur do_list
qui répète une action sur tous les éléments
d'une liste (à l'instar de map qui retourne le résultat de
l'application de la même fonction à tous les éléments d'une liste).
#let rec écrit_suite = function k ->
do_list (function lst ->
do_list (function k -> print_int k; print_string " ") lst;
print_newline ())
(génère k);;
écrit_suite : int -> unit = <fun>
Ce document a été traduit de LATEX par
HEVEA.