diff --git a/Recap Island.html b/Recap Island.html new file mode 100644 index 0000000..56fff6f --- /dev/null +++ b/Recap Island.html @@ -0,0 +1,2015 @@ + + +Recap Island

Recap Island 1.0.2

dynamic memory allocation, structures, enum, union, Makefile,


If there is a conflict between the subject and the skeleton or moulinette, the subject is always right.
However, please report any inconsistencies to your assistant.

Submissions

Repository structure
At the end, your git repo must follow this architecture:
epita-prepa-computer-science-prog-103-p-06-2030-firstname.lastname
+├── recap_island
+│   ├── fundamentals
+│   │   ├── Makefile
+│   │   ├── main.c
+│   │   ├── quotes.c
+│   │   ├── village.h
+│   │   ├── village_manager.c
+│   │   └── villagers.c
+│   └── proficiencies
+│       ├── strange_list.c
+│       └── strange_list.h
+├── .gitignore
+└── README
+

Do not forget to check the following requirements before submitting your work:
  • You shall obviously replace firstname.lastname with your login.
  • The .gitignore file is mandatory.
  • Remove all personal tests from your code, except those from the Tests folder.
  • The given prototypes must be strictly respected.
  • The code MUST compile! Otherwise you will not receive a grade.

.gitignore example
Here is an example of a .gitignore file:
*.a
+*.lib
+*.o
+*.obj
+*.out
+
+.idea/
+*~
+*.DotSettings.user
+

This needs to be setup before the first submission!

Introduction


After years managing his villagers and home loans, Tom Nook has decided that it was time for big changes. He needs your help to manage the island. Your mission is quite simple: create a tool that will make everyone's life easier.

Warning(s)
Throughout this practical, you will only be able to use both <stdlib.h> and <stddef.h> libraries, unless clearly specified.

Information
For this practical, you need to download the Given Files. This is an archive file. To use it, you need to untar it using the following command:

Shell example(s)
tar -xvf assets.tar.gz
+

To start, you will need to implement a good base to keep track of all the villagers on the island.



fundamentals/village.h


In order to organize everything properly, Tom Nook wants you to classify each villager by their daily activities. To keep everything simple, and to avoid Isabelle drowning in paperwork, Tom Nook has given you a list of predefined job categories.
You will need to implement an enum works which contains the following four activities:

  • WORKER
  • SELLER
  • MUSICIAN
  • UNEMPLOYED

Now that this is done, note that every island has a collection of villagers. You will now need to implement the struct villager which will hold the following attributes for every villager:

  • the char *name that will hold the name of the villager
  • the unsigned int age to keep track of its age
  • the enum works job to know which activity it does
  • the char *favorite_quote to keep its favorite quote in mind



fundamentals/quotes.c


Tom Nook loves to collect each favorite quotes of the island villagers. In this section, you will need to process the villager's favorite quotes.

Lore
Tom Nook wants to know what each of the villagers likes to say the most.

This function returns the favorite quote of the villager of name name.

village is an array of struct villager.
population is the length of the array.
name is the name of the villager whose quote you will return.

If the villager doesn't exist, the village is NULL or population equals 0, you will return NULL.

Prototype(s)
char *get_quote(const struct villager *village, unsigned int population, char *name);
+

Hint(s)
You should use the strcmp function from the string.h header.

Code example(s)
#include <stdio.h>
+
+int main(void)
+{
+    struct villager village[2] = {
+        {
+            .name = "Tom Nook",
+            .age = 99,
+            .job = SELLER,
+            .favorite_quote = "It's 42 bells",
+        },
+        {
+            .name = "Marie",
+            .age = 23,
+            .job = WORKER,
+            .favorite_quote = "It's so expensive!",
+        },
+    };
+    unsigned int population = 2;
+
+    char *quote = get_quote(village, population, "Tom Nook");
+    printf("- %s\n", quote);
+
+    quote = get_quote(village, population, "Marie");
+    printf("- %s\n", quote);
+
+    quote = get_quote(village, population, "TC");
+    printf("%p\n", quote);
+}
+

Output
- It's 42 bells
+- It's so expensive!
+(nil)
+

Lore
Tom Nook would like to have a file listing all the favorite quotes of the villagers.

You will need to write all the quotes of the village inside the file named filename, with a newline after each quote.

filename is the file you will write to.
village is an array of struct villager.
population is the length of the array.

This function returns:
-1 if the village or the filename is NULL.
-2 if an error occurs while opening or writing in the file.
0 otherwise.

If the file already exists, overwrite it.

Do not forget to close the file after you are done with it!

Warning(s)
In order to manipulate your file, you should use the stdio.h library.

Prototype(s)
int list_quotes(const char *filename, const struct villager *village, unsigned int population);
+

Code example(s)
#include <stdio.h>
+
+int main(void)
+{
+    struct villager village[2] = {
+        {
+            .name = "Tom Nook",
+            .age = 99,
+            .job = SELLER,
+            .favorite_quote = "It's 42 bells",
+        },
+        {
+            .name = "Marie",
+            .age = 23,
+            .job = WORKER,
+            .favorite_quote = "It's so expensive!",
+        },
+    };
+    unsigned int population = 2;
+
+    int err = list_quotes("/tmp/list_quotes", village, population);
+    printf("%d\n", err);
+
+    err = list_quotes(NULL, village, population);
+    printf("%d\n", err);
+}
+

Output
0
+-1
+$ cat /tmp/list_quotes
+It's 42 bells
+It's so expensive!
+

Lore
Finally, Tom Nook has a special request. He would like you to extract the second longest quote in a file.

This function returns the second longest quote of the list of quotes in the file filename.

filename is the file you will read.

If filename is NULL, if an error occurs while opening or reading the file or the file only has one line, you should return NULL.
Else, return a newly allocated string containing the second longest quote.

Do not forget to close the file after you are done with it!

Warning(s)
In order to manipulate your file, you should use the stdio.h library.

Prototype(s)
char *second_longest_quote(const char *filename);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    // $ cat /tmp/list_quotes
+    // It's 42 bells
+    // It's so expensive!
+    char *quote = second_longest_quote("/tmp/list_quotes");
+    printf("%s\n", quote);
+    free(quote);
+
+    quote = second_longest_quote("/");
+    printf("%p\n", quote);
+
+    free(quote);
+}
+

Output
It's 42 bells
+(nil)
+



fundamentals/villagers.c


Once everything is properly done, Tom Nook tells you that he would like your help to organize everything. It is really important for him to keep everything sorted.

Lore
Tom Nook insists on knowing who the oldest villager is on the island at all time. Whether it is for a better construction planning, outside of their nap time, or to "honor their wisdom", he still wants to know.

This function returns the name of the oldest villager in the village.

village is an array of struct villager.
population is the length of the array.

If village is NULL or population equals 0, you will return NULL.

Prototype(s)
char *oldest_villager(const struct villager *village, unsigned int population);
+

Code example(s)
#include <stdio.h>
+
+int main(void)
+{
+    struct villager village[2] = {
+        {
+            .name = "Tom Nook",
+            .age = 99,
+            .job = SELLER,
+            .favorite_quote = "It's 42 bells",
+        },
+        {
+            .name = "Marie",
+            .age = 23,
+            .job = WORKER,
+            .favorite_quote = "It's so expensive!",
+        },
+    };
+    unsigned int population = 2;
+
+    char *oldest = oldest_villager(village, population);
+    printf("Hi %s!\n", oldest);
+
+    oldest = oldest_villager(NULL, 0);
+    printf("%p\n", oldest);
+}
+

Output
Hi Tom Nook!
+(nil)
+

Lore
Once again, the love for statistics of Tom Nook has made him ask you for the average age of the island villagers.

This function returns the average age of the villagers in the village.

village is an array of struct villager.
population is the length of the array.

If the village is NULL or if the population equals 0, you will return -1.

Prototype(s)
float average_village_age(const struct villager *village, unsigned int population);
+

Code example(s)
#include <stdio.h>
+
+int main(void)
+{
+    struct villager village[2] = {
+        {
+            .name = "Tom Nook",
+            .age = 99,
+            .job = SELLER,
+            .favorite_quote = "It's 42 bells",
+        },
+        {
+            .name = "Marie",
+            .age = 23,
+            .job = WORKER,
+            .favorite_quote = "It's so expensive!",
+        },
+    };
+    unsigned int population = 2;
+
+    float avg = average_village_age(village, population);
+    printf("Avg: %.2f\n", avg);
+
+    avg = average_village_age(village, 0);
+    printf("Avg: %.2f\n", avg);
+}
+

Output
Avg: 61.00
+Avg: -1.00
+

Lore
Tom nook would like to have the villagers organized by their professions, to make it easier to know who does what.

This function sorts the villagers by their job in the same order as the enum works.

village is an array of struct villager.
population is the length of the array.

If village is NULL, you will not do anything.

The sorting algorithm you will use is up to you, its complexity will not be tested.

Prototype(s)
void sort_village(struct villager *village, unsigned int population);
+

Code example(s)
#include <stdio.h>
+
+int main(void)
+{
+    struct villager village[2] = {
+        {
+            .name = "Tom Nook",
+            .age = 99,
+            .job = SELLER,
+            .favorite_quote = "It's 42 bells",
+        },
+        {
+            .name = "Marie",
+            .age = 23,
+            .job = WORKER,
+            .favorite_quote = "It's so expensive!",
+        },
+    };
+    unsigned int population = 2;
+
+    sort_village(village, population);
+
+    for (unsigned int i = 0; i < population; i++)
+    {
+        printf("I'm %s (%d)\n", village[i].name, village[i].age);
+    }
+}
+

Output
I'm Marie (23)
+I'm Tom Nook (99)
+



fundamentals/village_manager.c


Now that you have implemented the basics of the village, you will need to implement some functions to grow your village.

Lore
A new villager just arrived on your island. You will need to register them in your village!

This function adds a villager at the end of an array representing the village.

village is a pointer to an array of struct villager.
population is a pointer to the length of the array.
villager is the new element to be added at the end of village.

You will need to allocate enough space in village to add villager.
Your code will return :
-2 if memory allocation fails.
-1 if either the village or the population is NULL.
0 otherwise.

Do not forget to update your population!

Prototype(s)
int add_villager(struct villager **village, unsigned int *population, struct villager villager);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    struct villager *village = NULL;
+    unsigned int population = 0;
+
+    struct villager tom_nook = {
+        .name = "Tom Nook",
+        .age = 99,
+        .job = SELLER,
+        .favorite_quote = "It's 42 bells",
+    };
+
+    int err = add_villager(&village, &population, tom_nook);
+    printf("%d\n", err);
+
+    struct villager marie = {
+        .name = "Marie",
+        .age = 23,
+        .job = WORKER,
+        .favorite_quote = "It's so expensive!",
+    };
+
+    err = add_villager(&village, &population, marie);
+    printf("%d\n", err);
+
+    err = add_villager(&village, NULL, marie);
+    printf("%d\n", err);
+
+    for (unsigned int i = 0; i < population; i++)
+    {
+        printf("I'm %s (%d)\n", village[i].name, village[i].age);
+    }
+
+    free(village);
+}
+

Output
0
+0
+-1
+I'm Tom Nook (99)
+I'm Marie (23)
+

Lore
It seems some villagers want to move out, you should help them!

This function removes a villager from an array representing the village.

village is a pointer to an array of struct villager.
population is a pointer to the length of the array.
name is the name of the villager to be removed from village.

You will need to reallocate the correct amount of memory after removal.
Your code will return :
-2 if memory allocation fails.
-1 if either the village or the population is NULL, or no corresponding villager is found.
0 otherwise.

If a villager with the correct name is found, you must move all the villagers following it by one space to the left.
Do not forget to update the population!

Prototype(s)
int remove_villager(struct villager **village, unsigned int *population, char *name);
+

Hint(s)
You should use the strcmp function from the string.h header.

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    struct villager *village = NULL;
+    unsigned int population = 0;
+
+    struct villager tom_nook = {
+        .name = "Tom Nook",
+        .age = 99,
+        .job = SELLER,
+        .favorite_quote = "It's 42 bells",
+    };
+
+    add_villager(&village, &population, tom_nook);
+
+    struct villager marie = {
+        .name = "Marie",
+        .age = 23,
+        .job = WORKER,
+        .favorite_quote = "It's so expensive!",
+    };
+
+    add_villager(&village, &population, marie);
+
+    int err = remove_villager(&village, &population, "Tom Nook");
+    printf("%d\n", err);
+
+    err = remove_villager(&village, &population, "Tom Nook");
+    printf("%d\n", err);
+
+    err = remove_villager(NULL, &population, "Marie");
+    printf("%d\n", err);
+
+    for (unsigned int i = 0; i < population; i++)
+    {
+        printf("I'm %s (%d)\n", village[i].name, village[i].age);
+    }
+
+    free(village);
+}
+

Output
0
+-1
+-1
+I'm Marie (23)
+

Lore
Tom Nook decided that the island needs a full administrative refresh, so he asked you to get rid of the previous register.

This function frees the memory allocated to the array reprenting the village.

village is a pointer to an array of struct villager.
population is a pointer to the length of the array.

You shall do nothing if either the village or the population is NULL.

Do not forget to update the population and set the content of village to NULL.

Prototype(s)
void clear_village(struct villager **village, unsigned int *population);
+

Code example(s)
#include <stdio.h>
+
+int main(void)
+{
+    struct villager *village = NULL;
+    unsigned int population = 0;
+
+    struct villager tom_nook = {
+        .name = "Tom Nook",
+        .age = 99,
+        .job = SELLER,
+        .favorite_quote = "It's 42 bells",
+    };
+
+    add_villager(&village, &population, tom_nook);
+
+    struct villager marie = {
+        .name = "Marie",
+        .age = 23,
+        .job = WORKER,
+        .favorite_quote = "It's so expensive!",
+    };
+
+    add_villager(&village, &population, marie);
+
+    clear_village(&village, &population);
+
+    for (unsigned int i = 0; i < population; i++)
+    {
+        printf("I'm %s (%d)\n", village[i].name, village[i].age);
+    }
+
+    printf("%p\n", village);
+    printf("%u\n", population);
+}
+

Output
(nil)
+0
+



fundamentals/Makefile


You have to write a Makefile to compile all of your files. You can use the given main.c file to test your code.
Your Makefile will contain the target all, compiling your files and the main.c, as well as a clean that removes everything your makefile generated.
Your executable should be named "main" and should be compiled using the following flags: -Wall -Wextra -Werror


Just when you thought you had everything figured out, you receive a message from Tom Nook. He just discovered a list of really unusual data. Apparently, entries are not of tha same type, and he needs your help to take care of them!



proficiencies/strange_list.h


To help you navigate through this strange list, Tom Nook asks you to implement some elements.
First of all, you will need to implement an enum data_type, containing the following elements:

  • FLOAT_TYPE
  • INT_TYPE
  • STRING_TYPE

You will then need to implement the union value containing the float f, the int i and the char *s.
Finally, you will need to implement the struct data containing the enum data_type type and the union value value.



proficiencies/strange_list.c


You will now handle all the special operations Tom Nook needs.

Lore
Tom Nook would like to print the values in his strange list.

For this function, you will need to print all the values contained in list. If list is NULL, you will do nothing.

Prototype(s)
void print_strange_list(const struct data *list, unsigned int size);
+

You will need to use the following format.

Output
INT    : {i}
+FLOAT  : {f}
+STRING : {s}
+

Warning(s)
For this function, you have the right to use the following headers: stdio.h header for the printf function, and the string.h header in case you would like to use a padding function.
Even though these headers are included in your strange_list.c you are not allowed to use any of their functions anywhere else in this file, except if you are told otherwise.

Information
You will need to implement the other functions before being able to test this one. However, you don't need to to pass its tests on the moulinette.

Lore
In case he needs to, Tom Nook would like you to code a function to append elements to this strange list.

In this function, you should appen elements to list.
You will need to make sure enough space is allocated in the list to append element at the end. Be careful, you will need to update the size!
You will return:
-2 if the allocation fails
-1 if either list or size is NULL
0 otherwise.

Prototype(s)
int append_strange_list(struct data **list, unsigned int *size, struct data element);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    struct data *list = NULL;
+    unsigned int size = 0;
+
+    struct data elt1 = { .type = INT_TYPE, .value = { .i = 42 } };
+    struct data elt2 = { .type = STRING_TYPE, .value = { .s = "QUOI" } };
+
+    int err = append_strange_list(&list, &size, elt1);
+    printf("%d\n", err);
+
+    err = append_strange_list(&list, &size, elt2);
+    printf("%d\n", err);
+
+    err = append_strange_list(&list, NULL, elt1);
+    printf("%d\n", err);
+
+    print_strange_list(list, size);
+
+    free(list);
+}
+

Output
0
+0
+-1
+INT    : 42
+STRING : QUOI
+

You will need to remove the element at the position index of the list. You will then need to resize list to the right size and update size.
This function returns:
-2 if memory allocation fails.
-1 if list is NULL or size is NULL or if index is out of range.
0 otherwise.

Prototype(s)
int remove_at_strange_list(struct data **list, unsigned int *size, int index);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    struct data *list = NULL;
+    unsigned int size = 0;
+
+    struct data elt1 = { .type = INT_TYPE, .value = { .i = 42 } };
+    struct data elt2 = { .type = STRING_TYPE, .value = { .s = "FEUR" } };
+
+    append_strange_list(&list, &size, elt1);
+    append_strange_list(&list, &size, elt2);
+    append_strange_list(&list, &size, elt2);
+
+    int err = remove_at_strange_list(&list, &size, 1);
+    printf("%d\n", err);
+
+    err = remove_at_strange_list(&list, &size, 42);
+    printf("%d\n", err);
+
+    print_strange_list(list, size);
+
+    free(list);
+}
+

Output
0
+-1
+INT    : 42
+STRING : FEUR
+

This function behaves just like print_strange_list, but inside of a file. If the file already contain something, you should override it.
It returns:
-2 in case there is any error while opening the file or writing inside the file.
-1 if filename or list is NULL.
0 if everything went well.

Prototype(s)
int list_strange_list(const char *filename, const struct data *list, unsigned int size);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    struct data *list = NULL;
+    unsigned int size = 0;
+
+    struct data elt1 = { .type = INT_TYPE, .value = { .i = 42 } };
+    struct data elt2 = { .type = STRING_TYPE, .value = { .s = "welcome2u" } };
+
+    append_strange_list(&list, &size, elt1);
+
+    append_strange_list(&list, &size, elt2);
+
+    int err = list_strange_list("/tmp/list", list, size);
+    printf("%d\n", err);
+
+    err = list_strange_list("/", list, size);
+    printf("%d\n", err);
+
+    free(list);
+}
+

Output
0
+-2
+$ cat /tmp/list
+INT    : 42
+STRING : welcome2u
+


[ 1.0.2 ] 2026-02-23 21:00:00
Fundamentals
  • villager.c > oldest_villager: village instead of villager
Proficiencies
  • strange_list.c > given_mains: wrong type for size

[ 1.0.1 ] 2026-02-23 16:00:00
Fundamentals
  • quotes.c > second_longest_quote: mention of name instead of filename


This page and all subpages are for internal use at EPITA only.
The use of this document must abide by the following rules:
Copyright © 2026-2027 - EPITA
\ No newline at end of file diff --git a/assets.tar.gz b/assets.tar.gz new file mode 100644 index 0000000..c29f4a5 Binary files /dev/null and b/assets.tar.gz differ