Aller au contenu

C6 OCaml : aspects fonctionnels

"An industrial-strength functional programming language with an emphasis on expressiveness and safety"
ocaml.org
(Site officiel d'OCaml)

Cours

Support de cours chapitre 6

Attention

Ce diaporama ne vous donne que quelques points de repères lors de vos révisions. Il devrait être complété par la relecture attentive de vos propres notes de cours et par une révision approfondie des exercices.

Travaux dirigés

Fiche de TD6

Travaux pratiques

▪ Exercice 1 : Un notebook pour démarrer

A propos des notebooks

Dans cette activité, on utilise pour la première fois les jupyter notebook, c'est-à-dire des documents contenant à la fois :

  • des zones de texte explicatives,
  • des zones de code Ocaml, executables directement à la façon de ce qui se passe lorsqu'on utilise l'environnement utop de OCaml.

A chaque fois, que nous utilisons cet outil, deux choix s'offrent à vous :

  1. l'utiliser localement sur votre ordinateur à condition d'y avoir installé jupyter notebook (c'est le cas sur les ordinateurs de la salle). Pour cela, créer un dossier nommé par exemple Notebook et depuis un terminal lancer jupyter dans ce dossier en écrivant simplement :

    jupyter notebook
    
    L'application se lance dans votre navigateur, télécharger le notebook et utiliser le bouton Téléverser en haut à droit pour le télécharger dans votre dossier et l'ouvrir.

  2. Utiliser l'application Capytale de votre environnement numérique de travail metice. Dans ce cas, utiliser le lien de partage fourni dans l'activité. Cette option vous permet notamment de travailler depuis la maison car aucune installation (ni de OCaml, ni de Jupyter) n'est nécessaire.

Les activités utilisant un notebook proposerons donc toujours les deux options décrites ci-dessus.

  • Télécharger le notebook pour l'utiliser en local (installation de jupyter nécessaire)Notebook : Premiers pas en OCaml
  • Utiliser l'application Capytale (aucune installation nécessaire)logo capytale

▪ Exercice 2 : Quelques évaluations

  1. Prédire le type et la valeur des expressions suivantes, vérifier en les évaluant dans utop :

    • (7.-5.) *. 3.
    • 14 mod 3
    • (6+6)/2
    • 5/2
    • 'a'
    • "Ocaml"
    • "Hello" ^ " World"
    • 3.0 ** 2
    • 9 < 8
    • 7 <> 5
    • "Incroyable".[5]
  2. Effectuer les calcul suivants à l'aide d'Ocaml :

    • Reste dans la division euclidienne de 2023 par 312
    • Quotient dans la division euclidienne de 7777 par 42
    • \(7^4\)
    • \(\dfrac{14 + 9}{25-3\times7}\)

▪ Exercice 3 : Quelques erreurs ...

  1. Prédire l'évaluation de chacune des expressions ci-dessous

    • let a = 5. + 2
    • if true then 1 else 2.0
    • let b = -3.14
    • 'z' = "z"
    • let s = "Python" in s.[0] = 'C'
    • abs(-2.718)
    • let z = 2.0**5
    • let s = "OCaml" in if s.[1]="C" then true else false
  2. Vérifier en testant dans utop (et expliquer)

Note

Pour les exercices suivants, on pourra au choix continuer à travailler dans utop soit faire les premières compilations.

▪ Exercice 4 : Ou exclusif

  1. Ecrire une fonction xor en OCaml qui prend en argument deux booléens a et b et renvoie true lorsque l'un des deux est vrai et false sinon

  2. Donner une écriture de cette fonction en utilisant un filtrage par motif

▪ Exercice 5 : Quelques fonctions élémentaires

  1. Ecrire une fonction perimetre_cercle : float -> float qui prend en argument un flottant r et renvoie le perimètre du cercle de rayon r, on utilisera une valeur de pi de 3.14 définie dans un environnement local.

  2. Ecrire une fonction discriminant : float -> float -> float -> float qui prend en argument trois flottants \(a, b\) et \(c\) et renvoie \(b^2 - 4ac\).

  3. Ecrire une fonction est_pair : int -> bool qui renvoie true lorsque l'entier donné en argument est pair.

  4. Ecrire une fonction mention : float -> string qui renvoie la mention au bac associée à la moyenne donnée en argument par exemple mention 12.8 donne "Assez-bien".

  5. Ecrire une fonction fact : int -> int qui renvoie la factorielle de l'entier donné en argument.

▪ Exercice 6 : Termes d'une suite

Ecrire une fonctions suite qui prend en argument un entier n et renvoie le  n-ième terme de la suite \(u\) définie par \(u_0=1\) et \(u_{n+1} = 2 u_n + 3\)

▪ Exercice 7 : Dessiner (sans boucles)

  1. Ecrire une fonction repete qui prend en argument un caractère car et un entier n et affiche n fois ce caractère à l'écran puis passe à la ligne

  2. En utilisant la fonction précédente écrire la fonction triangle qui prend en argument un caractère car et un entier n et dessine un triangle de ce caractère. Par exemple :

    utop # triangle '*' 5;;
    *****
    ****
    ***
    **
    *
    

  3. Même question mais en affichant le triangle "pointe vers le haut" :

    utop # triangle2 '*' 5;;
    *
    **
    ***
    ****
    *****
    

▪ Exercice 8 : Type figure

On considère le type union suivant permet de représenter des figures géoémtriques :

type figure = 
| Cercle of float 
| Carre of float 
| Rectangle of float*float;;
  1. En utilisant une correspondance de motif, écrire une fonction perimetre qui renvoie le perimetre d'une figure

  2. Définir la variable rect représentant un rectangle de dimension \(3\times9\) et calculer son aire à l'aide de la fonction précédente.

  3. Reprendre les questions précédentes pour l'aire.

▪ Exercice 9 : Type nombre

  1. Créer le type union nombre pouvant être un entier ou un flottant
  2. A l'aide d'un filtrage par motif, écrire une fonction addition qui prend en argument deux variables de type nombre et renvoie leur somme.

▪ Exercice 10 : Type couleur

  1. Créer le type produit couleur sous la forme d'un triplet de trois entiers.
  2. Le négatif d'une couleur \((x,y,z)\) est la couleur \((255-x, 255-y, 255-z)\). Ecrire une fonction prenant une couleur comme paramètre et renvoyant son négatif.
  3. A l'aide d'un filtrage par motif écrire une fonction qui affiche :

    • Rouge pur si la composante rouge est strictement positive et les deux autres composantes sont nulles,
    • Vert pur si la composante verte est strictement positive et les deux autres composantes sont nulles,
    • Bleu pur si la composante bleue est strictement positive et les deux autres composantes sont nulles,
    • Mélange dans les autres cas.

▪ Exercice 11 : Chaines de caractères

Aide

  • On rappelle que le caractère d'indice i de la chaine chaine s'obtient avec la notation chaine.[i]
  • La fonction String.sub prend en argument une chaine et deux indices et renvoie la sous chaine entre ces deux indices. Par exemple String.sub "OCaml" 1 3 renvoir  "Cam".
  1. Ecrire une fonction est_dans qui prend en argument une chaine de caractères chaine et un caractère car et renvoie true si car se trouve dans chaine et false sinon
  2. Ecrire une fonction compte_occurence qui prend en argument une chaine de caractères chaine et un caractère car et renvoie le nombre d'apparition de car dans chaine

▪ Exercice 12 : Création de liste

  1. Ecrire une fonction cree_liste qui prend en argument un élément elt et un entier rep et qui crée la liste constituée de rep fois l'élément elt. Par exemple cree_liste 42 3 renvoie la liste [42; 42; 42]
  2. Ecrire la fonction entiers qui prend en argument un entier n et renvoie la liste des entiers [1,2,..,n]. Par exemple entiers 5 renvoie [1; 2; 3; 4; 5].
  3. Ecrire une fonction double qui prend en argument une liste et renvoie la liste dans laquelle chaque élément de l a été dupliqué. Par exemple double [3; 6; 7] renvoie la liste [3; 3; 6; 6; 7; 7;].
  4. Ecrire la fonction mult_liste qui prend en argument une liste et un entier rep et qui crée la liste constituée de rep répétitions de la liste. Par exemple mult_liste [1; 4; 2] 3 renvoie la liste [1; 4; 2; 1; 4; 2; 1; 4; 2]

▪ Exercice 13 : Somme, moyenne, maximum, minimum

  1. Ecrire une fonction somme_int qui prend en argument une liste d'entiers et renvoie la somme de ces entiers.

  2. Ecrire une fonction moyenne_float qui prend en argument une liste non vide de flottants et renvoie leur moyenne.

  3. Ecrire une fonction minimum qui renvoie le minimum de la liste non vide de nombres donnée en argument.

  4. Ecrire une fonction indice_max qui renvoie la liste des indices des occurrences du maximum des éléments de la liste (non vide) donnée en argument.

▪ Exercice 14 : Indice d'un element

Ecrire une fonction indice qui prend en argument un entier n et une liste d'entiers l et qui renvoie l'indice de la première occurrence de n dans l. On renvoie -1 si n n'appartient pas à l. Par exemples :

  • indice 3 [1; 6; 7; 2; 3; 0] renvoie 4
  • indice 1 [1; 6; 7; 2; 3; 0] renvoie 0
  • indice 5 [1; 6; 7; 2; 3; 0] renvoie -1

▪ Exercice 15 : Suppression d'un élément

  1. Ecrire une fonction supprime qui prend en argument une liste l et une valeur v et supprime toutes les occurrences de v dans l.
  2. Même question en supprimant seulement la première occurrence
  3. Même question en supprimant seulement la dernière occurrence

▪ Exercice 16 : Retourner une liste

Ecrire une fonction retourne qui prend en argument une liste et renvoie la liste retournée (c'est-à-dire avec les éléments dans l'ordre inverse). Par exemple retourne [2; 4; 5; 1] renvoie la liste [1; 5; 4; 2]

Remarque

Cette fonction existe déjà, c'est List.rev

▪ Exercice 17 : Doublons dans une liste

  1. Ecrire une fonction sans_doublons_triee qui prend en argument une liste d'entiers triée et renvoie true si cette liste ne contient pas de doublons. Par exemple sans_doublons_triee [2; 5; 5; 8; 10] doit renvoyer  false.

  2. Ecrire une fonction elimine_doublons_triee qui prend en argument une liste d'entiers triée et renvoie cette liste en supprimant tous les doublons éventuels qui s'y trouvent. Par exemple elimine_doublons_triee [2; 5; 5; 8; 10] doit renvoyer [2; 5; 8; 10]

  3. Ecrire une fonction compare qui prend en argument deux entiers a et b et renvoie -1 si a<b, 0 si a=b et 1 si a>b

  4. Une fonction de tri de liste existe déjà en OCaml, c'est List.sort qui prend en argument une fonction de comparaison (telle que celle définie à la question précédente) et une liste et renvoie la liste triée en utilisant la fonction de comparaison. Tester cette fonction.

  5. Ecrire les fonctions des questions 1 et 2 pour des listes quelconques (non forcément triées) en utilisant List.sort

  6. Même question sans utiliser List.sort

▪ Exercice 18 : Liste monotone

Ecrire une fonction monotone qui prend en argument une liste et renvoie un booléen indiquant si la liste donnée en argument est monotone ou non.

Aide

On pourra dans un premier temps écrire deux fonctions croissante et décroissante avant de trouver une solution plus concise.

▪ Exercice 19 : Partition suivant un prédicat

  1. Ecrire une fonction separe qui prend en argument une liste et renvoie deux listes : celles des éléments positifs ou nuls et celle des éléments négatifs. Par exemple separe [2; -3; -2; -1; 7; -4] renvoie les liste [2; 7] et [-3; -2; -4].

  2. En s'inspirant de l'exemple précédent écrire une fonction separe_bis qui prend de plus en argument une fonction qui renvoie un booléen (et s'applique aux éléments de la liste) et renvoie deux listes : celles pour laquelle l'application de la fonction renvoie true et celle pour laquelle l'application de la fonction renvoie false.

▪ Exercice 20 : Exercices en ligne

Le site officiel de la fondation Ocaml, propose des exercices progressifs à faire en ligne directement dans le navigateur.

Humour d'informaticien

Webcomic Credit : Hmm-la-bd cc by-nc