Skip to content
Snippets Groups Projects
Commit d513e9f7 authored by COQUERY EMMANUEL's avatar COQUERY EMMANUEL
Browse files

Corrigé TP2

parent 66f5967c
No related branches found
No related tags found
No related merge requests found
tp/tp2.ml 0 → 100644
(**********************************************************************)
(**********************************************************************)
(* 1.1 *)
(**
Concatène 2 listes
@param l1 la première liste à concaténer
@param l2 la deuxième liste
@return la liste résultant de la concaténation de l1 avec l2
*)
let rec concatene (l1 : int list) (l2 : int list) : int list =
match l1 with [] -> l2 | x :: l1' -> x :: concatene l1' l2
;;
(* Quelques tests *)
concatene [ 1; 2; 3 ] [ 4; 5; 6 ] = [ 1; 2; 3; 4; 5; 6 ];;
concatene [] [ 4; 5; 6 ] = [ 4; 5; 6 ];;
concatene [ 1; 2; 3 ] [] = [ 1; 2; 3 ];;
concatene [] [] = []
(**********************************************************************)
(* 1.2 *)
(**
applatit prend une liste de liste et renvoie la liste resultant de la concatenation des sous-listes
@param ll la liste contenant les liste à concatener
@return la liste contenant les élements des sous-listes
*)
let rec applatit (ll : int list list) : int list =
match ll with [] -> [] | l :: ll' -> concatene l (applatit ll')
;;
(* Quelques tests *)
applatit [ [ 1; 2 ]; [ 3; 4; 5 ]; []; [ 6 ] ] = [ 1; 2; 3; 4; 5; 6 ];;
applatit [ [ 1 ] ] = [ 1 ];;
applatit [ [] ] = [];;
applatit [] = []
(**
applatit2 prend une liste de liste et renvoie la liste resultant de la concatenation des sous-listes.
applatit2 n'utilise pas concatene
@param ll la liste contenant les liste à concatener
@return la liste contenant les élements des sous-listes
*)
let rec applatit2 (ll : int list list) : int list =
match ll with
| [] -> []
| [] :: ll' -> applatit2 ll'
| (n :: l') :: ll' -> n :: applatit2 (l' :: ll')
;;
(* Quelques tests *)
applatit2 [ [ 1; 2 ]; [ 3; 4; 5 ]; []; [ 6 ] ] = [ 1; 2; 3; 4; 5; 6 ];;
applatit2 [ [ 1 ] ] = [ 1 ];;
applatit2 [ [] ] = [];;
applatit2 [] = []
(**********************************************************************)
(**********************************************************************)
(* 2 *)
(**
Renverse une liste.
@param l la liste à renverse.
@return la liste renversée
*)
let renverse =
(*
Cette fonction concatène son premier argument renversé à son second
@param lr la liste à renverser
@param lc la liste à laquelle on veut concaténer des éléments
@return la concaténation de lr renversée et de lc
*)
let rec renverse_ajoute (lr : int list) (lc : int list) : int list =
match lr with
| [] -> lc
| n :: lr' ->
(* on ajoute n en tête de la liste lc et on fait l'appel récursif
qui ajoutera les autres éléments devant *)
renverse_ajoute lr' (n :: lc)
in
fun (l : int list) -> renverse_ajoute l []
(**********************************************************************)
(**********************************************************************)
(* 3.1 *)
(* Insersion dans une liste triée *)
(**
Insère un entier dans une liste triée.
@param n la valeur à insérer
@param l la liste dans laquelle on fait l'insertion
@return une nouvelle liste contenant les élément de l et n et elle-même
*)
let rec insertion (n : int) (l : int list) : int list =
match l with
| [] -> [ n ] (* on aurait pu écrire [n] *)
| k :: l' ->
if k >= n (* on veut placer n en tête de liste *) then n :: l
(* attention c'est n :: l et pas n :: l'
on aurait aussi pu écrire n :: k :: l' *)
else k :: insertion n l'
;;
(* Quelques tests*)
insertion 3 [ 1; 2; 4; 5 ] = [ 1; 2; 3; 4; 5 ];;
insertion 3 [ 1; 2; 3; 4; 5 ] = [ 1; 2; 3; 3; 4; 5 ];;
insertion 3 [ 4; 5 ] = [ 3; 4; 5 ];;
insertion 3 [ 1; 2 ] = [ 1; 2; 3 ];;
insertion 3 [] = [ 3 ]
(**********************************************************************)
(* 3.2 *)
(**
Trie une liste en utilisant l'algorithme de tri par insertion
@param l la liste à trier
@return la liste contenant les éléments de l triés
*)
let rec tri_insertion (l : int list) : int list =
match l with
| [] -> []
| n :: l' ->
(* Ici, on insère dans le reste de la liste triée *)
insertion n (tri_insertion l')
;;
(* Quelques tests *)
tri_insertion [ 1; 4; 2; 3 ] = [ 1; 2; 3; 4 ];;
tri_insertion [ 1; 2; 3; 4 ] = [ 1; 2; 3; 4 ];;
tri_insertion [ 4; 3; 2; 1 ] = [ 1; 2; 3; 4 ];;
tri_insertion [ 1 ] = [ 1 ];;
tri_insertion [] = []
(**********************************************************************)
(**********************************************************************)
(* 4.1 *)
(**
Résultat d'une recherche
*)
type resultat =
(* une valeur a été trouvée,
on associe la donnée de cette valeur au constructeur,
elle a donc le type string*)
| Trouve of string
(* On a rien trouvé, pas de donnée associée *)
| Rien
(* 4.2 *)
(**
Cherche la valeur associée à une clé dans une liste de paires (clé,valeur).
@param cle la clé
@param la la liste d'association
@return Trouve v si la paire (cle,v) est dans la liste, Rien sinon
*)
let rec cherche (cle : int) (la : (int * string) list) : resultat =
match la with
| [] -> Rien
| (cle', v) :: la' ->
if cle' = cle (* si on a trouvé la clé *) then Trouve v
else (* on cherche dans le reste de la liste *)
cherche cle la'
;;
(* Quelques tests *)
cherche 3 [ (1, "a"); (3, "b"); (5, "c") ] = Trouve "b";;
cherche 3 [ (3, "b"); (5, "c") ] = Trouve "b";;
cherche 3 [ (1, "a"); (3, "b") ] = Trouve "b";;
cherche 3 [ (5, "b"); (1, "a") ] = Rien;;
cherche 3 [] = Rien
(**********************************************************************)
(**********************************************************************)
(**
Type représentant les opérateurs binaires.
*)
type binop = Plus | Moins | Mult | Div
(**
Type représentant les morceaux d'expression.
*)
type elt_expr = Op of binop | Cst of int
(**
Type représentant les résultats.
*)
type resultat =
| Ok of int
| ErrDivZero
| ErrExpr
(**
Évalue le résultat d'une opération binaire.
Prend l'opération en argument ainsi que deux résultats.
S'il l'un des arguments est une erreur, cette (une de ces)
erreur est renvoyée comme résultat.
@param op l'opération à effectuer
@param a1 la première valeur à passer à op
@param a2 la deuxième valeur à passer à op
@return le réultat de l'opération ou une erreur le cas échéant
*)
(* 5.1 *)
let eval_op (op : binop) (a1 : resultat) (a2 : resultat) : resultat =
match (a1, a2) with
| Ok v1, Ok v2 -> (
match op with
| Plus -> Ok (v1 + v2)
| Moins -> Ok (v1 - v2)
| Mult -> Ok (v1 * v2)
| Div -> if v2 = 0 then ErrDivZero else Ok (v1 / v2))
| Ok _, err -> err
| err, _ -> err
;;
(* Quelques tests *)
eval_op Plus (Ok 1) (Ok 2) = Ok 3;;
eval_op Moins (Ok 2) (Ok 3) = Ok (-1);;
eval_op Div (Ok 3) (Ok 0) = ErrDivZero;;
eval_op Div (Ok 5) (Ok 2) = Ok 2;;
eval_op Mult (Ok 7) (Ok 6) = Ok 42;;
eval_op Plus ErrDivZero (Ok 5) = ErrDivZero;;
eval_op Mult ErrExpr (Ok 4) = ErrExpr;;
eval_op Div (Ok 5) ErrExpr = ErrExpr;;
eval_op Moins (Ok 4) ErrDivZero = ErrDivZero;;
eval_op Plus ErrDivZero ErrExpr = ErrDivZero
(**********************************************************************)
(* 5.2 *)
(**
Évalue une suite d'expressions et donne la liste des résultats
@param la liste d'éléments d'expression formant la liste suite d'expressions
@return le résultat de l'évaluation des expressions
*)
let rec eval_expr (le : elt_expr list) : resultat list =
match le with
| [] -> []
| Cst n :: le' -> Ok n :: eval_expr le'
| Op op :: le' -> (
match eval_expr le' with
| r1 :: r2 :: rl -> eval_op op r1 r2 :: rl
| _ -> [ ErrExpr ])
;;
(* Quelques tests *)
eval_expr [ Cst 3 ] = [ Ok 3 ];;
eval_expr [ Op Mult; Cst 3; Cst 2 ] = [ Ok 6 ];;
eval_expr [ Op Div; Cst 7; Cst 3 ] = [ Ok 2 ];;
eval_expr [ Op Moins; Cst 3; Cst 1 ] = [ Ok 2 ];;
eval_expr [ Op Plus; Op Div; Cst 7; Cst 3 ] = [ ErrExpr ];;
eval_expr [ Op Plus; Op Div; Cst 7; Cst 3; Cst 5 ] = [ Ok 7 ];;
eval_expr [ Op Plus; Op Div; Cst 7; Op Moins; Cst 2; Cst 2; Cst 3 ]
= [ ErrDivZero ]
;;
eval_expr [ Op Plus; Cst 3; Cst 5; Op Moins; Cst 2; Cst 7 ] = [ Ok 8; Ok (-5) ]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment