Vous êtes sur la page 1sur 3

MPSI DS 1 Option Informatique MPSI DS 1 Option Informatique

|[]::l'->aplatir l'

DEVOIR SURVEILLE n°1 |(t::q)::l' -> t::(aplatir (q::l'));;

4.Écrire une fonction racine x eps de type float -> float -> float récursive, qui retourne √x
corrigé avec une précision de eps, en utilisant l’algorithme suivant, appelé algorithme de
Babylone :
 u0 = 1

Exercice 1 : Questions diverses et variées  1 x 
un +1 = 2  un + u 
  n 

1.Donner le type de l’expression suivante : let f g x = g x + 2023;; qui s’arrête lorsque un +1 − un < eps ⇔ un −
x
< 2 × eps .
un
f : ('a -> int) -> 'a -> int
- Version récursive :
g est clairement une fonction qui s’applique à l’argument x de type quelconque ‘a et qui let racineR x eps =
renvoie un entier car f renvoie ce dernier augmenté de l’entier 2018 ; en conséquence, g a let rec aux u =
let ecart = abs_float (u -. x/.u) in
pour type 'a -> int et f a pour type ('a -> int) -> 'a -> int. if ecart <2.*. eps then u else aux (0.5*.(u+.x/.u))
in aux 1.;;
2.Écrire une fonction produit : (float -> float) -> int -> int -> float telle que, pour f : → et
- Version itérative :
n≤ m∈
m
, (produit f n m) calcule le produit : Õ f (k) .
k= n
let racineI x eps =
- Version récursive : let u = ref 1. in
while abs_float (!u -. x/. !u) >=2.*.eps do
let rec produit f n m = u := 0.5*.(!u +.x/. !u)
match n with done;
|n when n = m -> f (float_of_int n) !u;;
|_ -> (f (float_of_int n)) *. (produit f (n+1) m);;
5.Écrire une fonction est_triee : 'a list -> bool qui prend comme argument une
- Version itérative :
liste et renvoie le booléen true si la liste est triée par ordre croissant, et false dans tout
let rec produit f n m = autre cas.
let p = ref 1.0 in
for i = n to m do
p := !p*. f (float_of_int i); - Version 1 :
done;
!p;; let rec est_triee l =
match l with
En déduire la fonction factorielle : int -> int. |[] -> true
|[t] -> true
let factorielle n = int_of_float(produit (function i -> i) 1 n);; |t1::t2::q -> t1 <= t2 && (est_triee (t2::q));;

3.Ecrire une fonction aplatir l qui transforme une liste de listes en une liste simple ; par - Version 2 : avec fonction auxiliaire et accumulateur (permettant de stocker l’élément
exemple, aplatir [[1] ;[2 ;3] ;[4 ;5 ;6]] doit renvoyer [1 ;2 ;3 ;4 ;5 ;6]. précédent) :

- Version avec @ (on ajoute d’un coup tous les éléments de la sous-liste): let est_triee l =
rec aux tete queue =
let rec aplatir l = match queue with
match l with |[] -> true
|[] -> [] |t::q when t < tete -> false
|t::q -> t@(aplatir q);; |t::q -> aux t q
in match l with
- Version sans @ (on ajoute un à un les éléments de la sous-liste): |[] -> true
|t::q -> aux t q
let rec aplatir l = ;;
match l with
|[] -> []
P. CHATEL - 1/6 - 22/03/2023 P. CHATEL - 2/6 - 22/03/2023
MPSI DS 1 Option Informatique MPSI DS 1 Option Informatique

6. Écrire une fonction decomposition : int -> int -> int list qui prend else let v = duree_vol i in
if v > vm then aux (i+1) v [i]
en argument un entier n et un entier b (compris entre 2 et 10) et retourne comme résultat
else if v = vm then aux (i+1) vm (i ::lm)
la décomposition de n en base b sous forme d'une liste. else aux (i+1) vm lm
in aux 1 0 [];;
- Version où chiffres dans ordre inverse :
max_duree_vol_alt 20;;
let rec decomposition n b =
if n < b then [n] else (n mod b)::(decomposition (n/b) b);;
for i = 1 to 20 do
- Version où chiffres dans bon ordre : print_int (duree_vol i);print_string" ";
done;;
let rec decomposition n b =
let rec aux n d =
if n < b then n::d Problème 2 : Ensembles
else aux (n/b) ((n mod b)::d)
in aux n [];; On représente un ensemble (fini) d'objets par la liste de ses éléments. La liste vide représente donc l'ensemble vide.
Une liste représente un ensemble si et seulement si elle est sans doublons, i.e. les éléments n'apparaissent qu'une
Problème 1 : Suite de Syracuse seule fois dans la liste.

let f a =
1. Fonction valide qui calcule le booléen indiquant si une liste représente effectivement un ensemble.
if a mod 2 = 0 then a/2 else 3*a + 1 ;;
La liste vide (qui représente l’ensemble vide) est valide et une liste est valide si on ne retrouve pas sa tête
let rec u a n = dans sa queue.
match n with
| 0 -> a let rec valide ens =
| n-> u (f a) (n-1) ;; match ens with
| [] -> true (* ensemble vide *)
let rec termes u0 = | e :: ens' when List.mem e ens' -> false (* e est un doublon *)
match u0 with | _ :: ens' -> valide ens';; (* il ne faut pas de doublon dans la queue *)
| 1 -> [1]
| _ -> u0 ::termes (f u0) ;; #valide [1; 3; 4; 8; 2];;
- : bool = true
let rec duree_vol u0 = #valide [1; 3; 4; 3; 2];;
match u0 with - : bool = false
|1 -> 0
| _ -> 1 + duree_vol (f u0) ;;
2. Fonction unique , qui supprime les doublons d'une liste : unique [1; 2; 1; 0; 3; 2] calcule la
let rec altitude_vol u0 = liste [1; 2; 0; 3] .
match u0 with
|1 -> 1 La liste vide ne présente pas de doublon. Sinon si la tête de la liste se retrouve dans sa queue, on la supprime
| _ -> let a = altitude_vol(f u0) in max u0 a ;; et dans le cas contraire, on la garde ; ainsi, seul le dernier exemplaire de chaque valeur sera conservé.

let duree_vol_alt u0 = let rec unique liste =


let rec aux a n = match liste with
if a < u0 then n else aux (f a) (n+ 1) | [] -> [] (* évidemment pas de doublon dans ce cas !*)
in aux (f u0) 0 ;; | t :: q when List.mem t q -> unique q (* t étant déjà dans la queue, on le
supprime une première fois *)
| t :: q -> t :: (unique q);; (* t n’est pas un doublon; on le conserve *)
let u0 = 5 in termes u0, duree_vol u0 ,altitude_vol u0, duree_vol_alt u0 ;; #unique [1; 3; 4; 3; 2];;
- : int list = [1; 4; 3; 2]
let max_duree_vol_alt n =
let rec aux i vm lm =
Autre solution :
if i > n then vm,lm

P. CHATEL - 3/6 - 22/03/2023 P. CHATEL - 4/6 - 22/03/2023


MPSI DS 1 Option Informatique MPSI DS 1 Option Informatique

let rec unique liste =


let rec aux elts liste = (* elts est la liste des éléments déjà rencontrés *) #intersection [3; 2; 8; 1] [5; 1; 3; 7];;
match liste with - : int list = [3; 1]
| [] -> []
| t :: q when mem t elts -> aux elts q 6. Fonction parties qui calcule l'ensemble des parties d'un ensemble.
| t :: q -> t :: (aux (t::elts) q)
in aux [] liste;; Si l’ensemble E est vide, l’ensemble de ses sous-parties ne contient que l’ensemble vide, sinon il faut ajouter
aux sous-parties de E’ = E\{e} les sous-parties de E’ auxquelles on a ajouté e.

3. Fonction inclus qui calcule le booléen indiquant si un ensemble est inclus dans un autre. let rec parties ens =
match ens with
Le premier ensemble est inclus dans le second soit s’il est vide, sinon ou sa tête appartient au second et il | [] -> [[]]
faut alors que sa queue soit incluse dans celui-ci, ou dans le cas contraire, il n’est pas inclus dans le second. | e :: ens' -> let p' = parties ens' in
p' @ (List.map (function l -> e :: l) p');;
let rec inclus ens1 ens2 =
match ens1 with Autre écriture possible :
| [] -> true (* l’ensemble vide est inclus dans tout ensemble *)
| e :: ens1' when List.mem e ens2 -> inclus ens1' ens2 let parties ens =
| _ -> false;; (* tout élément du 1er doit appartenir au 2ieme *) let rec aux p = function
| [] -> p
#inclus [3; 1; 8] [1; 8; 4; 2; 3; 7];; | e :: ens' -> aux (p@(List.map (function l -> e :: l) p)) ens'
- : bool = true in aux [[]] ens;;
#inclus [3; 1; 8] [1; 4; 2; 3; 7];;
- : bool = false #parties [3; 5; 1];;
- : int list list = [[]; [1]; [5]; [5; 1]; [3]; [3; 1]; [3; 5]; [3; 5;
1]]
4. Fonction egal qui calcule le booléen indiquant si deux ensembles sont égaux.

Solution 1 : Deux ensembles sont égaux si l’un est inclus dans l’autre et vice-versa.

let egal ens1 ens2 =


(inclus ens1 ens2) && (inclus ens2 ens1);;

#egal [1; 7; 4] [3; 7; 1; 4];;


- : bool = false
#egal [1; 7; 4] [7; 1; 4];;
- : bool = true

Solution 2 : Deux ensembles finis sont égaux s’ils ont même cardinal et si l’un est inclus dans l’autre.
let egal ens1 ens2 =
(List.length ens1 = List.length ens2) && (inclus ens1 ens2) ;;

5. Fonction intersection qui opère sur les ensembles.

Si le premier ensemble est vide, l’intersection l’est sinon sa tête appartient au second et fait alors partir de
leur intersection si et seulement si elle appartient au deuxième.

let rec intersection ens1 ens2 =


match ens1 with
| [] -> []
| e :: ens1' when List.mem e ens2 -> e :: (intersection ens1' ens2)
(* on ne garde que les éléments du 1er qui sont dans le 2ieme *)
| e :: ens1' -> intersection ens1' ens2;;

P. CHATEL - 5/6 - 22/03/2023 P. CHATEL - 6/6 - 22/03/2023

Vous aimerez peut-être aussi