Skip to content
Snippets Groups Projects
tp2.ml 7.89 KiB
Newer Older
  • Learn to ignore specific revisions
  • COQUERY EMMANUEL's avatar
    COQUERY EMMANUEL committed
    (**********************************************************************)
    (**********************************************************************)
    (* 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) ]