<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nicolas</id>
	<title>Wiki du LAMA (UMR 5127) - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nicolas"/>
	<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php/Sp%C3%A9cial:Contributions/Nicolas"/>
	<updated>2026-04-18T20:59:36Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3857</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3857"/>
		<updated>2009-02-24T17:05:38Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 1 : Tuples&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 4 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Avantage de la première forme (à plusieurs arguments): Elle permet une application partielle: on peut appliquer cette fonction à une seule partie des arguments.&lt;br /&gt;
&lt;br /&gt;
Inconvénients de la seconde forme (à un argument): &lt;br /&gt;
*il faut faire appel à fst, snd;&lt;br /&gt;
*Caml doit séparer les paires: c&#039;est une perte de temps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 2 : Listes&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
suite à l&#039;étude des fonctions &lt;br /&gt;
*longueur&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec longueur l=&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt;0&lt;br /&gt;
     | _ :: l -&amp;gt; 1+longueur l&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*applique&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec app f p =&lt;br /&gt;
     match p with &lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: p -&amp;gt; f(a) :: app f p&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*concatene&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec cat l1 l2 =&lt;br /&gt;
     match l1 with&lt;br /&gt;
     [] -&amp;gt; l2&lt;br /&gt;
     | a :: l -&amp;gt; a :: (cat l l2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*renverse,&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec renverse l =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: l -&amp;gt; (renverse l)@[a]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
on remarque des similitudes. Ces fonctions ont le même schéma de base ( celui de la fonction reduit) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec reduit l o f =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; o&lt;br /&gt;
     | a :: l -&amp;gt; f a (reduit l o f)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;NB :&#039;&#039; val reduit : &#039;a list -&amp;gt; &#039;b -&amp;gt; (&#039;a -&amp;gt; &#039;b -&amp;gt; &#039;b) -&amp;gt; &#039;b = &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 6 :&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Reprogrammons les fonctions précédentes à partir de la fonction reduit ! &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let longueur l =&lt;br /&gt;
     let f _ r = 1 + r in &lt;br /&gt;
     reduit l o f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let app g l =&lt;br /&gt;
     let f  &lt;br /&gt;
     reduit l [] f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let cat l1 l2 =&lt;br /&gt;
     let f a r = a :: r in  &lt;br /&gt;
     reduit l1 l2 f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let renverse l =&lt;br /&gt;
     let f r a = [r]@[a]  &lt;br /&gt;
     reduit l [] f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3856</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3856"/>
		<updated>2009-02-24T17:05:21Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 1 : Tuples&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Avantage de la première forme (à plusieurs arguments): Elle permet une application partielle: on peut appliquer cette fonction à une seule partie des arguments.&lt;br /&gt;
&lt;br /&gt;
Inconvénients de la seconde forme (à un argument): &lt;br /&gt;
*il faut faire appel à fst, snd;&lt;br /&gt;
*Caml doit séparer les paires: c&#039;est une perte de temps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 2 : Listes&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
suite à l&#039;étude des fonctions &lt;br /&gt;
*longueur&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec longueur l=&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt;0&lt;br /&gt;
     | _ :: l -&amp;gt; 1+longueur l&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*applique&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec app f p =&lt;br /&gt;
     match p with &lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: p -&amp;gt; f(a) :: app f p&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*concatene&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec cat l1 l2 =&lt;br /&gt;
     match l1 with&lt;br /&gt;
     [] -&amp;gt; l2&lt;br /&gt;
     | a :: l -&amp;gt; a :: (cat l l2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*renverse,&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec renverse l =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: l -&amp;gt; (renverse l)@[a]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
on remarque des similitudes. Ces fonctions ont le même schéma de base ( celui de la fonction reduit) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec reduit l o f =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; o&lt;br /&gt;
     | a :: l -&amp;gt; f a (reduit l o f)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;NB :&#039;&#039; val reduit : &#039;a list -&amp;gt; &#039;b -&amp;gt; (&#039;a -&amp;gt; &#039;b -&amp;gt; &#039;b) -&amp;gt; &#039;b = &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 6 :&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Reprogrammons les fonctions précédentes à partir de la fonction reduit ! &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let longueur l =&lt;br /&gt;
     let f _ r = 1 + r in &lt;br /&gt;
     reduit l o f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let app g l =&lt;br /&gt;
     let f  &lt;br /&gt;
     reduit l [] f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let cat l1 l2 =&lt;br /&gt;
     let f a r = a :: r in  &lt;br /&gt;
     reduit l1 l2 f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let renverse l =&lt;br /&gt;
     let f r a = [r]@[a]  &lt;br /&gt;
     reduit l [] f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3855</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3855"/>
		<updated>2009-02-24T17:03:13Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Avantage de la première forme (à plusieurs arguments): Elle permet une application partielle: on peut appliquer cette fonction à une seule partie des arguments.&lt;br /&gt;
&lt;br /&gt;
Inconvénients de la seconde forme (à un argument): &lt;br /&gt;
*il faut faire appel à fst, snd;&lt;br /&gt;
*Caml doit séparer les paires: c&#039;est une perte de temps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 2 : Listes&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
suite à l&#039;étude des fonctions &lt;br /&gt;
*longueur&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec longueur l=&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt;0&lt;br /&gt;
     | _ :: l -&amp;gt; 1+longueur l&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*applique&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec app f p =&lt;br /&gt;
     match p with &lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: p -&amp;gt; f(a) :: app f p&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*concatene&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec cat l1 l2 =&lt;br /&gt;
     match l1 with&lt;br /&gt;
     [] -&amp;gt; l2&lt;br /&gt;
     | a :: l -&amp;gt; a :: (cat l l2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*renverse,&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec renverse l =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: l -&amp;gt; (renverse l)@[a]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
on remarque des similitudes. Ces fonctions ont le même schéma de base ( celui de la fonction reduit) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec reduit l o f =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; o&lt;br /&gt;
     | a :: l -&amp;gt; f a (reduit l o f)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;NB :&#039;&#039; val reduit : &#039;a list -&amp;gt; &#039;b -&amp;gt; (&#039;a -&amp;gt; &#039;b -&amp;gt; &#039;b) -&amp;gt; &#039;b = &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 6 :&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Reprogrammons les fonctions précédentes à partir de la fonction reduit ! &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let longueur l =&lt;br /&gt;
     let f _ r = 1 + r in &lt;br /&gt;
     reduit l o f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let app g l =&lt;br /&gt;
     let f  &lt;br /&gt;
     reduit l [] f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let cat l1 l2 =&lt;br /&gt;
     let f a r = a :: r in  &lt;br /&gt;
     reduit l1 l2 f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; &lt;br /&gt;
 let renverse l =&lt;br /&gt;
     let f r a = [r]@[a]  &lt;br /&gt;
     reduit l [] f&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3854</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3854"/>
		<updated>2009-02-24T16:51:39Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Avantage de la première forme (à plusieurs arguments): Elle permet une application partielle: on peut appliquer cette fonction à une seule partie des arguments.&lt;br /&gt;
&lt;br /&gt;
Inconvénients de la seconde forme (à un argument): &lt;br /&gt;
*il faut faire appel à fst, snd;&lt;br /&gt;
*Caml doit séparer les paires: c&#039;est une perte de temps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 2 : Listes&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
suite à l&#039;étude des fonctions &lt;br /&gt;
*longueur&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec longueur l=&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt;0&lt;br /&gt;
     | _ :: l -&amp;gt; 1+longueur l&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*applique&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec app f p =&lt;br /&gt;
     match p with &lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: p -&amp;gt; f(a) :: app f p&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*concatene&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec cat l1 l2 =&lt;br /&gt;
     match l1 with&lt;br /&gt;
     [] -&amp;gt; l2&lt;br /&gt;
     | a :: l -&amp;gt; a :: (cat l l2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*renverse,&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec renverse l =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: l -&amp;gt; (renverse l)@[a]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
on remarque des similitudes. Ces fonctions ont le même schéma de base ( celui de la fonction reduit) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec reduit l o f =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; o&lt;br /&gt;
     | a :: l -&amp;gt; f a (reduit l o f)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;NB :&#039;&#039; val reduit : &#039;a list -&amp;gt; &#039;b -&amp;gt; (&#039;a -&amp;gt; &#039;b -&amp;gt; &#039;b) -&amp;gt; &#039;b = &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3853</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3853"/>
		<updated>2009-02-24T16:48:11Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Avantage de la première forme (à plusieurs arguments): Elle permet une application partielle: on peut appliquer cette fonction à une seule partie des arguments.&lt;br /&gt;
&lt;br /&gt;
Inconvénients de la seconde forme (à un argument): &lt;br /&gt;
*il faut faire appel à fst, snd;&lt;br /&gt;
*Caml doit séparer les paires: c&#039;est une perte de temps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exercice 2 : Listes&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
suite à l&#039;étude des fonctions &lt;br /&gt;
*longueur&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec longueur l=&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt;0&lt;br /&gt;
     | _ :: l -&amp;gt; 1+longueur l&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*applique&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec app f p =&lt;br /&gt;
     match p with &lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: p -&amp;gt; f(a) :: app f p&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*concatene&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec cat l1 l2 =&lt;br /&gt;
     match l1 with&lt;br /&gt;
     [] -&amp;gt; l2&lt;br /&gt;
     | a :: l -&amp;gt; a :: (cat l l2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*renverse,&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec renverse l =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; []&lt;br /&gt;
     | a :: l -&amp;gt; (renverse l)@[a]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
on remarque des similitudes. Ces fonctions ont le même schéma de base ( celui de la fonction reduit) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec reduit l o f =&lt;br /&gt;
     match l with&lt;br /&gt;
     [] -&amp;gt; o&lt;br /&gt;
     | a :: l -&amp;gt; f a (reduit l o f)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3846</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3846"/>
		<updated>2009-02-24T16:14:25Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3844</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3844"/>
		<updated>2009-02-24T16:09:56Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 4:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On définit la fonction curry par:&lt;br /&gt;
&lt;br /&gt;
 Let curry (f: &#039;a * &#039;b -&amp;gt; &#039;c) : &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x y -&amp;gt; f(x,y);;&lt;br /&gt;
&lt;br /&gt;
Ou encore en simplifiant:&lt;br /&gt;
&lt;br /&gt;
 Let curry f x y = f(x,y);;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On définit ensuite la fonction uncurry par:&lt;br /&gt;
&lt;br /&gt;
 Let uncurry (f: &#039;a -&amp;gt; &#039;b -&amp;gt; &#039;c) : &#039;a * &#039;b -&amp;gt; &#039;c&lt;br /&gt;
     = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&lt;br /&gt;
Ou encore de trois autres manières plus simplifiées:&lt;br /&gt;
&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; f (fst x) (snd x);;&lt;br /&gt;
&lt;br /&gt;
 Let uncurry f = fun x -&amp;gt; match x with (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&lt;br /&gt;
 Let uncurry f = function (a,b) -&amp;gt; f a b;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1) &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;exemple : &#039;&#039;fib 10 = (55, 88) pour exécuter la fonction Fibonacci(10), il y a 88 appels récursifs nécessaires...&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3842</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3842"/>
		<updated>2009-02-24T16:02:57Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Préliminaires==&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD1 et le TP0==&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
::Pour améliorer la précision je suggère de passer les coordonnées en type Float. --[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Le TD2==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Question 5 :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
D&#039;après la fonction récursive Fibonacci définit par &amp;lt;br /&amp;gt;&lt;br /&gt;
f(0)=0 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(1)=1 &amp;lt;br /&amp;gt;&lt;br /&gt;
f(n+2)=f(n+1)+f(n), &amp;lt;br /&amp;gt;&lt;br /&gt;
comment compter le nombre d&#039;appels récursifs en Caml? &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 let rec fib n =&lt;br /&gt;
     if (n&amp;lt;2) then (n,0)&lt;br /&gt;
     else let t = fib (n-1) in&lt;br /&gt;
          let s = fib (n-2) in &lt;br /&gt;
     (fst t + fst s , snd t + snd s + 1)&lt;br /&gt;
&lt;br /&gt;
==Le TP1 - début==&lt;br /&gt;
&lt;br /&gt;
 --- à venir ---&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3798</id>
		<title>INFO401 corr TD TP</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=INFO401_corr_TD_TP&amp;diff=3798"/>
		<updated>2009-01-31T10:42:41Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Le TD1 et le TP0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Préliminaires=&lt;br /&gt;
&lt;br /&gt;
Pour afficher correctement dans le wiki, allez voir un peu comment on fait. Vous pouvez regarder par exemple sur le [[INFO401 | wiki du cours]] ou directement sur des articles de [http://fr.wikipedia.org/wiki/Accueil Wikipedia]. La documentation de mediawiki se trouve [http://meta.wikimedia.org/wiki/Aide:Éditeur ici].&lt;br /&gt;
&lt;br /&gt;
Un truc important : pour rentrer du code Caml, il faut mettre les balises &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;...&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; autour de votre code. Allez par exemple voir le début de la section sur [[#Le TD1 et le TP0 | le TD1 et TP0]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aller discuter des corrections dans les sujets de discussions associes...&lt;br /&gt;
&lt;br /&gt;
=Le TD1 et le TP0=&lt;br /&gt;
&lt;br /&gt;
Pour vous montrer un exemple de ce que j&#039;attends, voila la correction de la fonction factorielle. (C&#039;était facile...) J&#039;ai volontairement mis beaucoup de commentaires...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;La fonction factorielle (TD1, exercice 2, question 2)&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le but est de calculer la fonction &amp;lt;math&amp;gt;!n = 1\times2\times \cdots \times n&amp;lt;/math&amp;gt; par récurrence. La version typée est verbeuse de la fonction correspondante en Caml donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* fonction factorielle : c&#039;est la factorielle habituelle des mathématiciens... *)&lt;br /&gt;
let rec fact (n:int) : int =&lt;br /&gt;
  if (n&amp;gt;1)&lt;br /&gt;
  then  n * (fact (n-1))&lt;br /&gt;
  else 1      (* rq : pour que le programme ne boucle pas sur les valeurs négatives, on renvoie 1 dés que n&amp;lt;1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme la fonction est récursive, il ne faut pas oublier le &amp;lt;tt&amp;gt;rec&amp;lt;/tt&amp;gt; au début de la définition.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On aurait pu faire une autre version, qui fonctionne différemment sur les nombres négatifs :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact&#039; = function&lt;br /&gt;
   n when (n&amp;gt;0) -&amp;gt; n * fact&#039; (n-1)&lt;br /&gt;
 | n when (n&amp;lt;0) -&amp;gt; n * fact&#039; (n+1)&lt;br /&gt;
 | _ -&amp;gt; 1  (* si n n&#039;est ni plus petit que 0 ni plus grand que 0, n est égal à 0, et on renvoie donc 1 *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
J&#039;ai volontairement mis une version qui contient plusieurs choses que nous n&#039;avons pas encore vues en cours :&lt;br /&gt;
* utilisation de &amp;quot;&amp;lt;tt&amp;gt;function&amp;lt;/tt&amp;gt;&amp;quot; plutôt que &amp;lt;tt&amp;gt;fun&amp;lt;/tt&amp;gt;,&lt;br /&gt;
* le symbole &amp;quot;&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;&amp;quot;,&lt;br /&gt;
* le mot clé &amp;quot;&amp;lt;tt&amp;gt;when&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Vous devriez pouvoir comprendre ce que fait la fonction. Sinon, voici une version que vous auriez pu écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fact_bis = fun n -&amp;gt;&lt;br /&gt;
  if (n=0)&lt;br /&gt;
  then 1&lt;br /&gt;
  else begin&lt;br /&gt;
    if (n&amp;gt;0)&lt;br /&gt;
    then n*fact_bis (n-1)&lt;br /&gt;
    else n*fact_bis (n+1)   (* dans ce cas, n est forcement négatif *)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Les fonctions sommes &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il s&#039;agit ici d&#039;écrire la fonction qui va additionner les carrés des entiers de 1 jusqu&#039;à un nombre donné.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_carre b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (b*b) + somme_carre (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite on nous demande de calculer la somme des cubes des entiers de 1 jusqu&#039;à un nombre donné. On pourrait faire le même programme en remplaçant b*b par b*b*b, mais on va définir une fonction puissance (car elle n&#039;existe pas d&#039;origine sous Caml), qui nous servira aussi pour la suite... :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec puissance x a =&lt;br /&gt;
if (a = 0) then 1&lt;br /&gt;
else x * puissance x (a-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On doit maintenant calculer la somme des &amp;lt;math&amp;gt;i^i&amp;lt;/math&amp;gt;, i variant de 1 à un nombre donné :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_puissance b =&lt;br /&gt;
if (b=0) then 0&lt;br /&gt;
else (puissance b b) + somme_puissance (b-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut définir une unique fonction qui permettrait de faire toutes ces sommes, celle-ci aura pour argument une fonction quelconque :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec somme_fonction n f = (* f étant une fonction *)&lt;br /&gt;
if (n=0) then f 0&lt;br /&gt;
else f n + somme_fonction (n-1) f;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cette fonction est de type &amp;quot;&amp;lt;tt&amp;gt;int -&amp;gt; fun -&amp;gt; int&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Nombres pairs et impairs (TP0 Partie 2 Question 2) &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut écrire les fonctions récursives pairs et impairs, qui renvoient vrai si le nombre est pair (respectivement impair) et faux si le nombre est impair (respectivement pair);&lt;br /&gt;
Ici nous devons déclarer simultanément les deux fonctions, car chacune fait appel à l&#039;autre lors de son exécution.&lt;br /&gt;
&lt;br /&gt;
Cela donne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec pair n =&lt;br /&gt;
  if (n=0) then true&lt;br /&gt;
  else impair (n-1)&lt;br /&gt;
and impair n =&lt;br /&gt;
  if (n=0) then false&lt;br /&gt;
  else  pair (n-1);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Suite de Fibonacci &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La suite de fibonacci est tel que u&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;=0 u&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;=1 et u&amp;lt;sub&amp;gt;n+2&amp;lt;/sub&amp;gt;=u&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt;+u&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec fib n =&lt;br /&gt;
if (n=0) then 0&lt;br /&gt;
else if (n=1) then 1&lt;br /&gt;
else fib (n-1) + fib (n-2);;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La plus grande valeur que l&#039;on peut obtenir sans que cela soit trop long est 24157817, ce qui correspond à fib 37.&lt;br /&gt;
Nous trouvons qu&#039;il faut déjà 88 additions pour calculer fib 10.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq :&#039;&#039;&#039; fib de 37 prend effectivement beaucoup de temps. Il faut 39088168 additions avant d&#039;en arriver à bout. Il est possible de faire une version de Fibonacci qui va très vite et qui calcule &amp;lt;tt&amp;gt;fib 37&amp;lt;/tt&amp;gt; en seulement 36 additions...&lt;br /&gt;
: Comment ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Dragon ! &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;i&amp;gt; Le dragon est une créature mythique, présente dans de nombreuses cultures.&lt;br /&gt;
  On peut déterminer deux grands types de dragons : le dragon occidental et le dragon oriental&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction dragon a pour but de dessiner un dragon, pour cela on utilise une fonction récursive qui admet pour argument le nombre n d&#039;itération de la fonction, et les coordonnées de 2 points. A chaque itération, la fonction calcule pour chaque segment, un nouveau point et le relie ensuite aux deux autres.&lt;br /&gt;
&lt;br /&gt;
On obtient en tout 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; segments entremêlés, qui forment un dragon.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s go !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let rec dragon (n:int) (a:int) (b:int) (c:int) (d:int) : unit =&lt;br /&gt;
if (n = 0) then (moveto a b ; lineto c d)&lt;br /&gt;
               else begin&lt;br /&gt;
                      let x = (a+c+d-b)/2 in&lt;br /&gt;
                      let y = (b+d+a-c)/2 in&lt;br /&gt;
                      dragon (n-1) a b x y ;&lt;br /&gt;
                      dragon (n-1) c d x y&lt;br /&gt;
                    end ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Rq : &#039;&#039;&#039; votre version du dragon est bien, mais pas très précises. (Je chipote un peu...)  Pour les paramètres (&amp;lt;tt&amp;gt;dragon 11 100 100 400 400&amp;lt;/tt&amp;gt;), de nombreux carrés ne sont pas bien tracés.&lt;br /&gt;
:Comment expliquez-vous cela, et comment pouvez-vous le corriger ?&lt;br /&gt;
&lt;br /&gt;
__Pour améliorer la précision je suggère de passer les coordonnées en type Float __--[[Utilisateur:Nicolas|Nicolas]] 31 janvier 2009 à 11:42 (CET)&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion:INFO421_:_Programmation_fonctionnelle&amp;diff=3696</id>
		<title>Discussion:INFO421 : Programmation fonctionnelle</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion:INFO421_:_Programmation_fonctionnelle&amp;diff=3696"/>
		<updated>2009-01-21T12:46:49Z</updated>

		<summary type="html">&lt;p&gt;Nicolas : /* Inscription sur le Wiki */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Comment commencer une discussion ==&lt;br /&gt;
&lt;br /&gt;
Pour commencer une discussion, il suffit de cliquer sur le &#039;&#039;&#039;&amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;&#039;&#039;&#039; en haut de  la page. Vous pouvez alors rentrer un sujet de discussion et éditer le texte comme pour le wiki.&lt;br /&gt;
&lt;br /&gt;
C&#039;est mieux de signer vos intervention en utilisant l&#039;avant dernier bouton d&#039;édition, ou avec &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;--~~~~&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Pour répondre, il faut « modifier » la section correspondante...&lt;br /&gt;
:Par soucis de visibilité, il est parfois préférable de rajouter une marge à gauche (comme ici). Pour faire ça, il faut commencer votre ligne par un «&amp;lt;tt&amp;gt;:&amp;lt;/tt&amp;gt;». (Ou un «&amp;lt;tt&amp;gt;::&amp;lt;/tt&amp;gt;»...)&lt;br /&gt;
&lt;br /&gt;
--[[Utilisateur:Hyvernat|Hyvernat]] 12 janvier 2009 à 13:47 (CET)&lt;br /&gt;
&lt;br /&gt;
== Inscription sur le Wiki ==&lt;br /&gt;
&lt;br /&gt;
Voila, c&#039;est juste pour dire que je me suis inscrit...&lt;br /&gt;
&lt;br /&gt;
--[[Utilisateur:Hyvernat|Hyvernat]] 21 janvier 2009 à 11:01 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Inscription sur le Wiki&lt;br /&gt;
--[[Utilisateur:LAYER|LAYER]] 21 janvier 2009 à 13:39 (CET)&lt;br /&gt;
&lt;br /&gt;
inscription terminée --[[Utilisateur:Laurent corantin|Laurent corantin]] 21 janvier 2009 à 13:40 (CET)&lt;br /&gt;
&lt;br /&gt;
:: Travail terminé! --[[Utilisateur:Caroline|Caroline]] 21 janvier 2009 à 13:42 (CET)&lt;br /&gt;
&lt;br /&gt;
:: Inscription ok --[[Utilisateur:JulienMorel|JulienMorel]] 21 janvier 2009 à 13:43 (CET)&lt;br /&gt;
&lt;br /&gt;
c bon&lt;br /&gt;
&lt;br /&gt;
inscription sur le wiki --[[Utilisateur:Thomas BILLOUD|Thomas BILLOUD]] 21 janvier 2009 à 13:44 (CET)&lt;br /&gt;
&lt;br /&gt;
inscription confirmée --[[Utilisateur:Costa jp|Costa jp]] 21 janvier 2009 à 13:44 (CET)&lt;br /&gt;
&lt;br /&gt;
inscrit ! --[[Utilisateur:Mauris Robin|Mauris Robin]] 21 janvier 2009 à 13:45 (CET)&lt;br /&gt;
&lt;br /&gt;
inscription--[[Utilisateur:Aulev|Aulev]] 21 janvier 2009 à 13:46 (CET)&lt;br /&gt;
&lt;br /&gt;
::hi all!!!--[[Utilisateur:Nicolas|Nicolas]] 21 janvier 2009 à 13:46 (CET)&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
</feed>