Des programmes tres simples pour les Mathématiques

# Chapitre 6 Des programmes tres simples pour les Mathématiques

## 6.1 Définir le minimum

### 6.1.1 Minimum de 2 nombres

Pour trouver le minimum de a et b et on compare a et b. Le minimum vaut a si a<=b et sinon il vaut b.
On remarquera que puisque l’instruction `retourne` fait sortir du programme, on peut écrire le programme sans utiliser de `sinon`.

    Mini(a,b):={
      si a<=b alors retourne a;fsi;
      retourne b;
    }:;

On tape :
`Mini(23,4*6)`
On obtient : `23`
On tape :
`Mini(1.5,sqrt(2))`
On obtient : `sqrt(2)`

### 6.1.2 Minimum de 3 nombres

On utilise le fait que :
Min(a,b,c)=Min(Min(a,b),c)
et on utilise le programme précédent.

    Mini3(a,b,c):={
      local m;
      m:=Mini(a,b);
      m:=Mini(m,c);
      retourne m;
    }:;

On tape :
`Mini3(3```^```3,4*6,5```^```2)`
On obtient : `24`
On tape :
`Mini3(1.5,sqrt(2),1.41)`
On obtient : `1.41`

### 6.1.3 Minimum d’une liste de nombres

Pour trouver le minimum de la liste L, on parcourt la liste L en utilisant une variable m qui sera le minimum de ce que l’on vient de parcourir et qui sera mis à jour au fur et à mesure que l’on parcourt la liste L.
On renvoie m et l’indice jm qu’il a dans L.

    MiniL(L):={
      local m,j,d,a,jm;
      d:=dim(L)-1;
      m:=L[0];
      jm:=0;
      pour j de 1 jusque d faire
        a:=L[j];
        si a<m alors
          m:=a;
          jm:=j;
        fsi;
      fpour;
      retourne m,jm;
    }:;

On tape :
`MiniL([12,32,3,23,5,2,45])`
On obtient : `2`

## 6.2 Trier

### 6.2.1 Ordonner 2 nombres par ordre croissant

    Trier(a,b):={
      si a<=b alors retourne a,b;fsi;
      retourne b,a;
    }:;

On tape :
`Trier(125/3,163/4)`
On obtient : `163/4,125/3`

### 6.2.2 Ordonner 3 nombres par ordre croissant

    Trier3(a,b,c):={
      si a>b alors a,b:=b,a;fsi;
      si c<=a alors retourne c,a,b;fsi;
      si c<=b alors retourne a,c,b; fsi;
      retourne a,b,c;
    }:;

On tape :
`Trier3(12,1,23)`
On obtient : `1,12,23`

### 6.2.3 Ordonner une séquence de nombres par ordre croissant

#### Tri par recherche du minimum

On utilise une liste Lrep pour mettre la liste triée. On parcourt la liste L pour chercher l’indice jm du plus petit élément m, puis on le met dans la liste Lrep et et on enlève cet élément de L on enlève cet élément de L Puis on refait la même chose avec la liste privée de son premier élément etc..
On va utiliser `mid(L,j,k)` qui renvoie la sous liste de `L` de longueur `k` qui commence à l’indice `j` ou `mid(S,j)` qui renvoie la liste fin de `L` commençant à l’indice `j` .
Remarque À la place de `mid(L,j,k)` on peut aussi utiliser `L[j..j+k-1]` (on met les indices de début et de fin de la sous liste) et à la place de `mid(L,j)` on peut aussi utiliser `L[j..dim(L)-1]`.

    TrierLr(L):={
      local j,k,m,jm,d,Lrep;
      d:=dim(L)-1;
      Lrep:=[];
      pour j de 0 jusque d faire
        m,jm:=MiniL(L);
        Lrep:=append(Lrep,m);
        L:=concat(mid(L,0,jm),mid(L,jm+1));
      fpour
     retourne Lrep;
    }:;

On utilise la même liste L pour mettre la liste triée. On parcourt la liste L pour chercher l’indice jm du plus petit élément m, puis on l’échange avec le premier élémment de L. Puis on refait la même chose avec la liste privée de son premier élément etc...C’est le tri par recherche du minimum.

    TrierL(L):={
      local j,k,m,jm,d;
      d:=dim(L)-1;
      pour k de 0 jusque d-1 faire
        jm:=k;
        m:=L[k];
        pour j de k+1 jusque d faire
          si m>L[j] alors m:=L[j];jm:=j; fsi;
        fpour;
      L[jm]:=L[k];
      L[k]:=m;
      fpour
     retourne L;
    }:;

On tape :
`TrierLr([23,12,1,14,21,4,45,11])`
Ou on tape :
`TrierL([23,12,1,14,21,4,45,11])`
On obtient : `[1,4,11,12,14,21,23,45]`

#### Tri par insertion

On utilise une liste la même lisre L pour mettre la liste triée. À chaque étape on insère l’élément suivant `a=L[k]` dans le début de la liste qui est déjà triée. Quand on a trouvé où» il fallait insérer a par exemple entre `L[j-1]` et `L[j]` il faut lui faire de la place en décalant d’un cran vers la droite les éléments de `L` de j jusque k. C’est le tri par insertion.

    TrieL(L):={
      local j,k,d,a,p;
      d:=dim(L)-1;
      pour k de 1 jusque d faire
        j:=0;
        a:=L[k];
        tantque a>L[j] faire j:=j+1; ftantque
        si j<k alors
          // on d\'ecale d'un cran vers la droite
          pour p de k jusque j+1 pas -1 faire
            L[p]:=L[p-1]
          fpour;
          L[j]:=a;
        fsi
      fpour
      retourne L;
    }:;

On tape :
`TrieL([23,12,1,14,21,4,45,11])`
On obtient : `[1,4,11,12,14,21,23,45]`

#### Tri par fusion

À chaque étape on partage la liste L en deux listes L1 er L2 de même longueur. On trie ces 2 listes grâce à 2 appels récursifs, puis on les fusionnne. Pour cela on écrit la fonction `fusion` qui fusionne 2 listes triées : à chaque étape on compare un élément de L1 avec un élément de L2, on met le plus petit des 2 dans la liste réponse et on avance l’indice correspondant au plus petit d’un cran et on recommence...
On tape :

    fusion(L1,L2):={
    local d1,d2,j1,j2,L;
     d1:=dim(L1)-1;
     d2:=dim(L2)-1;
     L:=[];
     j1:=0;
     j2:=0;
    tantque j1<=d1 et j2<=d2 faire
     si L1[j1]<L2[j2] alors L:=append(L,L1[j1]); j1:=j1+1;
       sinon  L:=append(L,L2[j2]); j2:=j2+1;
     fsi;
    ftantque;
    si j1<=d1 alors L:=concat(L,mid(L1,j1);
     sinon   L:=concat(L,mid(L2,j2);
    fsi;
    retourne L;
    }:;

    Trifusion(L):={
      local d,d1,L1,L2;
      d:=dim(L);
      si d==1 ou d==0 alors retourne L;fsi;
      d1:=iquo(d,2);
      L1:=mid(L,0,d1);
      L2:=mid(L,d1);
      L1:=Trifusion(L1);
      L2:=Trifusion(L2);
      retourne fusion(L1,L2);
    }:;

On peut améliorer le programme précédent en utilisant une liste que l’on modifie en place (avec l’opérateur `=<`) afin de ne pas recopier la liste `L` à chaque affectation par `:=`. Attention, cela nécessite de faire une copie de la liste vide initiale par `copy` sinon c’est la liste du programme lui-même qui sera modifiée et ne sera donc plus initialisée à une liste vide.

    fusionenplace(L1,L2):={
    local d1,d2,j1,j2,k,j,L;
     d1:=dim(L1)-1;
     d2:=dim(L2)-1;
     L:=copy([]);
     j1:=0;
     j2:=0;
     k:=0;
     tantque j1<=d1 et j2<=d2 faire
       si L1[j1]<L2[j2] alors L[k]=<L1[j1]; j1:=j1+1;
       sinon  L[k]=<L2[j2]; j2:=j2+1;
       fsi;
       k:=k+1;
     ftantque;
     pour j de j1 jusque d1 faire
       L[k]=<L1[j];
       k:=k+1;
     fpour;
     pour j de j2 jusque d2 faire
       L[k]=<L2[j];
       k:=k+1;
     fpour;
     retourne L;
    }
    :;
    Trifusionenplace(L):={
      local L1,L2,d1,d;
      d:=dim(L);
      si d==1 ou d==0 alors retourne L;fsi;
      d1:=iquo(d,2);
      L1:=mid(L,0,d1);
      L2:=mid(L,d1);
      L1:=Trifusionenplace(L1);
      L2:=Trifusionenplace(L2);
      retourne fusionenplace(L1,L2);
    }
    :;

## 6.3 Définir une fonction par morceaux

On peut utiliser l’instruction `si...sinon` ou l’instruction `ifte` ou mieux l’instruction `when` (ou avec la version infixée de `when` qui est `?`).
Soit la fonction f définie par :

f(x)= | ⎧ ⎪ ⎨ ⎪ ⎩ |
−1 | si x<0
0 | si x=0
+1 | si x>0

On tape

     f(x):={
      si x<0 alors retourne -1;fsi;
      si x==0  alors retourne 0 fsi;
      si x>0 alors retourne 1;fsi;
    }:;

mais on peut aussi écrire la même chose avec l’instruction `ifte` :
`f(x):=ifte(x<0,1,ifte(x==0,0,1)`
Mais il faut alors savoir que pour que `f(a)` soit valable il faut que `a` contienne une valeur.
Par contre si on tape :
`g(x):=when(x<0,1,when(x==0,0,1)`
ou
`g(x):=(x>0)? 1 : ((x==0)? 0 : -1)`
`g(a)` est valable même si `a` est symbolique i.e. ne contient pas de valeur.

## 6.4 Convertir

### 6.4.1 Des secondes en jours, heures, minutes et secondes

On se donne un nombre ns de secondes que l’on veut convertir en heures h, minutes mn et secondes s. On a :

ns=3600h+60mn+s=s+60(mn+60h)

On tape :

    converth(ns):={
      local h,mn,s;
      s:=irem(ns,60);
      ns:=iquo(ns,60);
      mn:=irem(ns,60);
      h:=iquo(ns,60);
    retourne h,mn,s;
    }:;

On tape :
`converth(123456789)`
On obtient : `34293,33,9`
Si on veut aussi convertir en jours j, heures h, minutes mn et secondes s. On a :

ns=24*3600j+3600h+60mn+s=s+60(mn+60(h+24j))

Ou bien, on tape :

    convertj(ns):={
      local j,h,mn,s;
      s:=irem(ns,60);
      ns:=iquo(ns,60);
      mn:=irem(ns,60);
      ns:=iquo(ns,60);
      h:=irem(ns,24);
      j:=iquo(ns,24);
    retourne j,h,mn,s;
    }:;

On tape :
`convertj(123456789)`
On obtient : `1428,21,33,9`

### 6.4.2 Des degrés en radians

Si la mesure d’un angle est rad en radians et deg en degrés, on a :

rad=deg*π/180

    deg2rad(deg):=deg*pi/180;

On tape :
`deg2rad(48.2384062423)`
On obtient : `0.841919014843`

### 6.4.3 Des radians en degrés

Si la mesure d’un angle est rad en radians et deg en degrés, on a :

deg=rad*180/π

    rad2deg(rad):=rad*180/pi;

On tape :
`rad2deg(0.841919014843)`
On obtient : `48.2384062423`

## 6.5 Les fractions

### 6.5.1 Simplifier une fraction

On suppose que l’on donne la fraction F sous la forme de la liste [N,D] de son numérateur et de son dénominateur. Pour la simplifier il suffit de diviser le numérateur et le dénominateur par leur pgcd.
On utilise ici la fonction `gcd` de `Xcas` pour le calcul du pgcd. On tape :

    Simplifie(F):={
     local pgcd,N,D;
     N:=F[0];
     D:=F[1];
     pgcd:=gcd(N,D);
     retourne [N/pgcd,D/pgcd];
    }:;

On tape :
`Simplifie([5544,55]);`
On obtient : `[504,5]`

### 6.5.2 Additionner 2 fractions

On commence par simplifier les 2 fractions, puis on cherche leur dénominateur commun qui est le ppcm de leur dénominateurs, On réduit ces fractions à ce dénominateur commun et on ajoute les numérateurs.
On suppose que l’on donne les fraction F1 et F2 sous la forme de la liste [N,D]. Puis on simplifie le résultat.
On utilise ici la fonction `lcm` de `Xcas` pour le calcul du ppcm.

    Ajoute(F1,F2):={
     local ppcm,N1,D1,N2,D2,N,D;
     F1:=Simplifie(F1);
     F2:=Simplifie(F2);
     N1:=F1[0];
     D1:=F1[1];
     N2:=F2[0];
     D2:=F2[1];
     D:=lcm(D1,D2);
     N1:=N1*D/D1;
     N2:=N2*D/D2;
     retourne Simplifie([N1+N2,D]);
    }:;

On tape :
`Ajoute([1234,22],[5549,55])`
On obtient : `[8634,55]`

### 6.5.3 Multiplier 2 fractions

On commence par simplifier les 2 fractions, puis on multiplie les numérateurs entre eux et les dénominateurs entre eux. Puis on simplifie le résultat.

    Multiple(F1,F2):={
     local N1,D1,N2,D2;
     F1:=Simplifie(F1);
     F2:=Simplifie(F2);
     N1:=F1[0];
     D1:=F1[1];
     N2:=F2[0];
     D2:=F2[1];
     retourne Simplifie([N1*N2,D1*D2]);
    }:;

On tape :
`Multiple([1234,22],[5549,55])`
On obtient : `[3423733,605]`