---
exports:
- format: pdf
  output: TD.pdf
  template: ../../template/TD
- format: tex
  output: TDmd.tex
  template: ../../template/TD
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: C++17
  language: C++17
  name: xcpp17
math:
  \SI: '#1\ #2'
  \kilogram: \text{kg}
  \meter: \text{m}
  \mref: \mathbf{m}_\text{ref}
  \per: /
  \second: \text{s}
  \squared: ^2
---

# TD 4 : Des fonctions, des tests et de la documentation

+++ {"tags": ["instructor"]}

:::{admonition} Notes aux enseignants

La notion d'appel de fonction vs définition de la fonction n'est pas
simple pour les débutants. Une erreur classique est d'indiquer le type
au moment de l'appel (ex : `cout << int factorielle(3);`).  Faire le
parallèle avec les variables : on déclare le type d'une variable une
fois pour toutes et ensuite on l'utilise sans le rappeler (ex : `cout
<< x;`) et c'est pareil avec les fonctions.

Une autre difficulté est de comprendre ce qu'est réellement un
paramètre, et la différence entre paramètre et variable locale.  Par
exemple dans l'exercice 1 beaucoup d'élèves ont tendance à mettre pi
en paramètre.

:::

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "10", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 1 : Premières fonctions

Voici une fonction qui calcule la surface d'un rectangle :

:::{literalinclude} surface-rectangle.cpp
:start-after: BEGIN surfaceRectangle
:end-before: END surfaceRectangle
:::

1.  Définissez une **fonction** `surfaceDisque` qui calcule la surface
    d'un disque de rayon donné. On prendra $\pi=3,1415926$.

    /// BEGIN SOLUTION
    :::{literalinclude} surface-disque-correction.cpp
    :start-after: BEGIN surfaceDisque
    :end-before: END surfaceDisque
    :::
    /// END SOLUTION

2.  Définissez une **fonction** `surfaceTriangle` qui calcule la
    surface d'un triangle de base et de hauteur données.

    /// BEGIN SOLUTION
    :::{literalinclude} surface-triangle-correction.cpp
    :start-after: BEGIN surfaceTriangle
    :end-before: END surfaceTriangle
    :::
    /// END SOLUTION

::::

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "20", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 2 : En route vers l'exponentielle
{raw:latex}`\newlineforenumerate`

1.  Nous avons vu en cours et en TP une fonction `factorielle(n)` qui
    calcule la factorielle d'un entier positif $n$. Pour un exercice
    du TP à venir, et pour éviter les problèmes de dépassement de
    capacité, il est souhaitable que les calculs intermédiaires et le
    résultat soient des `double`. Adaptez en conséquence la fonction
    `factorielle`.

    /// BEGIN SOLUTION
    :::{literalinclude} fonction-factorielle-doubles-doctests-correction.cpp
    :start-after: BEGIN factorielle
    :end-before: END factorielle
    :::
    /// END SOLUTION

2.  On considère la fonction dont la documentation et l'entête sont
    donnés ci-dessous :

    :::{literalinclude} puissance.cpp
    :start-after: BEGIN puissanceEntete
    :end-before: END puissanceEntete
    :::

    Quels sont les types de ses paramètres formels et de sa valeur de
    retour?

    /// BEGIN SOLUTION

    Le paramètre formel `a` est de type `double`,
    le paramètre formel `n` est de type `int`, la
    valeur de retour est de type `double`.

    /// END SOLUTION

3.  Écrivez quelques exemples d'utilisation de la fonction
    `puissance`. Éditez-les sous forme de tests, en vous inspirant du
    test suivant pour la fonction `surfaceRectangle`:

    :::{literalinclude} surface-rectangle.cpp
    :start-after: BEGIN surfaceRectangleTest
    :end-before: END surfaceRectangleTest
    :::

    /// BEGIN SOLUTION
    :::{literalinclude} puissance-recursive-correction.cpp
    :start-after: BEGIN test_puissance
    :end-before: END test_puissance
    :::
    /// END SOLUTION

4.  Définissez la fonction `puissance`.

    /// BEGIN SOLUTION
    :::{literalinclude} puissance.cpp
    :start-after: BEGIN puissance
    :end-before: END puissance
    :::
    /// END SOLUTION

5.  Cherchez dans les notes de cours la sémantique **simplifiée** de
    l'appel d'une fonction.

6.  Exécutez pas à pas le programme suivant :

    :::{literalinclude} appel-fonction-simplifiee.cpp
    :start-after: BEGIN code_a_comprendre
    :end-before: END code_a_comprendre
    :::

    Quelle est la valeur de la variable `resultat` à la fin?

    /// BEGIN SOLUTION

    Les trois premières lignes initialisent les variables `k`, `x` et
    `a`. Ensuite on calcule `puissance(x - a, k) / factorielle(k)`,
    qu'on stocke dans `resultat`.

    Au moment du calcul, les expressions passées aux fonctions
    auxiliaires sont remplacées par leur valeur. Ainsi l'appel
    effectif est `puissance(2, 3) / factorielle(3)`.

    Il ne reste plus qu'à exécuter pas à pas la fonction `puissance`
    avec $2$ et $3$ comme valeurs initiales pour ses paramètres
    formels `a` et `n`: on obtient $8.0$ comme valeur de retour.

    On fait de même avec `factorielle` avec $3$ comme valeur initiale
    pour le paramètre formel `n`, ce qui donne $6.0$.

    Il ne reste qu'à faire la division `8.0 / 6.0`, ce qui donne
    environ $1.333$, et c'est la valeur de `resultat`.

    /// END SOLUTION

7.  $\clubsuit$ Définissez les fonctions `factorielle` et `puissance`
    en récursif cette fois, puis refaites l'exécution pas à
    pas. Qu'est-ce qui change?

    /// BEGIN SOLUTION
    :::{literalinclude} factorielle-recursive-correction.cpp
    :start-after: BEGIN factorielle
    :end-before: END factorielle
    :::
    /// END SOLUTION

    /// BEGIN SOLUTION
    :::{literalinclude} puissance-recursive-correction.cpp
    :start-after: BEGIN puissance
    :end-before: END puissance
    :::
    /// END SOLUTION

::::

{raw:latex}`\clearpage`

+++ {"tags": ["instructor"]}

:::{admonition} Notes aux enseignants

Les étudiants ont vu en cours la sémantique détaillée de l'appel de
fonctions, mais c'est encore fragile.  Dans l'exercice suivant, forcer
les étudiants à suivre pas à pas les étapes décrites dans la
sémantique de l'appel de fonction, en utilisant la même représentation
de la pile que dans le poly. À corriger soigneusement au tableau, avec
le même formalisme que dans le cours (donc pas comme la présentation
compacte utilisée dans la correction ci-dessous).

:::

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "30", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 3 : Variables locales/globales, pile et exécution pas à pas

On considère les deux programmes suivants :

:::{literalinclude} variable_globale.cpp
:start-after: BEGIN variableGlobale
:end-before: END variableGlobale
:::

:::{literalinclude} variable_locale.cpp
:start-after: BEGIN variableLocale
:end-before: END variableLocale
:::

1.  Mettez en évidence les différences entre les deux programmes (par
    exemple au surligneur).

    BEGIN SOLUTION

    Dans le premier programme, la variable `i` est globale (comme `k`
    et `resultat`), alors qu'elle est locale à la fonction `f` dans le
    second programme.

    END SOLUTION

2.  Cherchez dans les notes de cours la sémantique **détaillée** de
    l'appel d'une fonction (formalisation suivant le modèle
    d'exécution).

    BEGIN SOLUTION

    Voir [ici](semantique_appel_fonctions).

    END SOLUTION

3.  Exécutez pas à pas les deux programmes en décrivant au fur et à
    mesure l'état de la mémoire (pile). Quelle est la valeur la
    variable `resultat` à la fin de l'exécution?

    BEGIN SOLUTION

    Pour une meilleur compréhension nous allons mettre en parallèle
    l'état des piles lors de l'exécution des deux programmes (celui ou
    la variable `i` est globale et celui ou elle est locale).

    Les deux programmes pour rappel :
    ```
    int k = 3;                                        ││  int k = 3;
    int i = 5;                                        ││  int f(int j) {
    int f(int j) {                                    ││      int i = 5;
        i = i + j;                                    ││      i = i + j;
        return i;                                     ││      return i;
    }                                                 ││  }
    resultat = f(1) + f(2) + f(k);                    ││  resultat = f(1) + f(2) + f(k);
    ```

    État de la pile juste avant l'instruction `resultat = f(1) + f(2) + f(k);` :

    ```
    portée  │ variable     │ valeur  │                ││  portée  │ variable     │ valeur  │
    __________________________________                ││  __________________________________
            ┌──────────────┬─────────┐                ││
    globale │ int i        │    5    │                ││          ┌──────────────┬─────────┐
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Dans le calcul de `f(1)`, juste avant l'instruction `i = i + j` :

    ```
            ┌──────────────┬─────────┐                ││          ┌──────────────┬─────────┐
          f │ int j        │    1    │                ││        f │ int i        │    5    │
    globale │ int resultat │    ?    │ f(1)+f(2)+f(k) ││        f │ int j        │    1    │ f(1)+f(2)+f(k)
    globale │ int i        │    5    │                ││  globale │ int resultat │    ?    │
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Dans le calcul de f(1), juste avant l'instruction `return` :

    ```
            ┌──────────────┬─────────┐                ││          ┌──────────────┬─────────┐
          f │ int j        │    1    │                ││        f │ int i        │    6    │
    globale │ int resultat │    ?    │ f(1)+f(2)+f(k) ││        f │ int j        │    1    │
    globale │ int i        │    6    │                ││  globale │ int resultat │    ?    │ f(1)+f(2)+f(k)
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Juste après le calcul de f(1) :

    ```
            ┌──────────────┬─────────┐                ││
    globale │ int resultat │    ?    │ 6+f(2)+f(k)    ││          ┌──────────────┬─────────┐
    globale │ int i        │    6    │                ││  globale │ int resultat │    ?    │ 6+f(2)+f(k)
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Dans le calcul de `f(2)`, juste avant l'instruction `i = i+j` :

    ```
            ┌──────────────┬─────────┐                ││          ┌──────────────┬─────────┐
          f │ int j        │    2    │                ││        f │ int i        │    5    │
    globale │ int resultat │    ?    │ 6+f(2)+f(k)    ││        f │ int j        │    2    │ 6+f(2)+f(k)
    globale │ int i        │    6    │                ││  globale │ int resultat │    ?    │
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Dans le calcul de f(1), juste avant l'instruction `return` :

    ```
            ┌──────────────┬─────────┐                ││          ┌──────────────┬─────────┐
          f │ int j        │    2    │                ││        f │ int i        │    7    │
    globale │ int resultat │    ?    │ 6+f(2)+f(k)    ││        f │ int j        │    2    │
    globale │ int i        │    8    │                ││  globale │ int resultat │    ?    │ 6+f(2)+f(k)
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Juste après le calcul de f(2) :

    ```
            ┌──────────────┬─────────┐                ││
    globale │ int resultat │    ?    │ 6+8+f(k)       ││          ┌──────────────┬─────────┐
    globale │ int i        │    6    │                ││  globale │ int resultat │    ?    │ 6+7+f(k)
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Dans le calcul de f(k), juste avant l'instruction `return` :

    ```
            ┌──────────────┬─────────┐                ││          ┌──────────────┬─────────┐
          f │ int j        │    3    │                ││        f │ int i        │    8    │
    globale │ int resultat │    ?    │ 6+7+f(3)       ││        f │ int j        │    3    │
    globale │ int i        │    11   │                ││  globale │ int resultat │    ?    │ 6+7+f(3)
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    Juste après l'exécution de la dernière instruction :

    ```
            ┌──────────────┬─────────┐                ││
    globale │ int resultat │   25    │ (=6+8+11)      ││          ┌──────────────┬─────────┐
    globale │ int i        │    6    │                ││  globale │ int resultat │   21    │ (= 6+7+8)
    globale │ int k        │    3    │                ││  globale │ int k        │    3    │
            ├──────────────┴─────────┤                ││          ├──────────────┴─────────┤
            │         ...            │                ││          │         ...            │
            └────────────────────────┘                ││          └────────────────────────┘
                      Pile                            ││                    Pile
    ```

    END SOLUTION

4.  Décrivez la différence de comportement entre ces programmes, et
    retrouvez dans les notes de cours le commentaire à ce propos.

    BEGIN SOLUTION

    Dans le premiers programme, `i` a une durée de vie sur l'ensemble
    de l'exécution du programme et n'est initialisée qu'une seule fois
    au début. Dans le deuxième programme, `i` est recréée et
    réinitialisée à `5` à chaque appel de `f`. Il est donc important
    de savoir déclarer ses variables avec la bonne portée : locales ou
    globales.

    END SOLUTION

::::

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "40", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 4 : La trilogie code, documentation, tests

Analysez la fonction `volumePiscine` suivante :
:::{literalinclude} piscine.cpp
:start-after: BEGIN volumePiscine
:end-before: END volumePiscine
:::
Munie des tests :
:::{literalinclude} piscine.cpp
:start-after: BEGIN volumePiscineTests
:end-before: END volumePiscineTests
:::

1.  Est-ce que les tests passent?

    /// BEGIN SOLUTION

    Oui!

    /// END SOLUTION

2.  La documentation, le code et les tests sont-ils cohérents?

    /// BEGIN SOLUTION

    Les tests et l'implantation ne sont pas cohérents avec la
    documentation, car cette dernière spécifié que le résultat doit
    être exprimé en litres, alors que dans le test et l'implantation
    le résultat calculé est exprimé en décalitres.

    /// END SOLUTION

3.  Corrigez les anomalies éventuelles.

    /// BEGIN SOLUTION

    Le facteur de conversion devrait être de $10^3=1000$ et pas de
    $100$.

    /// END SOLUTION

::::

{raw:latex}`\clearpage`

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "50", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 5 : $\clubsuit$

Analysez la fonction `mystere` suivante :

:::{literalinclude} mystere.cpp
:start-after: BEGIN mystereTout
:end-before: END mystereTout
:::

Munie des tests :

:::{literalinclude} mystere.cpp
:start-after: BEGIN mystereTests
:end-before: END mystereTests
:::

1.  Comment fait-on appel à cette fonction (quelle est sa **syntaxe**)?

    /// BEGIN SOLUTION

    La signature de la fonction :

    :::{literalinclude} mystere.cpp
    :start-after: BEGIN mystereEntete
    :end-before: END mystereEntete
    :::

    nous indique que la fonction attend un seul paramètre entier
    (`blop`). On écrit donc `mystere(x)` où `x` est un entier pour
    appeler la fonction.

    /// END SOLUTION

2.  Que fait cette fonction (quelle est sa **sémantique**)?
    **Indications :** pour les chaînes de caractères, l'opérateur `+`
    représente la concaténation (par exemple `"Cou" + "cou"` a pour
    valeur `"Coucou"`); comme pour les entiers, `x += expression` est
    un raccourci pour `x = x + expression`; enfin, dans une chaîne de
    caractères, «`\n`» représente un saut de ligne.

    /// BEGIN SOLUTION

    La fonction crée une chaîne de caractères représentant un triangle
    d'étoiles ayant `blop` lignes et la renvoie. La boucle externe se
    charge des lignes, tandis que la boucle imbriquée se charge des
    colonnes.

    Ainsi, `mystere(4)` renvoie la chaîne de caractères :

    :::{literalinclude} mystere.cpp
    :start-after: BEGIN mystereAffiche
    :end-before: END mystereAffiche
    :::

    /// END SOLUTION

3.  Ré-écrivez la fonction en choisissant des noms pertinents pour la
    fonction et ses variables et en la faisant précéder de sa
    documentation.

    /// BEGIN SOLUTION
    :::{literalinclude} mystere.cpp
    :start-after: BEGIN triangleEtoiles
    :end-before: END triangleEtoiles
    :::
    /// END SOLUTION

::::

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "60", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 6 : $\clubsuit$

Le but de cet exercice est de coder une fonction `point_de_chute` qui
calcule l'abscisse $x_c$ à laquelle tombe un projectile lancé en $x =
0$ avec une vitesse $v$ suivant un angle $\alpha$ (exprimé en degrés
par rapport à l'horizontale). Définissez la fonction
`point_de_chute`. On commencera par écrire sa documentation ainsi que
des tests (voir TD 1).

**Rappels :**

-   l'abscisse est donnée par la formule : $x_c=(2v_xv_y)/g$ où $v_x =
    v\cos(\alpha)$, $v_y = v\sin(\alpha)$ et $g$ est l'accélération
    gravitationnelle (environ $\SI{9,8}{\meter\per\second\squared}$ sur la planète
    Terre).

-   en C`++`, les fonctions mathématiques sinus et cosinus sont
    implantées par les fonctions prédéfinies `sin(arg)` et `cos(arg)`
    dans `<cmath>`, où l'angle `arg` est exprimé en radians.

/// BEGIN SOLUTION
:::{literalinclude} point-de-chute-correction.cpp
:start-after: BEGIN pointdeChute
:end-before: END pointdeChute
:::
/// END SOLUTION

::::

{raw:latex}`\clearpage`

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "70", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 7 : $\clubsuit$

Le but de cet exercice est de calculer la hauteur en fonction du temps
$z(t)$ à laquelle se trouve un pot de fleur ($m=\SI{3}{\kilogram}$)
lâché à $t=0$ depuis le 10{sup}`ème` étage ($h_0=\SI{27}{\meter}$), en
chute libre avec résistance de l'air; puis de calculer le temps de
chute.

1.  Définissez une fonction `chute_libre(t)` calculant $z(t)$ pour un
    $V_0$ donné ($V_0=\SI{80}{\meter\per\second}$).
    **Indications :**
    -   La hauteur s'exprime en fonction du temps par
            :::{math}
                z(t)=h_0-(V_0t+\frac{V_0^2}{g} \ln\left(\frac{1}{2}\left(1+e^{-2tg/V_0}\right)\right)\,,
            :::
        où $V_0$ est la vitesse limite
        de chute de l'objet et $g=\SI{9.81}{\meter\per\second\squared}$.
    -   La fonction logarithme népérien est prédéfinie sous la forme
        `log(arg)` dans `<cmath>`.

    /// BEGIN SOLUTION
    :::{literalinclude} chute-libre-correction.cpp
    :start-after: BEGIN simple_chute_libre
    :end-before: END simple_chute_libre
    :::
    /// END SOLUTION

2.  Que se passe-t-il si on varie $h_0$ et $V_0$? Généralisez votre
    fonction pour prendre en paramètres additionnels la hauteur
    initiale $h_0$ et la vitesse limite de chute $V_0$. Pour la
    gravité, définir une variable globale $g$.
        **Bonus :** définir cette variable globale comme une constante
    (nous irons sur Mars une autre fois).

    /// BEGIN SOLUTION
    :::{literalinclude} chute-libre-correction.cpp
    :start-after: BEGIN chute_libre
    :end-before: END chute_libre
    :::
    /// END SOLUTION

    Écrivez les appels à la fonction précédente pour calculer $z(t)$
        pour $t=\SI{2}{s}$ et pour différentes valeur de $V_0$: $10$, $40$,
        $60$, $120$, $\SI{180}{\meter\per\second}$.

    /// BEGIN SOLUTION
        ```
    chute_libre(2,27,10);
        chute_libre(2,27,40);
        chute_libre(2,27,60);
        chute_libre(2,27,120);
        chute_libre(2,27,180);
        ```
    /// END SOLUTION

3.  Écrivez une fonction `temps_de_chute` qui prend les même
    paramètres que précédemment et utilise `chute_libre` de façon
    répétée pour déterminer une approximation de la durée $t_c$ de la
    chute du pot de fleur jusqu'au sol.

    /// BEGIN SOLUTION
    :::{literalinclude} chute-libre-correction.cpp
    :start-after: BEGIN temps_de_chute
    :end-before: END temps_de_chute
    :::
    /// END SOLUTION

4.  La vitesse limite peut être obtenue en fonction de la masse
    volumique de l'air $\rho$, du coefficient de résistance
    aérodynamique $C_x$ et de la section de l'objet $S$ à l'aide de la
    formule $V_0=\sqrt{\frac{2mg}{C_x \rho S}}$. Définissez une
    fonction `vitesse_limite` pour calculer cette formule.  Puis
    implantez de nouvelles fonctions utilisant les précédentes pour
    calculer $z(t)$ et le temps de chute $t_c$ en fonction des
    paramètres $C_x$, $S$, et $m$. On suppose que $\rho$ est une
    variable globale déjà définie.

    /// BEGIN SOLUTION
    :::{literalinclude} chute-libre-correction.cpp
    :start-after: BEGIN vitesse_limite
    :end-before: END vitesse_limite
    :::
    /// END SOLUTION

::::

+++ {"nbgrader": {"grade": true, "locked": false, "points": 0, "grade_id": "80", "schema_version": 3, "solution": true}}

::::{admonition} Exercice 8 : $\clubsuit$ Triangles rectangles à côtés entiers

**Inspiré du problème 39 du Projet Euler, Integer right triangles**

Pour un périmètre $p=120$ donné, il n'existe que trois configurations
pour un triangle rectangle dont les côté sont de longueurs entières :
$\{20, 48, 52\}, \{24, 45, 51\}, \{30, 40, 50\}$.

Documentez et écrivez une fonction `nombreTrianglesRectanglesEntiers`
qui prend en entrée un entier, le périmètre fixé, et renvoie le nombre
de configurations possibles de triangles rectangles à côtés de
longueurs entières.

**Indications :** On pensera à écrire des fonctions intermédiaires
utiles, par exemple une fonction qui vérifie que la longueur de
l'hypothénuse d'un triangle rectangle est entière et renvoie sa valeur
à partir des longueurs de ses deux autres côtés, ou une fonction qui
vérifie si la somme des longueurs des trois côtés vaut bien le
périmètre fixé. Ne pas oublier de prévoir des tests automatiques pour
chaque fonction qui le permet.

/// BEGIN SOLUTION

:::{literalinclude} triangles-rectangles-entiers-correction.cpp
:start-after: BEGIN nombreTriangles
:end-before: END nombreTriangles
:::

Avec les tests :

:::{literalinclude} triangles-rectangles-entiers-correction.cpp
:start-after: BEGIN test_nombreTriangles
:end-before: END test_nombreTriangles
:::

/// END SOLUTION

::::
