# TP 1 — CC1

**Informatique L3 — Semestre 5**
**Durée : 2 heures**
**Date : mardi 20 octobre 2026**

---

## Consignes

- Le travail est **personnel**.
- Documents autorisés : cours, travaux réalisés en TD.
- Pas de navigation web, pas de plugin IA dans l'éditeur de texte.
- Le recours à des IA ou à un appareil connecté (téléphone, montre, etc.) sera considéré comme une fraude. Les activités réseaux et les écrans seront enregistrés.
- Au cas où le TP serait fait à la maison, un usage modéré de l'IA est autorisé. Il faut dans une seconde partie du devoir expliquer comment vous avez utilisé l'IA, les prompts employés et, surtout, comment vous avez testé les programmes chez vous (installation du compilateur, de l'éditeur de texte, _etc._). Vous devez utiliser exclusivement les IA (gratuites) proposées par l'Unistra (par exemple le modèle Qwen 3.8 de [https://mai.ia.unistra.fr/](https://mai.ia.unistra.fr/)).

## Compilation et dépôt

Le template `tp1_s5_2026.cpp` est fourni (disponible sur la page web du cours). Complétez le corps des fonctions demandées dans ce fichier.

Pour tester l'exercice N, compilez puis exécutez :

```bash
g++ tp1_s5_2026.cpp -DEXO<N> -o exo<N> && ./exo<N>
```

Par exemple, pour l'exercice 1 :

```bash
g++ tp1_s5_2026.cpp -DEXO1 -o exo1 && ./exo1
```

> **Ne modifiez pas les fonctions `main()` de test** : elles servent à la correction.

À la fin de la séance, déposez le fichier `tp1_s5_2026.cpp` complété sur Moodle (ou envoyez-le par courriel).

---

## Exercices

### Exercice 1

Écrire une fonction de signature `int multiply(int, int)` qui renvoie le produit de deux entiers.

### Exercice 2

Écrire une fonction de signature `int tab_product(int n, int *tab)` qui prend en entrée un tableau d'entiers de taille `n` et qui renvoie le produit des éléments du tableau.

### Exercice 3

Écrire une fonction de signature `int tab_min(int n, int *tab)` qui prend en entrée un tableau d'entiers de taille `n` et qui renvoie la plus petite valeur de ce tableau.

### Exercice 4

Écrire une fonction de signature `int tab_min(int n, int *tab, int &i)` qui prend en entrée un tableau d'entiers de taille `n` et qui renvoie la plus petite valeur de ce tableau ainsi qu'un indice `i` correspondant à cette valeur.

### Exercice 5

Écrire une fonction de signature `int tab_min(int n, int *tab, int &size_idmin, int *idmin)` qui prend en entrée un tableau d'entiers `tab` de taille `n` et qui renvoie la plus petite valeur de ce tableau.

La fonction prend aussi en entrée un tableau d'entiers `idmin` de même taille `n` et un entier `size_idmin`. En sortie de la fonction, `size_idmin` contient le nombre d'occurrences de la plus petite valeur de `tab` et `idmin` contient les indices des occurrences de cette valeur.

Par exemple, si `tab` contient `[3, 1, 5, 1, 2]`, alors `tab_min` renvoie `1`, `idmin` contient `[1, 3, ?, ?, ?]` et `size_idmin` vaut `2`.

### Exercice 6

Écrire un ensemble de fonctions qui permettent de gérer un tableau de taille `SIZE`. La taille du tableau est donnée par une constante globale :

```cpp
const int SIZE = 10;
```

Écrire :

- Une fonction `zero_tab(int *tab)` qui met le tableau à zéro.
- Une fonction `put_tab(int *tab, int i, int v)` qui met la valeur `v` à l'indice `i` du tableau `tab`.
- Une fonction `get_length(int *tab)` qui renvoie la longueur du tableau `tab`, c'est-à-dire l'indice du dernier élément non nul plus un. Si le tableau ne contient que des zéros, sa longueur est considérée comme nulle. Par exemple, si `tab` contient `[2, 0, 4, 0, 6, 0, 0, 0, 8, 0]`, alors `get_length(tab)` renvoie `9`.
- Une fonction `remove_zeros(int *tab)` qui supprime les éléments nuls du tableau `tab` et décale les éléments non nuls vers la gauche. Par exemple, si `tab` contient `[2, 0, 4, 0, 6, 0, 0, 0, 8, 0]`, alors `remove_zeros` met `tab` à `[2, 4, 6, 8, 0, 0, 0, 0, 0, 0]`.
- Une fonction `display_tab(int *tab)` qui affiche le tableau.

### Exercice 7

Écrire deux fonctions :

```cpp
int fibonacci(int n);
void tabfibonacci(int n, int *tab);
```

**(a)** `fibonacci(n)` renvoie le n-ième nombre de la suite de Fibonacci. Cette fonction **DOIT** être récursive. On rappelle que la suite de Fibonacci est définie par `F(0) = 0`, `F(1) = 1` et `F(n) = F(n-1) + F(n-2)` pour `n >= 2`.

**(b)** `tabfibonacci(n, tab)` remplit le tableau `tab`, déjà alloué et de taille `n`, avec les `n` premiers nombres de la suite de Fibonacci. Cette fonction utilisera la fonction `fibonacci` de la question **(a)**.

Exemples :

- `fibonacci(7) == 13`.
- Après `int tab[8]; tabfibonacci(8, tab);`, le tableau `tab` contient `[0, 1, 1, 2, 3, 5, 8, 13]`.

Remarque : une version plus efficace sera programmée à l'exercice 9 ; ici, on exige que `fibonacci` soit récursive.

### Exercice 8

Écrire une fonction :

```cpp
int* factorielles(int n)
```

qui renvoie un tableau `res` de taille `n`, alloué avec `new[]`, tel que `res[i]` contient la factorielle de `i` : `res[0] = 0! = 1`, `res[1] = 1! = 1`, `res[2] = 2! = 2`, ..., `res[n-1] = (n-1)!`.

On rappelle la définition récursive de la factorielle : `0! = 1` et `n! = n × (n-1)!` pour `n >= 1`.

On pourra écrire une fonction intermédiaire :

```cpp
int factorielle(int n)
```

qui renvoie la factorielle de `n`. Quelle est la complexité de cet algorithme ? (répondre en commentaire dans le code)

### Exercice 9

Comme dans l'exercice 7, on souhaite calculer les `n` premiers nombres de Fibonacci, mais cette fois de façon optimisée : au lieu de recalculer chaque valeur avec la fonction récursive, on remplit le tableau au fur et à mesure, en stockant les résultats intermédiaires. Écrire une fonction :

```cpp
int* fast_fibonacci(int n)
```

qui renvoie un tableau de taille `n` contenant les `n` premiers nombres de Fibonacci (la fonction alloue elle-même le tableau avec `new[]`).

Vérifier que le nouvel algorithme est plus efficace. Quelle est sa complexité ? (répondre en commentaires dans le programme)

### Exercice 10

Le but de cet exercice est d'écrire un encodeur utilisant le chiffre de César. On rappelle que le chiffre de César est une méthode de chiffrement qui consiste à décaler chaque lettre de l'alphabet d'un nombre fixe de positions. Par exemple, avec un décalage de 3, `abc` devient `def` et `xyz` devient `abc`.

Écrire une fonction :

```cpp
char* cesar(char* s, int shift)
```

qui renvoie une chaîne de caractères contenant le texte chiffré de la chaîne `s` avec un décalage de `shift` positions. La fonction devra allouer la mémoire pour cette chaîne (avec `new[]`). On considère uniquement les lettres minuscules de l'alphabet et on conserve les espaces. On pourra utiliser la fonction `strlen` pour connaître la longueur de la chaîne `s` (attention, cette fonction ne compte pas le caractère de fin de chaîne `\0`).

> **Rappel — manipulation des `char`.** En C++, un `char` est stocké sous forme d'un entier (son code). Les lettres minuscules ont des codes consécutifs : `'b' == 'a' + 1`, `'c' == 'a' + 2`, etc. On peut donc obtenir la position d'une lettre dans l'alphabet avec `s[i] - 'a'` (par exemple `'e' - 'a' == 4`) et reconstruire une lettre à partir de sa position avec `'a' + pos`. L'opérateur modulo (`%`) gère le retour au début de l'alphabet : avec un décalage de 3, `'y'` (position 24) devient `'b'` (position `(24 + 3) % 26 == 1`).

## TP à la maison

Si le TP est fait à la maison, ajouter à la fin du fichier de rendu, au format markdown, la description de votre usage de l'IA et de l'installation de votre système personnel de programmation C++ (éditeur de texte, installation du compilateur, tests de vos programmes). La compétence évaluée ici est votre capacité à mettre en place sur votre propre matériel des outils de programmation.
