« INFO401 corr TD TP » : différence entre les versions

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche
Ligne 17 : Ligne 17 :
Le but est de calculer la fonction <math>!n = 1\times2\times \cdots \times n</math> par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :
Le but est de calculer la fonction <math>!n = 1\times2\times \cdots \times n</math> par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :


<source lang="ocaml">
(* fonction factorielle : c'est la factorielle habituelle des mathématiciens... *)
(* fonction factorielle : c'est la factorielle habituelle des mathématiciens... *)
let rec fact (n:int) : int =
if (n>1)
let rec fact (n:int) : int =
then n * (fact (n-1))
if (n>1)
then n * (fact (n-1))
else 1 (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n<1 *)
else 1 (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n<1 *)
</source>


Comme la fonction est récursive, il ne faut pas oublier le <tt>rec</tt> au début de la définition.
Comme la fonction est récursive, il ne faut pas oublier le <tt>rec</tt> au début de la définition.
Ligne 28 : Ligne 30 :
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :


<source lang="ocaml">
let rec fact' = function
let rec fact' = function
n when (n>0) -> n * fact' (n-1)
| n when (n<0) -> n * fact' (n+1)
n when (n>0) -> n * fact' (n-1)
| n when (n<0) -> n * fact' (n+1)
| _ -> 1 (* si n n'est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)
| _ -> 1 (* si n n'est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)
</source>


J'ai volontairement mis une version qui contient plusieurs choses que nous n'avons pas encore vues en cours :
J'ai volontairement mis une version qui contient plusieurs choses que nous n'avons pas encore vues en cours :
Ligne 40 : Ligne 44 :
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :


<source lang="ocaml">
let rec fact_bis = fun n ->
let rec fact_bis = fun n ->
if (n=0)
then 1
if (n=0)
then 1
else begin
else begin
if (n>0)
then n*fact_bis (n-1)
if (n>0)
else n*fact_bis (n+1) (* dans ce cas, n est forcement négatif *)
then n*fact_bis (n-1)
else n*fact_bis (n+1) (* dans ce cas, n est forcement négatif *)
end
end
</source>

Version du 23 janvier 2009 à 09:54

Préliminaires

Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le wiki du cours ou directement sur des articles de Wikipedia. La documentation de mediawiki se trouve ici.

Un truc important : pour rentrer du code Caml, il faut mettre les balises <source lang="ocaml">...</source>" autour de votre code. Allez par exemple voir le début de la section sur le TD1 et TP0.


Vous pouvez aller discuter des corrections dans les sujets de discussions associes...

Le TD1 et le TP0

Pour vous montrer un exemple de ce que j'attends, voila la correction de la fonction factorielle. (C'était facile...) J'ai volontairement mis beaucoup de commentaires...


La fonction factorielle (TD1, exercice 2, question 2)

Le but est de calculer la fonction par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :

<source lang="ocaml"> (* fonction factorielle : c'est la factorielle habituelle des mathématiciens... *) let rec fact (n:int) : int =

 if (n>1)
 then  n * (fact (n-1))
 else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n<1 *)

</source>

Comme la fonction est récursive, il ne faut pas oublier le rec au début de la définition.


On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :

<source lang="ocaml"> let rec fact' = function

  n when (n>0) -> n * fact' (n-1)
| n when (n<0) -> n * fact' (n+1)
| _ -> 1  (* si n n'est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)

</source>

J'ai volontairement mis une version qui contient plusieurs choses que nous n'avons pas encore vues en cours :

  • utilisation de "function" plutôt que fun,
  • le symbole "|",
  • le mot clé "when".

Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :

<source lang="ocaml"> let rec fact_bis = fun n ->

 if (n=0)
 then 1
 else begin
   if (n>0) 
   then n*fact_bis (n-1)
   else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)
 end

</source>