Skip to main content

Pokemon Banner

Tiplouf Adventure

Auteur : Gabriel Dezon Code reviewer : Arthur Wambst

Introduction

Lore

Vos débuts en tant que Dresseur Pokémon dans la région de Sinnoh ont commencé il y a quelques semaines, quand vous avez pu apprendre grâce à l'école Pokémon et notamment au professeur Bertin, que vous étiez éligible pour recevoir votre premier Pokémon.

Il va être tant de partir à l'aventure afin de mettre en pratique tout ce que vous avez appris jusqu'à présent !

Le professeur Bertin vous as donné rendez-vous dans son laboratoire afin que vous puissiez choisir votre premier Pokémon.

Quel choix faites-vous ?

Quel Pokémon choisissez-vous ?

Ok maintenant que vous avez choisi votre Pokémon (et fait le bon choix), il est temps de partir à l'aventure !

Commençons l'aventure !

Architecture

À la fin, votre dépôt git doit suivre cette architecture :

Vérification de l'arborescence : Vous pouvez vérifier l'arborescence actuelle de votre dépôt avec la commande suivante :

tree . -I '.git' -a
Arborescence
.
├── 201_road
│ ├── calculate_exp
│ │ ├── calculate_exp.c
│ │ ├── calculate_exp.h
| | |── main.c
│ │ └── Makefile
│ ├── count_pokemons
│ │ ├── count_pokemons.c
│ │ ├── count_pokemons.h
│ │ ├── main.c
│ │ └── Makefile
│ ├── choose_page
│ │ ├── choose_page.c
│ │ ├── choose_page.h
│ │ ├── main.c
│ │ └── Makefile
│ ├── confused_reverse
│ │ ├── confused_reverse.c
│ │ ├── confused_reverse.h
│ │ ├── main.c
│ │ └── Makefile
│ └── seeking_fight
│ ├── seeking_fight.c
│ ├── seeking_fight.h
│ ├── main.c
│ └── Makefile
├── vestigion_forest
│ ├── get_pokemons
│ │ ├── get_pokemons.c
│ │ ├── get_pokemons.h
│ │ ├── main.c
│ │ └── Makefile
│ ├── hurlement
│ │ ├── hurlement.c
│ │ ├── hurlement.h
│ │ ├── main.c
│ │ └── Makefile
│ ├── check_pokedex
│ │ ├── check_pokedex.c
│ │ ├── check_pokedex.h
│ │ ├── main.c
│ │ └── Makefile
│ ├── load_pokedex
│ │ ├── load_pokedex.c
│ │ ├── load_pokedex.h
│ │ ├── main.c
│ │ └── Makefile
│ └── horde
│ ├── horde.c
│ ├── horde.h
│ ├── main.c
│ └── Makefile
├── feli_cite
│ └── pokemon_struct
│ ├── pokemon_struct.c
│ ├── pokemon_struct.h
│ ├── main.c
│ └── Makefile
├── pokemon_gym
│ └── tournament_winner
│ ├── tournament_winner.c
│ ├── tournament_winner.h
│ ├── main.c
│ └── Makefile
├── README
└── .gitignore

Exigences importantes avant soumission :

  • Le fichier README est obligatoire.
  • Le fichier .gitignore est obligatoire.
  • Le code DOIT compiler ! Sinon vous n'obtiendrez pas de note.

Route 201: Echauffement

File: 201_road/calculate_exp/calculate_exp.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Arrays
  • Boucles
Imports autorisés
  • stddef.h
  • stdlib.h
Given Files
201_road/calculate_exp/calculate_exp.h
#ifndef CALCULATE_EXP_H
#define CALCULATE_EXP_H

#include <stddef.h>
#include <stdlib.h>

unsigned int calculate_exp(const unsigned int *exp_array, size_t size);

#endif // CALCULATE_EXP_H
201_road/calculate_exp/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = calculate_exp
SRCS = main.c calculate_exp.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Au cours de nos aventures, Tiplouf aura l'occasion de gangner beaucoup d'expérience lors de ses combats avec les autres pokemons. Nous devons trouver un moyen fiable de calculer combien de niveaux il a gagné en fonction de l'expérience qu'il a accumulé.

Écrivez une fonction calculate_exp qui prend en entrée un tableau de unsigned intreprésentant les points d'expérience gagnés par Tiplouf lors de ses combats. Tiplouf gagne un niveau chaque fois qu'il accumule 100 points d'expérience. La fonction doit retourner le nombre de niveaux gagnés par Tiplouf.

Prototype
unsigned int calculate_exp(const unsigned int *exp_array, size_t size);
Example
201_road/calculate_exp/main.c
#include <stdio.h>
#include "calculate_exp.h"

int main(void) {
unsigned int exp1[] = {50, 60, 70};
unsigned int exp2[] = {100, 200, 300};
unsigned int exp3[] = {150, 250, 350, 90, 10, 40};
unsigned int result1 = calculate_exp(exp1, 3);
unsigned int result2 = calculate_exp(exp2, 3);
unsigned int result3 = calculate_exp(exp3, 6);

printf("calculate_exp({50, 60, 70}) = %u\n", result1); // 1
printf("calculate_exp({100, 200, 300}) = %u\n", result2); // 6
printf("calculate_exp({150, 250, 350, 90, 10, 40}) = %u\n", result3); // 8

return 0;
}
output
$ make
$ ./calculate_exp
calculate_exp({50, 60, 70}) = 1
calculate_exp({100, 200, 300}) = 6
calculate_exp({150, 250, 350, 90, 10, 40}) = 8

File: 201_road/count_pokemons/count_pokemons.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Strings
Imports autorisés
  • stddef.h
  • stdlib.h
Given Files
201_road/count_pokemons/count_pokemons.h
#ifndef COUNT_POKEMONS_H
#define COUNT_POKEMONS_H

#include <stddef.h>
#include <stdlib.h>

int count_pokemons(const char *str);

#endif // COUNT_POKEMONS_H
201_road/count_pokemons/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = count_pokemons
SRCS = main.c count_pokemons.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Il t'arrive de recevoir des notes du professeur Bertin, te listant les pokemons que tu peux croiser dans la région de Sinnoh. Tu dois être capable de déterminer en un coup d'œil combien de pokemons sont listés.

Écrivez une fonction count_pokemons qui prend en entrée une chaîne de caractères et qui compte le nombre de Pokémons présents dans cette chaîne. Les noms de Pokémons sont séparés par des espaces ou tout autre caractère non alphabétique.

Prototype
int count_pokemons(const char *str);
Example
201_road/count_pokemons/main.c
#include <stdio.h>
#include "count_pokemons.h"

int main(void) {
int count1 = count_pokemons("Pikachu Bulbizarre Salameche Carapuce");
int count2 = count_pokemons("Evoli, Dracaufeu; Mewtwo");
int count3 = count_pokemons(" ;; Mewtwo-Mew - ");
int count4 = count_pokemons("Pikachu123Bulbizarre!Salameche@Carapuce#");

printf("count_pokemons(\"Pikachu Bulbizarre Salameche Carapuce\") = %d\n", count1); // 4
printf("count_pokemons(\"Evoli, Dracaufeu; Mewtwo\") = %d\n", count2); // 3
printf("count_pokemons(\" ;; Mewtwo-Mew - \") = %d\n", count3); // 2
printf("count_pokemons(\"Pikachu123Bulbizarre!Salameche@Carapuce#\") = %d\n", count4); // 4

return 0;
}
output
$ make
$ ./count_pokemons
count_pokemons("Pikachu Bulbizarre Salameche Carapuce") = 4
count_pokemons("Evoli, Dracaufeu; Mewtwo") = 3
count_pokemons(" ;; Mewtwo-Mew - ") = 2
count_pokemons("Pikachu123Bulbizarre!Salameche@Carapuce#") = 4

File: 201_road/choose_page/choose_page.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Arithmétique des pointeurs
Imports autorisés
  • stddef.h
  • stdlib.h
Given Files
201_road/choose_page/choose_page.h
#ifndef CHOOSE_PAGE_H
#define CHOOSE_PAGE_H

#include <stddef.h>
#include <stdlib.h>

void choose_page(char **arr, size_t nb_pokemon, size_t page, char*** out_page, size_t* out_size);

#endif // CHOOSE_PAGE_H
201_road/choose_page/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = choose_page
SRCS = main.c choose_page.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Vous allez commencer à avoir une grande collection de Pokémons ! Afin de mieux vous y retrouver, vous allez les stocker sur un PC, dans la boîte du Professeur Bertin. Dans ce PC, les pokémons sont affichés par page, chaque page contenant maximum 10 Pokémons.

Écrivez une fonction choose_page qui permet de naviguer dans un tableau de Pokémons en pages. Chaque page contient exactement 10 Pokémons. La fonction prend en paramètres :

  • arr : un tableau de pointeurs vers des chaînes de caractères (noms de Pokémons)
  • nb_pokemon : le nombre total de Pokémons dans le tableau
  • page : le numéro de la page demandée (en commençant à 1)
  • out_page : pointeur vers un pointeur qui recevra l'adresse du début de la page demandée
  • out_size : pointeur vers un size_t qui recevra le nombre de Pokémons dans cette page

La fonction remplit les deux paramètres de sortie. Si la page demandée est invalide (hors limites), mettez out_page et out_size à 0 (ou NULL pour le pointeur).

warning

Note : Vous ne devez pas allouer de mémoire dans cette fonction. Vous devez vous limiter à des manipulations de pointeurs.

Prototype
void choose_page(char **arr, size_t nb_pokemon, size_t page, char*** out_page, size_t* out_size);
Example
201_road/choose_page/main.c
#include <stdio.h>
#include "choose_page.h"

void print_page(char **page, size_t size) {
if (!page || size == 0) {
printf("Page vide ou invalide\n");
return;
}
for (size_t i = 0; i < size; i++) {
printf(" [%zu] %s\n", i, page[i]);
}
}

int main(void) {
char *pokemons[35] = {
"Pikachu", "Bulbizarre", "Salameche", "Carapuce", "Evoli",
"Mewtwo", "Dracaufeu", "Tiplouf", "Tortipouss", "Ouisticram",
"Roucool", "Magicarpe", "Rattata", "Rondoudou", "Nosferapti",
"Abo", "Machoc", "Psykokwak", "Caninos", "Goupix",
"Miaouss", "Mystherbe", "Ortide", "Rafflesia", "Paras",
"Parasect", "Jonquille", "Ortide", "Glabelle", "Taupiqueur",
"Sabelette", "Sablaireau", "Nidoran-F", "Nidorina", "Nidoqueen"
};
size_t nb_pokemon = 35;

// Test 1 : Page 1
char **page1;
size_t size1;
choose_page(pokemons, nb_pokemon, 1, &page1, &size1);
if (page1) {
printf("=== Page 1 ===\n");
print_page(page1, size1);
}

// Test 2 : Page 2
char **page2;
size_t size2;
choose_page(pokemons, nb_pokemon, 2, &page2, &size2);
if (page2) {
printf("\n=== Page 2 ===\n");
print_page(page2, size2);
}

// Test 3 : Page 4 (partielle)
char **page4;
size_t size4;
choose_page(pokemons, nb_pokemon, 4, &page4, &size4);
if (page4) {
printf("\n=== Page 4 (partielle) ===\n");
print_page(page4, size4);
}

// Test 4 : Page invalide
char **page_invalid;
size_t size_invalid;
choose_page(pokemons, nb_pokemon, 5, &page_invalid, &size_invalid);
if (page_invalid == NULL) {
printf("\n=== Page 5 (invalide) ===\n");
printf("Page invalide : out_page = NULL\n");
}

return 0;
}
output
$ make
$ ./choose_page
=== Page 1 ===
[0] Pikachu
[1] Bulbizarre
[2] Salameche
[3] Carapuce
[4] Evoli
[5] Mewtwo
[6] Dracaufeu
[7] Tiplouf
[8] Tortipouss
[9] Ouisticram

=== Page 2 ===
[0] Roucool
[1] Magicarpe
[2] Rattata
[3] Rondoudou
[4] Nosferapti
[5] Abo
[6] Machoc
[7] Psykokwak
[8] Caninos
[9] Goupix

=== Page 4 (partielle) ===
[0] Sabelette
[1] Sablaireau
[2] Nidoran-F
[3] Nidorina
[4] Nidoqueen

=== Page 5 (invalide) ===
Page invalide : out_page = NULL

File: 201_road/confused_reverse/confused_reverse.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • strings
Imports autorisés
  • stddef.h
  • stdlib.h
Given Files
201_road/confused_reverse/confused_reverse.h
#ifndef CONFUSED_REVERSE_H
#define CONFUSED_REVERSE_H

#include <stddef.h>
#include <stdlib.h>

void confused_reverse(char *s);

#endif // CONFUSED_REVERSE_H
201_road/confused_reverse/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = confused_reverse
SRCS = main.c confused_reverse.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Tiplouf est confus ! Il répète toutes ses phrases à l'envers. Écrivez une fonction confused_reverse qui inverse une chaîne de caractères EN PLACE.

Prototype
void confused_reverse(char *s);
Example
201_road/confused_reverse/main.c
#include <stdio.h>
#include "confused_reverse.h"

int main(void) {
char phrase1[] = "Tiplouf est confus !";
char phrase2[] = "Pokemon";
char phrase3[] = "AlEd";
confused_reverse(phrase1);
confused_reverse(phrase2);
confused_reverse(phrase3);
printf("\"Tiplouf est confus !\" -> \"%s\"\n", phrase1); // ! sufnoc tse fuolpiT
printf("\"Pokemon\" -> \"%s\"\n", phrase2); // nomekoP
printf("\"AlEd\" -> \"%s\"\n", phrase3); // dElA
return 0;
}
output
$ make
$ ./confused_reverse
"Tiplouf est confus !" -> "! sufnoc tse fuolpiT"
"Pokemon" -> "nomekoP"
"AlEd" -> "dElA"

File: 201_road/seeking_fight/seeking_fight.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Tableaux 2D
  • strings
Imports autorisés
  • stddef.h
  • stdlib.h
  • err.h
  • math.h
Given Files
201_road/seeking_fight/seeking_fight.h
#ifndef SEEKING_FIGHT_H
#define SEEKING_FIGHT_H

#include <stddef.h>

char *seeking_fight(char ***matrix, size_t rows, size_t cols, size_t x, size_t y);

#endif // SEEKING_FIGHT_H
201_road/seeking_fight/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
LDFLAGS = -lm
TARGET = seeking_fight
SRCS = main.c seeking_fight.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task
tip

La distance euclidienne entre deux points (x1, y1) et (x2, y2) est définie par :

distance = racine( (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) )

  • x1 et y1 : coordonnées du premier point
  • x2 et y2 : coordonnées du second point
  • (x2 - x1) * (x2 - x1) : carré de la différence des abscisses
  • (y2 - y1) * (y2 - y1) : carré de la différence des ordonnées
  • racine(...) : racine carrée du résultat

Il existe deux types de dresseurs, les dresseurs ambitions qui laissent les pokemons venir à eux, les prendre par surprise, et les dresseurs avec un minimum d'ambition qui vont chercher les pokemons eux-mêmes. Comment vous dire que l'un des deux n'ira pas bien loin dans la région de Sinnoh... Donc hop, hop, hop, écivons une fonction pour trouver le pokemon le plus proche dans les hautes herbes.

Écrivez une fonction seeking_fight qui prend en paramètres une matrice de char* représentant la carte, ses dimensions (rows, cols), et vos coordonnées (x, y). La fonction doit retourner le nom du Pokémon le plus proche de vous (utilisez la distance euclidienne). Une case vide est représentée par un pointeur NULL, donc un Pokémon n'est présent que si la case contient une chaîne de caractères non NULL.

Si plusieurs Pokémons sont à la même distance minimale, retournez celui qui apparaît en premier lors d'un parcours ligne par ligne de la matrice (de gauche à droite, de haut en bas).

Si les paramètres sont invalides (matrice NULL, x ou y hors de la matrice), appelez errx(EXIT_FAILURE, "message d'erreur") avec un message d'erreur approprié.

La fonction sqrt

La fonction sqrt de la bibliothèque math.h peut être utile pour calculer la racine carrée.

double sqrt(double x);
Prototype
char *seeking_fight(char ***matrix, size_t rows, size_t cols, size_t x, size_t y);
Example
201_road/seeking_fight/main.c
#include <stdio.h>
#include "seeking_fight.h"

int main(void) {
char *row0[] = {NULL, NULL, NULL, "Pikachu", NULL, NULL, NULL};
char *row1[] = {NULL, "Bulbizarre", NULL, NULL, NULL, "Evoli", NULL};
char *row2[] = {NULL, NULL, "Salameche", NULL, "Carapuce", NULL, NULL};
char *row3[] = {"Mewtwo", NULL, NULL, NULL, NULL, NULL, "Dracaufeu"};
char *row4[] = {NULL, "Tiplouf", NULL, NULL, NULL, "Tortipouss", NULL};
char *row5[] = {NULL, NULL, "Ouisticram", NULL, "Roucool", NULL, NULL};
char *row6[] = {NULL, NULL, NULL, "Magicarpe", NULL, NULL, NULL};
char **matrix[] = {row0, row1, row2, row3, row4, row5, row6};
size_t rows = 7, cols = 7;

// Test 1 : position centrale
size_t x1 = 3, y1 = 3;
char *closest1 = seeking_fight(matrix, rows, cols, x1, y1);
printf("Test 1: Le Pokemon le plus proche est : %s\n", closest1);

// Test 2 : coin haut gauche
size_t x2 = 0, y2 = 0;
char *closest2 = seeking_fight(matrix, rows, cols, x2, y2);
printf("Test 2: Le Pokemon le plus proche est : %s\n", closest2);

// Test 3 : bord bas droit
size_t x3 = 6, y3 = 6;
char *closest3 = seeking_fight(matrix, rows, cols, x3, y3);
printf("Test 3: Le Pokemon le plus proche est : %s\n", closest3);

// Test 4 : parametres invalides (x hors limites) -> errx EXIT_FAILURE
size_t x_invalid = 10;
size_t y_valid = 3;
seeking_fight(matrix, rows, cols, x_invalid, y_valid);

return 0;
}
output
$ make
$ ./seeking_fight
Test 1: Le Pokemon le plus proche est : Salameche
Test 2: Le Pokemon le plus proche est : Bulbizarre
Test 3: Le Pokemon le plus proche est : Tortipouss
seeking_fight: Coordonnees (10, 3) invalides pour une matrice 7x7

Forêt de Vestigion (à l'attaque de la mémoire)

File: vestigion_forest/get_pokemons/get_pokemons.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Gestion dynamique de la mémoire (malloc, free)
  • strings
  • Arithmétique des pointeurs
Imports autorisés
  • stddef.h
  • stdlib.h
  • string.h
Given Files
vestigion_forest/get_pokemons/get_pokemons.h
#ifndef GET_POKEMONS_H
#define GET_POKEMONS_H

char *get_pokemons(char **pokemons, char sep);

#endif // GET_POKEMONS_H
vestigion_forest/get_pokemons/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = get_pokemons
SRCS = main.c get_pokemons.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Vous vous souvenez ? Le professeur Bertin vous a demandé de lui fournir une liste de tous les Pokémons que vous avez rencontrés jusqu'à présent, mais pas question delui envoyer un par un ! Elle veut que vous poussiez lui envoyer tout d'un coup!

Écrivez une fonction get_pokemons qui prend en paramètres :

  • pokemons : un tableau de pointeurs vers des chaînes de caractères (noms de Pokémons), terminé par NULL
  • sep : un caractère séparateur

La fonction doit allouer dynamiquement une nouvelle chaîne de caractères qui concatène tous les Pokémons du tableau, séparés par le caractère sep.

Exemple : Si pokemons = {"Pikachu", "Bulbizarre", "Salamèche", NULL} et sep = ',', la fonction retourne une chaîne contenant "Pikachu,Bulbizarre,Salamèche".

La fonction doit aussi gérer les cas limites :

  • Si le tableau est vide ou NULL, retournez une chaîne vide "".
Prototype
char *get_pokemons(char **pokemons, char sep);
Example
vestigion_forest/get_pokemons/main.c
#include <stdio.h>
#include <stdlib.h>
#include "get_pokemons.h"

int main(void) {
// Test 1 : avec separateur virgule
char *pokemons1[] = {"Pikachu", "Bulbizarre", "Salameche", NULL};
char *result1 = get_pokemons(pokemons1, ',');
printf("Test 1: %s\n", result1); // Pikachu,Bulbizarre,Salameche
free(result1);

// Test 2 : avec separateur espace
char *pokemons2[] = {"Tiplouf", "Evoli", "Mewtwo", NULL};
char *result2 = get_pokemons(pokemons2, ' ');
printf("Test 2: %s\n", result2); // Tiplouf Evoli Mewtwo
free(result2);

// Test 3 : avec separateur tiret
char *pokemons3[] = {"Roucool", "Magicarpe", NULL};
char *result3 = get_pokemons(pokemons3, '-');
printf("Test 3: %s\n", result3); // Roucool-Magicarpe
free(result3);

// Test 4 : tableau vide
char *pokemons4[] = {NULL};
char *result4 = get_pokemons(pokemons4, ',');
printf("Test 4: '%s' (vide)\n", result4); // (chaine vide)
free(result4);

// Test 5 : un seul Pokemon
char *pokemons5[] = {"Dracaufeu", NULL};
char *result5 = get_pokemons(pokemons5, ',');
printf("Test 5: %s\n", result5); // Dracaufeu
free(result5);

return 0;
}
output
$ make
$ ./get_pokemons
Test 1: Pikachu,Bulbizarre,Salameche
Test 2: Tiplouf Evoli Mewtwo
Test 3: Roucool-Magicarpe
Test 4: '' (vide)
Test 5: Dracaufeu

File: vestigion_forest/hurlement/hurlement.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Manipulation de tableaux
  • Allocation mémoire
Imports autorisés
  • stddef.h
  • stdlib.h
Given Files
vestigion_forest/hurlement/hurlement.h
#ifndef HURLEMENT_H
#define HURLEMENT_H

#include <stddef.h>

void hurlement(const char **tab, size_t n, size_t k);

#endif // HURLEMENT_H
vestigion_forest/hurlement/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = hurlement
SRCS = main.c hurlement.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Tiplouf rencontre un nouveau Pokémon dans les hautes herbes de la Forêt de Vestigion : un Grahyèna ! Ce dernier pousse un hurlement qui fait fuir Tiplouf et t'oblige à réorganiser ton équipe de Pokémons. Pour cela, tu dois effectuer une rotation à droite sur ton équipe.

Écrivez une fonction hurlement qui prend en paramètres :

  • tab : un tableau de pointeurs vers des chaînes de caractères (noms de Pokémons)
  • n : le nombre de Pokémons dans le tableau
  • k : le nombre de positions à faire tourner vers la droite

La fonction doit allouer dynamiquement un nouveau tableau de chaînes de caractères, effectuer la rotation à droite de k positions, et retourner ce nouveau tableau. Le tableau retourné doit être terminé par un pointeur NULL.

Exemple : Si tab = ["Pikachu", "Bulbizarre", "Salameche", "Carapuce"], n = 4, et k = 2, la fonction retourne ["Salameche", "Carapuce", "Pikachu", "Bulbizarre", NULL].

Prototype
char** hurlement(const char **tab, size_t n, size_t k);
Example
vestigion_forest/hurlement/main.c
#include <stdio.h>
#include <stdlib.h>
#include "hurlement.h"

void print_tab(char **tab, size_t n) {
for (size_t i = 0; i < n; i++) {
printf("%s", tab[i]);
if (i < n - 1) printf(", ");
}
printf("\n");
}

int main(void) {
// Test 1 : rotation de 2 positions
const char *tab1[] = {"Pikachu", "Bulbizarre", "Salameche", "Carapuce"};
printf("Test 1 - Avant: ");
print_tab(tab1, 4);
char **res1 = hurlement(tab1, 4, 2);
printf("Test 1 - Apres (k=2): ");
print_tab(res1, 4); // Salameche, Carapuce, Pikachu, Bulbizarre
free(res1);

// Test 2 : rotation de 1 position
const char *tab2[] = {"Tiplouf", "Evoli", "Mewtwo", "Roucool"};
printf("\nTest 2 - Avant: ");
print_tab(tab2, 4);
char **res2 = hurlement(tab2, 4, 1);
printf("Test 2 - Apres (k=1): ");
print_tab(res2, 4); // Roucool, Tiplouf, Evoli, Mewtwo
free(res2);

// Test 3 : rotation de 0 position
const char *tab3[] = {"Dracaufeu", "Ouisticram", "Tortipouss"};
printf("\nTest 3 - Avant: ");
print_tab(tab3, 3);
char **res3 = hurlement(tab3, 3, 0);
printf("Test 3 - Apres (k=0): ");
print_tab(res3, 3); // Dracaufeu, Ouisticram, Tortipouss
free(res3);

// Test 4 : rotation superieure a n
const char *tab4[] = {"Nosferapti", "Abo", "Machoc"};
printf("\nTest 4 - Avant: ");
print_tab(tab4, 3);
char **res4 = hurlement(tab4, 3, 5); // 5 % 3 = 2
printf("Test 4 - Apres (k=5, equivalent a k=2): ");
print_tab(res4, 3); // Machoc, Nosferapti, Abo
free(res4);

return 0;
}
output
$ make
$ ./hurlement
Test 1 - Avant: Pikachu, Bulbizarre, Salameche, Carapuce
Test 1 - Apres (k=2): Salameche, Carapuce, Pikachu, Bulbizarre

Test 2 - Avant: Tiplouf, Evoli, Mewtwo, Roucool
Test 2 - Apres (k=1): Roucool, Tiplouf, Evoli, Mewtwo

Test 3 - Avant: Dracaufeu, Ouisticram, Tortipouss
Test 3 - Apres (k=0): Dracaufeu, Ouisticram, Tortipouss

Test 4 - Avant: Nosferapti, Abo, Machoc
Test 4 - Apres (k=5, equivalent a k=2): Machoc, Nosferapti, Abo

File: vestigion_forest/check_pokedex/check_pokedex.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Gestion des processus (fork, wait, waitpid)
  • Appels système (execvp)
  • strings
Imports autorisés
  • stddef.h
  • stdlib.h
  • unistd.h
  • sys/wait.h
Given Files
vestigion_forest/check_pokedex/check_pokedex.h
#ifndef CHECK_POKEDEX_H
#define CHECK_POKEDEX_H

void check_pokedex(const char *command);

#endif // CHECK_POKEDEX_H
vestigion_forest/check_pokedex/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = check_pokedex
SRCS = main.c check_pokedex.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Au bout du 50 messages reçus par le Professeur Bertin pour la même question dont la réponse est toujours "RTFM", elle décide de vous apprendre à lire dans le manuel par vous-même. Pour cela, elle vous demande d'écrire une fonction qui affiche la page de manuel d'une commande donnée.

Écrivez une fonction check_pokedex qui prend en paramètre une chaîne de caractères représentant une commande (p. ex. "ls", "grep", "gcc"), et affiche le manuel (man page) de cette commande.

La fonction doit :

  1. Créer un processus enfant
  2. Dans le processus enfant : exécuter la commande man avec la commande donnée en paramètre (ex: man ls)
  3. Dans le processus parent : attendre la fin du processus enfant puis écrire *** programme successful *** si l'exécution s'est bien passée, ou *** programme failed *** sinon. Une exécution est considérée comme réussie si le processus enfant se termine avec un code de retour 0.
Prototype
void check_pokedex(const char *command);
Example
vestigion_forest/check_pokedex/main.c
#include <stdio.h>
#include "check_pokedex.h"

int main(void) {
printf("=== Consultation du Pokedex pour 'ls' ===\n");
check_pokedex("ls");

printf("=== Consultation du Pokedex pour 'tiplouf' ===\n");
check_pokedex("tiplouf");

return 0;
}
output
$ make
$ ./check_pokedex
=== Consultation du Pokedex pour 'ls' ===
LS(1) User Commands LS(1)

NAME
ls - list directory contents

SYNOPSIS
ls [OPTION]... [FILE]...

DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is spec-
ified.

...

*** programme successful ***
=== Consultation du Pokedex pour 'tiplouf' ===
No manual entry for tiplouf
*** programme failed ***

File: vestigion_forest/load_pokedex/load_pokedex.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Gestion dynamique de la mémoire (malloc, realloc, free)
  • Manipulation de pointeurs
  • Arithmétique des pointeurs
Imports autorisés
  • stddef.h
  • stdlib.h
  • string.h
Given Files
vestigion_forest/load_pokedex/load_pokedex.h
#ifndef LOAD_POKEDEX_H
#define LOAD_POKEDEX_H

#include <stddef.h>

void load_pokedex(int** pokedex, const int* other_pokedex, size_t* len_pokedex, size_t len_other_pokedex);

#endif // LOAD_POKEDEX_H
vestigion_forest/load_pokedex/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = load_pokedex
SRCS = main.c load_pokedex.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Vous dépassez la capacité de votre Pokédex actuel, vous en recevez donc un nouveau de la part du Professeur Bertin. Il faut maintenant charger les données de l'ancien Pokédex dans le nouveau.

Écrivez une fonction load_pokedex qui fusionne deux Pokédex (tableaux d'entiers) en mettant à jour le premier.

La fonction prend en paramètres :

  • pokedex : pointeur vers un pointeur d'entiers (le Pokédex principal à fusionner et redimensionner)
  • other_pokedex : pointeur vers un tableau d'entiers (le Pokédex à ajouter)
  • len_pokedex : pointeur vers la taille actuelle du premier Pokédex (sera mise à jour)
  • len_other_pokedex : la taille du deuxième Pokédex

La fonction doit :

  1. Réallouer le premier Pokédex pour accueillir les éléments du deuxième
  2. Copier tous les éléments du other_pokedex à la fin du pokedex
  3. Mettre à jour la valeur pointée par len_pokedex avec la nouvelle taille

Exemple : Si pokedex = [1, 2, 3] (taille 3) et other_pokedex = [4, 5] (taille 2), après l'appel, pokedex devient [1, 2, 3, 4, 5] et len_pokedex devient 5.

Prototype
void load_pokedex(int** pokedex, const int* other_pokedex, size_t* len_pokedex, size_t len_other_pokedex);
Example
vestigion_forest/load_pokedex/main.c
#include <stdio.h>
#include <stdlib.h>
#include "load_pokedex.h"

void print_pokedex(const int *pokedex, size_t len) {
printf("[");
for (size_t i = 0; i < len; i++) {
printf("%d", pokedex[i]);
if (i < len - 1) printf(", ");
}
printf("]\n");
}

int main(void) {
// Test 1 : fusion basique
int *pokedex1 = malloc(3 * sizeof(int));
pokedex1[0] = 1; pokedex1[1] = 2; pokedex1[2] = 3;
size_t len1 = 3;

int other1[] = {4, 5};
size_t len_other1 = 2;

printf("Test 1 - Avant: ");
print_pokedex(pokedex1, len1);

load_pokedex(&pokedex1, other1, &len1, len_other1);

printf("Test 1 - Apres: ");
print_pokedex(pokedex1, len1); // [1, 2, 3, 4, 5]
free(pokedex1);

// Test 2 : fusion avec un Pokedex vide
int *pokedex2 = malloc(2 * sizeof(int));
pokedex2[0] = 10; pokedex2[1] = 20;
size_t len2 = 2;

int other2[] = {};
size_t len_other2 = 0;

printf("\nTest 2 - Avant: ");
print_pokedex(pokedex2, len2);

load_pokedex(&pokedex2, other2, &len2, len_other2);

printf("Test 2 - Apres: ");
print_pokedex(pokedex2, len2); // [10, 20]
free(pokedex2);

// Test 3 : fusion d'un Pokedex vide avec des donnees
int *pokedex3 = malloc(1 * sizeof(int));
pokedex3[0] = 0;
size_t len3 = 1;

int other3[] = {100, 200, 300};
size_t len_other3 = 3;

printf("\nTest 3 - Avant: ");
print_pokedex(pokedex3, len3);

load_pokedex(&pokedex3, other3, &len3, len_other3);

printf("Test 3 - Apres: ");
print_pokedex(pokedex3, len3); // [0, 100, 200, 300]
free(pokedex3);

// Test 4 : fusion avec des Pokedex plus grands
int *pokedex4 = malloc(5 * sizeof(int));
for (int i = 0; i < 5; i++) pokedex4[i] = i + 1;
size_t len4 = 5;

int other4[] = {10, 20, 30, 40, 50, 60};
size_t len_other4 = 6;

printf("\nTest 4 - Avant: ");
print_pokedex(pokedex4, len4);

load_pokedex(&pokedex4, other4, &len4, len_other4);

printf("Test 4 - Apres: ");
print_pokedex(pokedex4, len4); // [1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60]
free(pokedex4);

return 0;
}
output
$ make
$ ./load_pokedex
Test 1 - Avant: [1, 2, 3]
Test 1 - Apres: [1, 2, 3, 4, 5]

Test 2 - Avant: [10, 20]
Test 2 - Apres: [10, 20]

Test 3 - Avant: [0]
Test 3 - Apres: [0, 100, 200, 300]

Test 4 - Avant: [1, 2, 3, 4, 5]
Test 4 - Apres: [1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60]

File: vestigion_forest/horde/horde.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Gestion des processus (fork, wait, waitpid)
  • Affichage concurrentiel (printf)
  • Boucles et itération
Imports autorisés
  • stddef.h
  • stdlib.h
  • stdio.h
  • unistd.h
  • sys/wait.h
Given Files
vestigion_forest/horde/horde.h
#ifndef HORDE_H
#define HORDE_H

#include <stddef.h>

void horde(size_t nb);

#endif // HORDE_H
vestigion_forest/horde/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = horde
SRCS = main.c horde.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Écrivez une fonction horde qui crée nb processus enfants en utilisant fork().

Chaque processus enfant doit :

  • Afficher : "Pokemon [PID]: Attaque Tiplouf"
    • Remplacer [PID] par l'identifiant réel du processus (obtenu avec getpid())
  • Puis terminer

Le processus parent doit :

  • Attendre que tous les enfants se terminent
  • Après que tous les enfants aient terminé, afficher : "A toi de jouer"

Exemple : Si nb = 3, créer 3 Pokémons qui attaquent tous Tiplouf, puis le parent répond "A toi de jouer".

Prototype
void horde(size_t nb);
Example
vestigion_forest/horde/main.c
#include <stdio.h>
#include "horde.h"

int main(void) {
printf("=== Début de la horde ===\n");
horde(3);
printf("=== Fin de la horde ===\n");

return 0;
}
output
$ make
$ ./horde
=== Début de la horde ===
Pokemon [1234]: Attaque Tiplouf
Pokemon [1235]: Attaque Tiplouf
Pokemon [1236]: Attaque Tiplouf
A toi de jouer
=== Fin de la horde ===
note

Les PIDs et l'ordre d'affichage peuvent varier d'une exécution à l'autre.

Féli-Cité (Structures et Gestion de Mémoire)

File: feli_cite/pokemon_struct/pokemon_struct.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Structures (struct)
  • Gestion dynamique de la mémoire (malloc, free)
  • strings
  • Tableaux de pointeurs
Imports autorisés
  • stddef.h
  • stdlib.h
  • stdio.h
  • string.h
Given Files
feli_cite/pokemon_struct.h
#ifndef POKEMON_STRUCT_H
#define POKEMON_STRUCT_H

#include <stddef.h>

struct Pokemon {
char* name;
int health;
int level;
};

struct Pokemon *pokemon_init(const char *name, int base_health);
void pokemon_free(struct Pokemon *pokemon);
void pokemon_print(const struct Pokemon *pokemon);
const char *pokemon_get_name(const struct Pokemon *pokemon);
struct Pokemon **get_all_pokemon_evolved(struct Pokemon **pokemons, size_t size, int level_threshold);

#endif // POKEMON_STRUCT_H
feli_cite/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = pokemon_struct
SRCS = main.c pokemon_struct.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
feli_cite/main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pokemon_struct.h"

void test_pokemon_print(void) {
printf("=== Test: pokemon_print ===\n");
printf("Pokemon cree:\n");
Pokemon *bulbizarre = pokemon_init("Bulbizarre", 45);
pokemon_print(bulbizarre);
pokemon_free(bulbizarre);
}

void test_pokemon_get_name(void) {
printf("=== Test: pokemon_get_name ===\n");
Pokemon *carapuce = pokemon_init("Carapuce", 44);
const char *name = pokemon_get_name(carapuce);
printf("Recuperation du nom: %s\n", name);
pokemon_free(carapuce);
}

void test_pokemon_evolved(void) {
printf("=== Test: get_all_pokemon_evolved ===\n");

Pokemon *pikachu = pokemon_init("Pikachu", 35);
pikachu->level = 5;

Pokemon *bulbizarre = pokemon_init("Bulbizarre", 45);
bulbizarre->level = 3;

Pokemon *salameche = pokemon_init("Salameche", 39);
salameche->level = 2;

Pokemon **all_pokemons = malloc(4 * sizeof(Pokemon *));
all_pokemons[0] = pikachu;
all_pokemons[1] = bulbizarre;
all_pokemons[2] = salameche;
all_pokemons[3] = NULL;

printf("Tous les Pokemons:\n");
for (size_t i = 0; all_pokemons[i] != NULL; i++) {
printf(" - %s (niveau %d)\n", all_pokemons[i]->name, all_pokemons[i]->level);
}

Pokemon **evolved = get_all_pokemon_evolved(all_pokemons, 3, 3);

printf("\nPokemons de niveau >= 3:\n");
for (size_t i = 0; evolved[i] != NULL; i++) {
printf(" - %s (niveau %d)\n", evolved[i]->name, evolved[i]->level);
}

pokemon_free(pikachu);
pokemon_free(bulbizarre);
pokemon_free(salameche);
free(all_pokemons);
free(evolved);
}

void test_all(void) {
test_pokemon_print();
printf("\n");
test_pokemon_get_name();
printf("\n");
test_pokemon_evolved();
}

int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s [print|get_name|evolved|all]\n", argv[0]);
return 1;
} else if (strcmp(argv[1], "print") == 0) {
test_pokemon_print();
} else if (strcmp(argv[1], "get_name") == 0) {
test_pokemon_get_name();
} else if (strcmp(argv[1], "evolved") == 0) {
test_pokemon_evolved();
} else if (strcmp(argv[1], "all") == 0) {
test_all();
} else {
printf("Argument non reconnu: %s\n", argv[1]);
return 1;
}

return 0;
}

Given: pokemon_init

La fonction pokemon_init initialise une structure Pokémon avec un nom et une santé de base. Copiez-la dans votre fichier pokemon_struct.c.

feli_cite/pokemon_struct.c
#include <stdlib.h>
#include <string.h>
#include "pokemon_struct.h"

struct Pokemon *pokemon_init(const char *name, int base_health) {
struct Pokemon *pokemon = malloc(sizeof(struct Pokemon));
if (pokemon == NULL) {
return NULL;
}
pokemon->name = strdup(name);
pokemon->health = base_health;
pokemon->level = 1;
return pokemon;
}

Given: pokemon_free

La fonction pokemon_free libère complètement la mémoire alloué par la structure Pokémon. Copiez-la dans votre fichier pokemon_struct.c.

void pokemon_free(struct Pokemon *pokemon) {
if (pokemon == NULL) {
return;
}
free(pokemon->name);
free(pokemon);
}

Your Task: pokemon_print

Écrivez une fonction pokemon_print qui affiche un Pokémon formaté.

La fonction doit afficher le Pokémon au format :

Name: [name]
Health: [health]
Level: [level]
Prototype
void pokemon_print(const Pokemon *pokemon);
Test: pokemon_print
output
$ make
$ ./pokemon_struct print
=== Test: pokemon_print ===
Pokemon cree:
Name: Bulbizarre
Health: 45
Level: 1

Your Task: pokemon_get_name

Écrivez une fonction pokemon_get_name qui retourne le nom d'un Pokémon.

La fonction doit simplement retourner le nom du Pokémon.

Prototype
const char *pokemon_get_name(const Pokemon *pokemon);
Test: pokemon_get_name
output
$ make
$ ./pokemon_struct get_name
=== Test: pokemon_get_name ===
Recuperation du nom: Carapuce

Your Task: get_all_pokemon_evolved

Écrivez une fonction get_all_pokemon_evolved qui filtre les Pokémons par niveau.

La fonction doit :

  • Prendre un tableau de Pokémons et un seuil de niveau
  • Retourner un nouveau tableau contenant les Pokémons ayant un niveau >= level_threshold
  • Le tableau retourné doit être alloué dynamiquement et terminé par NULL
  • Les Pokémons dans le nouveau tableau sont les mêmes objets (pas des copies)
Prototype
Pokemon **get_all_pokemon_evolved(Pokemon **pokemons, size_t size, int level_threshold);
Test: get_all_pokemon_evolved
output
$ make
$ ./pokemon_struct evolved
=== Test: get_all_pokemon_evolved ===
Tous les Pokemons:
- Pikachu (niveau 5)
- Bulbizarre (niveau 3)
- Salameche (niveau 2)

Pokemons de niveau >= 3:
- Pikachu (niveau 5)
- Bulbizarre (niveau 3)
tip

Le fichier main.c fourni dans les "Given Files" contient les fonctions de test pour chaque fonction. Utilisez les arguments print, get_name, evolved, ou all pour lancer les tests.

Arène de Féli-Cité (Processus et Pipes)

File: pokemon_gym/tournament_winner/tournament_winner.c

Notions nécéssaires

Cet exercice nécessite les notions suivantes :

  • Gestion des processus (fork, wait, waitpid)
  • Communication inter-processus (pipes)
  • Manipulation de tableaux
  • Arithmétique des pointeurs
Imports autorisés
  • stddef.h
  • stdlib.h
  • unistd.h
  • sys/wait.h
Given Files
pokemon_gym/tournament_winner/tournament_winner.h
#ifndef TOURNAMENT_WINNER_H
#define TOURNAMENT_WINNER_H

#include <stddef.h>

int tournament_winner(const int *pokemons, size_t size);

#endif // TOURNAMENT_WINNER_H
pokemon_gym/tournament_winner/Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
TARGET = tournament_winner
SRCS = main.c tournament_winner.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
Your Task

Allez c'est l'heure du tournoi Pokémon ! C'est la bataille ultime pour déterminer le Pokémon le plus fort parmi tous les participants. Jouons ce combat !

Écrivez une fonction tournament_winner qui détermine le gagnant d'un tournoi (l'entier le plus grand) en utilisant un système de processus récursif et des pipes pour la communication.

La fonction prend en paramètres :

  • pokemons : un tableau d'entiers représentant les participants du tournoi
  • size : la taille du tableau

Algorithme :

  • Cas de base : Si size == 2, retournez l'entier le plus grand des deux
  • Cas récursif : Si size > 2 :
    1. Divisez le tableau en deux moitiés (gauche et droite)
    2. Créez deux processus enfants
    3. Chaque enfant appelle récursivement tournament_winner sur sa moitié
    4. Communiquez via des pipes : chaque enfant envoie son résultat au parent
    5. Le résultat du combat : chaque enfant affiche le vainqueur (le plus grand des deux entiers qu'il a reçus) en disant "[PID]: Pokemon [value] wins!"
    6. Le parent reçoit les deux résultats et retourne le plus grand

Exemple : Si pokemons = [5, 3, 8, 2, 9, 1, 7, 4], la fonction :

  • Crée deux enfants : l'un pour [5, 3, 8, 2], l'autre pour [9, 1, 7, 4]
  • Le premier enfant retourne 8, le second retourne 9
  • Le parent retourne 9 (le maximum)

Un combat qui ne contient qu'un seul Pokémon renvoie simplement ce Pokémon comme gagnant, ce cas arrive lorsque la taille du tableau est impaire.

note

Oui l'exercice peut être résolu sans processus, mais l'objectif est de pratiquer la gestion des processus et des pipes.

Prototype
int tournament_winner(const int *pokemons, size_t size);
Example
pokemon_gym/tournament_winner/main.c
#include <stdio.h>
#include "tournament_winner.h"

int main(void) {
// Test 1 : deux Pokemons
printf("=== Test 1: deux Pokemons ===\n");
int pokemons1[] = {5, 3};
int winner1 = tournament_winner(pokemons1, 2);
printf("Gagnant: %d\n\n", winner1);

// Test 2 : quatre Pokemons
printf("=== Test 2: quatre Pokemons ===\n");
int pokemons2[] = {5, 3, 8, 2};
int winner2 = tournament_winner(pokemons2, 4);
printf("Gagnant: %d\n\n", winner2);

// Test 3 : huit Pokemons
printf("=== Test 3: huit Pokemons ===\n");
int pokemons3[] = {5, 3, 8, 2, 9, 1, 7, 4};
int winner3 = tournament_winner(pokemons3, 8);
printf("Gagnant: %d\n", winner3);

return 0;
}
output
$ make
$ ./tournament_winner
=== Test 1: deux Pokemons ===
[1234]: Pokemon 5 wins!
Gagnant: 5

=== Test 2: quatre Pokemons ===
[1234]: Pokemon 8 wins!
[1235]: Pokemon 2 wins!
[1233]: Pokemon 8 wins!
Gagnant: 8

=== Test 3: huit Pokemons ===
[1234]: Pokemon 5 wins!
[1235]: Pokemon 8 wins!
[1236]: Pokemon 9 wins!
[1237]: Pokemon 7 wins!
[1233]: Pokemon 8 wins!
[1232]: Pokemon 9 wins!
[1231]: Pokemon 9 wins!
Gagnant: 9
note

Les PIDs et l'ordre d'affichage peuvent varier d'une exécution à l'autre.