From 6c6929bcb15099c4d70a31f15215e414448fd55f Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 9 Apr 2026 15:08:25 +0200 Subject: [PATCH] push --- .gitignore | 9 + Functional Market.html | 3474 +++++++++++++++++ README | 26 + assets.tar.gz | Bin 0 -> 1572 bytes functional_market/Fundamentals/calculator.c | 9 + functional_market/Fundamentals/calculator.h | 17 + functional_market/Fundamentals/crepe_stream.c | 32 + functional_market/Fundamentals/crepe_stream.h | 42 + functional_market/Fundamentals/intro.h | 7 + functional_market/Fundamentals/test | Bin 0 -> 18712 bytes functional_market/Fundamentals/toolbox.c | 37 + functional_market/Fundamentals/toolbox.h | 25 + functional_market/Proficiencies/list.c | 24 + functional_market/Proficiencies/list.h | 19 + functional_market/Proficiencies/visitor.c | 22 + functional_market/Proficiencies/visitor.h | 36 + 16 files changed, 3779 insertions(+) create mode 100644 .gitignore create mode 100644 Functional Market.html create mode 100644 README create mode 100644 assets.tar.gz create mode 100644 functional_market/Fundamentals/calculator.c create mode 100644 functional_market/Fundamentals/calculator.h create mode 100644 functional_market/Fundamentals/crepe_stream.c create mode 100644 functional_market/Fundamentals/crepe_stream.h create mode 100644 functional_market/Fundamentals/intro.h create mode 100755 functional_market/Fundamentals/test create mode 100644 functional_market/Fundamentals/toolbox.c create mode 100644 functional_market/Fundamentals/toolbox.h create mode 100644 functional_market/Proficiencies/list.c create mode 100644 functional_market/Proficiencies/list.h create mode 100644 functional_market/Proficiencies/visitor.c create mode 100644 functional_market/Proficiencies/visitor.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c4c8d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.a +*.lib +*.o +*.obj +*.out + +.idea/ +*~ +*.DotSettings.user diff --git a/Functional Market.html b/Functional Market.html new file mode 100644 index 0000000..36c7d30 --- /dev/null +++ b/Functional Market.html @@ -0,0 +1,3474 @@ + + +Functional Market

Functional Market 1.0.2

function pointers


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-104-p-03-2030-firstname.lastname
+├── functional_market
+│   ├── Fundamentals
+│   │   ├── calculator.c
+│   │   ├── calculator.h
+│   │   ├── crepe_stream.c
+│   │   ├── crepe_stream.h
+│   │   ├── intro.c
+│   │   ├── intro.h
+│   │   ├── toolbox.c
+│   │   └── toolbox.h
+│   └── Proficiencies
+│       ├── list.c
+│       ├── list.h
+│       ├── visitor.c
+│       └── visitor.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


In this practical, you will learn about how to use Function pointers.
You will need to have a thorough understanding of arrays, and trees.
You will also be using notions from previous practicals such as linked lists.
Here's a reminder: if you have trouble understanding something, just ask your assistants by making a ticker on discord!

Authorized includes
#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+

Lore
The market will open soon! However, it's not ready, the villager need your help!

Lore
A villager needs your help at the crepe stand, get your tools and help them!



fundamentals/intro.c


Lore
Before being able to help anyone, you need to learn how to use your tools.

To start off, you have to implement a function that returns the result of passing its input to a function pointer computer.

Prototype(s)
int compute(int input, int (*executor)(int));
+

Code example(s)
int next(int n)
+{
+    return n + 1;
+}
+
+#include <stdio.h>
+int main(void)
+{
+    int n = 3;
+    printf("compute(%d, &next) = %d\n", n, compute(n, &next));
+}
+

Output
compute(3, &next) = 4
+

Now, you have to return a function pointer depending on the name.
When this function pointer is executed, it needs to print one of the following lines depending on the name given.

Output
# name = "Isabelle":
+Hello Isabelle!
+
+# name = "Tom Nook":
+Hi Tom Nook.
+
+# name = "Blathers":
+Good night Blathers!
+
+# name = "Mr. Resetti":
+How are you doing Mr. Resetti?
+
+# Anything else (including NULL):
+I don't know you!
+

Warning(s)
Don't forget to add a newline at the end!

Hint(s)
That means you will need to create multiple auxiliary functions. Their names do not matter, they only need to follow the right signature.

Prototype(s)
void (*greet(char *name))(void);
+

Information
Understanding the signature of this function is part of the exercise.

Code example(s)
int main(int argc, char *argv[])
+{
+    (void)argc;
+    (*greet(argv[1]))();
+}
+

Output
$ ./greet Isabelle
+Hello Isabelle!
+$ ./greet Toto
+I don't know you!
+



fundamentals/calculator.c


Lore
You shouldn't forget your trusty calculator!

Danger(s)
For this function, you MUST NOT use any if, for, while or switch.
Instead, you MUST use a lookup table, that store multiple functions.
You SHOULD use a typedef for functions that take two integers and return an integer.
If you do, you MUST name it operator and put it into your calculator.h.

For this function, you should return the result of the operation between a and b depending on op.

calculator.h
enum operation
+{
+    ADD,
+    SUB,
+    MUL,
+    DIV,
+    MOD,
+};
+

Prototype(s)
int calculator(int a, int b, enum operation op);
+

Hint(s)
You do not need to care about invalid operations such as division by zero, and they will not be tested.

Code example(s)
#include <stdio.h>
+int main(void)
+{
+    int a = 4;
+    int b = 6;
+    enum operation op = ADD;
+    printf("calculator(%d, %d, %d) = %d\n", a, b, op, calculator(a, b, op));
+}
+

Output
calculator(4, 6, 0) = 10
+



fundamentals/toolbox.c


Lore
One last step before you go to the market: put all your tools in the toolbox.

Information
Here are structures as well as typedefs you will be using for the following exercises.
They are already present in the toolbox.h header file.

Each typedef is explained in its associated function.
There will also be examples provided to better understand how they work.

In an array, only data itself is allocated on the heap, not its elements.
A NULL array is treated as an empty array, not an error.

The reason the data of an array is a void * is to allow any type of element,
such as integers, strings and other structs.
To modify its content, it is usually cast as a char * to have an easy access to each byte.
Here is a simple example on how to access an element of the array:

Code example(s)
char *data = arr->data;
+char *second_element = data + arr->elem_size;
+char *fifth_element = data + 4 * arr->elem_size; // Don't forget array indexes are zero-based
+

toolbox.h
#include <stddef.h>
+
+typedef int (*comparator)(void *, void *);
+typedef void (*mapper)(void *, void *);
+typedef int (*predicate)(void *);
+typedef void *(*reducer)(void *, void *);
+typedef void (*acceptor)(void *);
+
+struct array
+{
+    void *data;
+    size_t len;
+    size_t elem_size;
+};
+

This function applies f on every element of arr.

Hint(s)
An acceptor is a function that takes a pointer to an element of the array.

Prototype(s)
void foreach(struct array *arr, acceptor f);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+void print_int(int *n)
+{
+    printf("%d\n", *n);
+}
+
+int main(void)
+{
+    struct array arr = {
+        .data = calloc(4, sizeof(int)),
+        .len = 4,
+        .elem_size = sizeof(int),
+    };
+
+    int *data = arr.data;
+    data[0] = 0;
+    data[1] = 1;
+    data[2] = 2;
+    data[3] = 3;
+
+    foreach(&arr, (acceptor)&print_int);
+
+    free(arr.data);
+}
+

Output
0
+1
+2
+3
+

This function returns arr sorted according to f.

Hint(s)
A comparator is a function that takes two pointers to elements of the array,
and returns a value :

- equal to 0 if they are equal
- less than 0 if the first is less than the second
- greater than 0 if the first is greater than the second

Danger(s)
Be careful, only the content of arr must change, you MUST return arr.

Prototype(s)
struct array *sort(struct array *arr, comparator f);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int reverse(int *a, int *b)
+{
+    return *b - *a;
+}
+
+void print_int(int *n)
+{
+    printf("%d\n", *n);
+}
+
+int main(void)
+{
+    struct array arr = {
+        .data = calloc(4, sizeof(int)),
+        .len = 4,
+        .elem_size = sizeof(int),
+    };
+
+    int *data = arr.data;
+    data[0] = 0;
+    data[1] = 1;
+    data[2] = 2;
+    data[3] = 3;
+
+    foreach(sort(&arr, (comparator)&reverse), (acceptor)&print_int);
+
+    free(arr.data);
+}
+

Output
3
+2
+1
+0
+

This function returns arr mapped according to f.

Hint(s)
A mapper is a function that takes two pointers.

The first is the destination, and the second is the source.

Information
To map an array means creating a new array by applying a function on each of the elements.
The types of the elements in the array before and after mapping CAN be different.

Danger(s)
Be careful, only the content of arr must change, you MUST return arr.
You will need to reallocate a new arr->data, and free the previous one.

Hint(s)
output_size is the size of an element after mapping.
Don't forget to update arr with it!

Prototype(s)
struct array *map(struct array *arr, size_t output_size, mapper f);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+void next(double *res, int *n)
+{
+    *res = *n + 1;
+}
+
+void print_double(double *n)
+{
+    printf("%.1lf\n", *n);
+}
+
+int main(void)
+{
+    struct array arr = {
+        .data = calloc(4, sizeof(int)),
+        .len = 4,
+        .elem_size = sizeof(int),
+    };
+
+    int *data = arr.data;
+    data[0] = 0;
+    data[1] = 1;
+    data[2] = 2;
+    data[3] = 3;
+
+    foreach(map(&arr, sizeof(double), (mapper)&next), (acceptor)&print_double);
+
+    free(arr.data);
+}
+

Output
1.0
+2.0
+3.0
+4.0
+

This function returns arr filtered according to if f is true.

Hint(s)
A predicate is a function that takes a pointer to an element of the array, and returns a value:
- equal to 0 if the predicate is false
- different from 0 if the predicate is true

Danger(s)
Be careful, only the content of arr must change, you MUST return arr.

Prototype(s)
struct array *filter(struct array *arr, predicate f);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int odd(int *n)
+{
+    return *n % 2;
+}
+
+void print_int(int *n)
+{
+    printf("%d\n", *n);
+}
+
+int main(void)
+{
+    struct array arr = {
+        .data = calloc(4, sizeof(int)),
+        .len = 4,
+        .elem_size = sizeof(int),
+    };
+
+    int *data = arr.data;
+    data[0] = 0;
+    data[1] = 1;
+    data[2] = 2;
+    data[3] = 3;
+
+    foreach(filter(&arr, (predicate)&odd), (acceptor)&print_int);
+
+    free(arr.data);
+}
+

Output
1
+3
+

This function returns the result of arr reduced by f.

Hint(s)
A reducer is a function that takes two pointers.

The first is the destination, and the second is the source.

It also returns the destination.

Prototype(s)
void *reduce(struct array *arr, void *start_value, reducer f);
+

Code example(s)
#include <stdio.h>
+#include <stdlib.h>
+
+int *add(int *res, int *n)
+{
+    *res += *n;
+    return res;
+}
+
+void print_int(int *n)
+{
+    printf("%d\n", *n);
+}
+
+int main(void)
+{
+    struct array arr = {
+        .data = calloc(4, sizeof(int)),
+        .len = 4,
+        .elem_size = sizeof(int),
+    };
+
+    int *data = arr.data;
+    data[0] = 0;
+    data[1] = 1;
+    data[2] = 2;
+    data[3] = 3;
+
+    int res = 0;
+    reduce(&arr, &res, (reducer)&add);
+    printf("%d\n", res);
+
+    free(arr.data);
+}
+

Output
6
+



fundamentals/crepe_stream.c


Lore
Someone needs you at the crepe stand, they need you to organize the menu.

Danger(s)
For the next part, you MUST use your previous functions.
The moulinette will use its own, but if you haven't done them,
you won't be able to test on your computer.

It is up to you to use the correct one. It will be tested.

crepe_stream.h
enum dough
+{
+    WHEAT,
+    BUCKWHEAT,
+};
+
+enum topping
+{
+    NOTHING,
+
+    // Sweet
+    SUGAR,
+    CHOCOLATE,
+    WHIPPED_CREAM,
+
+    // Savory
+    CHEESE,
+    MEAT,
+    EGG,
+};
+
+struct crepe
+{
+    char *name;
+    enum dough dough;
+    enum topping inside;
+    enum topping outside;
+    int price;
+};
+

Hint(s)
You will need to make multiple auxiliary functions, but the the main functions only need a few lines.

This function prints all crepes in the array according to the following format,
with all enumerations in lowercase and with any character '_' replaced by a space :

Output
<name>: $<price>
+- Made out of <dough>
+- Contains <inside topping> with <outside topping> on top
+

Prototype(s)
void print_menu(struct array *arr);
+

Code example(s)
#include <stdlib.h>
+
+int main(void)
+{
+    struct array arr = {
+        .elem_size = sizeof(struct crepe),
+        .len = 4,
+        .data = calloc(4, sizeof(struct crepe)),
+    };
+    struct crepe *data = arr.data;
+    data[0] = (struct crepe){
+        .name = "Dairy",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = EGG,
+        .price = 5,
+    };
+    data[1] = (struct crepe){
+        .name = "Raclette",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = MEAT,
+        .price = 8,
+    };
+    data[2] = (struct crepe){
+        .name = "Choco",
+        .dough = WHEAT,
+        .inside = CHOCOLATE,
+        .outside = WHIPPED_CREAM,
+        .price = 6,
+    };
+    data[3] = (struct crepe){
+        .name = "Sugary",
+        .dough = WHEAT,
+        .inside = SUGAR,
+        .outside = NOTHING,
+        .price = 7,
+    };
+
+    print_menu(&arr);
+
+    free(arr.data);
+}
+

Output
Dairy: $5
+- Made out of buckwheat
+- Contains cheese with egg on top
+Raclette: $8
+- Made out of buckwheat
+- Contains cheese with meat on top
+Choco: $6
+- Made out of wheat
+- Contains chocolate with whipped cream on top
+Sugary: $7
+- Made out of wheat
+- Contains sugar with nothing on top
+

This function returns the array of crepes sorted by prices

Even prices should come first in ascending order, then odd prices in descending order.

Prototype(s)
struct array *sort_by_prices(struct array *arr);
+

Code example(s)
#include <stdlib.h>
+
+int main(void)
+{
+    struct array arr = {
+        .elem_size = sizeof(struct crepe),
+        .len = 4,
+        .data = calloc(4, sizeof(struct crepe)),
+    };
+    struct crepe *data = arr.data;
+    data[0] = (struct crepe){
+        .name = "Dairy",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = EGG,
+        .price = 5,
+    };
+    data[1] = (struct crepe){
+        .name = "Raclette",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = MEAT,
+        .price = 8,
+    };
+    data[2] = (struct crepe){
+        .name = "Choco",
+        .dough = WHEAT,
+        .inside = CHOCOLATE,
+        .outside = WHIPPED_CREAM,
+        .price = 6,
+    };
+    data[3] = (struct crepe){
+        .name = "Sugary",
+        .dough = WHEAT,
+        .inside = SUGAR,
+        .outside = NOTHING,
+        .price = 7,
+    };
+
+    print_menu(sort_by_prices(&arr));
+
+    free(arr.data);
+}
+

Output
Choco: $6
+- Made out of wheat
+- Contains chocolate with whipped cream on top
+Raclette: $8
+- Made out of buckwheat
+- Contains cheese with meat on top
+Sugary: $7
+- Made out of wheat
+- Contains sugar with nothing on top
+Dairy: $5
+- Made out of buckwheat
+- Contains cheese with egg on top
+

This function returns the names of the crepes in the array of crepes

Prototype(s)
struct array *names(struct array *arr);
+

Code example(s)
#include <stdlib.h>
+
+void print_string(char **str)
+{
+    puts(*str);
+}
+
+int main(void)
+{
+    struct array arr = {
+        .elem_size = sizeof(struct crepe),
+        .len = 4,
+        .data = calloc(4, sizeof(struct crepe)),
+    };
+    struct crepe *data = arr.data;
+    data[0] = (struct crepe){
+        .name = "Dairy",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = EGG,
+        .price = 5,
+    };
+    data[1] = (struct crepe){
+        .name = "Raclette",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = MEAT,
+        .price = 8,
+    };
+    data[2] = (struct crepe){
+        .name = "Choco",
+        .dough = WHEAT,
+        .inside = CHOCOLATE,
+        .outside = WHIPPED_CREAM,
+        .price = 6,
+    };
+    data[3] = (struct crepe){
+        .name = "Sugary",
+        .dough = WHEAT,
+        .inside = SUGAR,
+        .outside = NOTHING,
+        .price = 7,
+    };
+
+    foreach(names(&arr), (acceptor)&print_string);
+
+    free(arr.data);
+}
+

Output
Dairy
+Raclette
+Choco
+Sugary
+

This function returns the array of crepes containing only crepes that do not have any meat.

Prototype(s)
struct array *vegetarian(struct array *arr);
+

Code example(s)
#include <stdlib.h>
+
+int main(void)
+{
+    struct array arr = {
+        .elem_size = sizeof(struct crepe),
+        .len = 4,
+        .data = calloc(4, sizeof(struct crepe)),
+    };
+    struct crepe *data = arr.data;
+    data[0] = (struct crepe){
+        .name = "Dairy",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = EGG,
+        .price = 5,
+    };
+    data[1] = (struct crepe){
+        .name = "Raclette",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = MEAT,
+        .price = 8,
+    };
+    data[2] = (struct crepe){
+        .name = "Choco",
+        .dough = WHEAT,
+        .inside = CHOCOLATE,
+        .outside = WHIPPED_CREAM,
+        .price = 6,
+    };
+    data[3] = (struct crepe){
+        .name = "Sugary",
+        .dough = WHEAT,
+        .inside = SUGAR,
+        .outside = NOTHING,
+        .price = 7,
+    };
+
+    print_menu(vegetarian(&arr));
+
+    free(arr.data);
+}
+

Output
Dairy: $5
+- Made out of buckwheat
+- Contains cheese with egg on top
+Choco: $6
+- Made out of wheat
+- Contains chocolate with whipped cream on top
+Sugary: $7
+- Made out of wheat
+- Contains sugar with nothing on top
+

This function returns the total price of the crepes in the array.

Prototype(s)
int total_price(struct array *arr);
+

Code example(s)
#include <stdlib.h>
+
+int main(void)
+{
+    struct array arr = {
+        .elem_size = sizeof(struct crepe),
+        .len = 4,
+        .data = calloc(4, sizeof(struct crepe)),
+    };
+    struct crepe *data = arr.data;
+    data[0] = (struct crepe){
+        .name = "Dairy",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = EGG,
+        .price = 5,
+    };
+    data[1] = (struct crepe){
+        .name = "Raclette",
+        .dough = BUCKWHEAT,
+        .inside = CHEESE,
+        .outside = MEAT,
+        .price = 8,
+    };
+    data[2] = (struct crepe){
+        .name = "Choco",
+        .dough = WHEAT,
+        .inside = CHOCOLATE,
+        .outside = WHIPPED_CREAM,
+        .price = 6,
+    };
+    data[3] = (struct crepe){
+        .name = "Sugary",
+        .dough = WHEAT,
+        .inside = SUGAR,
+        .outside = NOTHING,
+        .price = 7,
+    };
+
+    printf("%d\n", total_price(&arr));
+
+    free(arr.data);
+}
+

Output
26
+


Information
In this part, you will be manipulating simply linked generic lists and binary trees.



proficiencies/list.c


Information
NULL is considered an empty list.

list.h
typedef void (*acceptor)(void*);
+
+struct list
+{
+    void *data;
+    struct list *next;
+    acceptor print;
+    acceptor free;
+};
+

This function adds a new element at the front of the linked list.

If l is NULL, don't do anything and return.

Prototype(s)
void push_front(struct list **l, void *data, acceptor p, acceptor f);
+

This function removes the element at the front of the linked list.
There shouldn't be any memory leaks.

If l is NULL or empty, don't do anything and return.

Prototype(s)
void pop_front(struct list **l);
+

Code example(s)
void do_nothing(void *n)
+{
+    (void)n;
+}
+
+void print_long(void *n)
+{
+    printf("%ld", (long)n);
+}
+
+void print_int(int *n)
+{
+    printf("%d", *n);
+}
+
+int main(void)
+{
+    struct list *l = NULL;
+    push_front(&l, (void *)18, &print_long, &do_nothing);
+    int *on_heap = calloc(1, sizeof(int));
+    *on_heap = 42;
+    push_front(&l, on_heap, (acceptor)&print_int, &free);
+    int on_stack = 4;
+    push_front(&l, &on_stack, (acceptor)&print_int, &do_nothing);
+    // print_list(l);
+    pop_front(&l);
+    pop_front(&l);
+    pop_front(&l);
+}
+

Output
// Nothing
+

This function prints every element, separated by " -> ".
The output must always be terminated by a newline.

Prototype(s)
void print_list(struct list *l);
+

Code example(s)
void do_nothing(void *n)
+{
+    (void)n;
+}
+
+void print_long(void *n)
+{
+    printf("%ld", (long)n);
+}
+
+void print_int(int *n)
+{
+    printf("%d", *n);
+}
+
+int main(void)
+{
+    struct list *l = NULL;
+    push_front(&l, (void *)18, &print_long, &do_nothing);
+    int *on_heap = calloc(1, sizeof(int));
+    *on_heap = 42;
+    push_front(&l, on_heap, (acceptor)&print_int, &free);
+    int on_stack = 4;
+    push_front(&l, &on_stack, (acceptor)&print_int, &do_nothing);
+    print_list(l);
+    pop_front(&l);
+    pop_front(&l);
+    pop_front(&l);
+}
+

Output
4 -> 42 -> 18
+

This function empties the list.
There shouldn't be any memory leaks, and the list should be able to be reused.

If l is NULL, don't do anything and return.

Prototype(s)
void destroy_list(struct list **l);
+

Code example(s)
void do_nothing(void *n)
+{
+    (void)n;
+}
+
+void print_long(void *n)
+{
+    printf("%ld", (long)n);
+}
+
+void print_int(int *n)
+{
+    printf("%d", *n);
+}
+
+int main(void)
+{
+    struct list *l = NULL;
+    push_front(&l, (void *)18, &print_long, &do_nothing);
+    int *on_heap = calloc(1, sizeof(int));
+    *on_heap = 42;
+    push_front(&l, on_heap, (acceptor)&print_int, &free);
+    int on_stack = 4;
+    push_front(&l, &on_stack, (acceptor)&print_int, &do_nothing);
+    print_list(l);
+    destroy_list(&l);
+}
+

Output
4 -> 42 -> 18
+



proficiencies/visitor.c


Information
In this part, you will be interacting with ASTs of arithmetical expressions.
You won't have to do any parsing or memory management.
You will only implement the Visitor design pattern to be able to print the AST.

The children of an ast_node are its operands, there may be 0, 1 or 2 depending on the type.

visitor.h
enum node_type
+{
+    // 0 operand
+    NUM,
+
+    // 1 operand
+    POS,
+    NEG,
+
+    // 2 operands
+    ADD,
+    SUB,
+    MUL,
+    DIV,
+    MOD,
+};
+
+struct ast_node
+{
+    int value;
+    enum node_type type;
+    struct ast_node *children;
+};
+
+typedef void(*visitor)(struct ast_node *);
+

Danger(s)
You MUST NOT use any if, while, for or switch!

This function should just call the visitor v on node.

Prototype(s)
void visit(struct ast_node *node, visitor v);
+

This function should print the ast using infix notation.
Don't forget to add a newline at the end!

Here is the format to follow, given:
- a as the first operand
- b as the second operand
- op as the operator

Output
Binary operators:
+(a op b)
+Unary operators:
+opa
+Number:
+a
+

Prototype(s)
void print_infix(struct ast_node *node);
+

Code example(s)
int main(void)
+{
+    struct ast_node node = {
+        .type = MUL,
+        .children =
+            (struct ast_node[]){
+                {
+                    .type = NUM,
+                    .value = 6,
+                },
+                {
+                    .type = NEG,
+                    .children =
+                        (struct ast_node[]){
+                            {
+                                .type = NUM,
+                                .value = 7,
+                            },
+                        },
+                },
+            },
+    };
+
+    print_infix(&node);
+}
+

Output
(6 * -7)
+

This function should print the ast using prefix notation.
Don't forget to add a newline at the end!

Here is the format to follow, given:
- a as the first operand
- b as the second operand
- op as the operator

Output
Binary operators:
+op a b
+Unary operators:
+op a
+Number:
+a
+

Prototype(s)
void print_prefix(struct ast_node *node);
+

Code example(s)
int main(void)
+{
+    struct ast_node node = {
+        .type = MUL,
+        .children =
+            (struct ast_node[]){
+                {
+                    .type = NUM,
+                    .value = 6,
+                },
+                {
+                    .type = NEG,
+                    .children =
+                        (struct ast_node[]){
+                            {
+                                .type = NUM,
+                                .value = 7,
+                            },
+                        },
+                },
+            },
+    };
+
+    print_prefix(&node);
+}
+

Output
* 6 - 7
+

This function should print the ast using suffix notation.
Don't forget to add a newline at the end!

Here is the format to follow, given:
- a as the first operand
- b as the second operand
- op as the operator

Output
Binary operators:
+a b op
+Unary operators:
+a op
+Number:
+a
+

Prototype(s)
void print_suffix(struct ast_node *node);
+

Code example(s)
int main(void)
+{
+    struct ast_node node = {
+        .type = MUL,
+        .children =
+            (struct ast_node[]){
+                {
+                    .type = NUM,
+                    .value = 6,
+                },
+                {
+                    .type = NEG,
+                    .children =
+                        (struct ast_node[]){
+                            {
+                                .type = NUM,
+                                .value = 7,
+                            },
+                        },
+                },
+            },
+    };
+
+    print_suffix(&node);
+}
+

Output
6 7 - *
+



[ 1.0.2 ] 2026-04-07 18:00:00
Proficiencies
  • visitor.c > print: specified adding a newline

[ 1.0.1 ] 2026-04-06 19:00:00
Guidelines
  • Guidelines > Includes: added authorized includes


This page and all subpages are for internal use at EPITA only.
The use of this document must abide by the following rules:
  • You are seeing it from the EPITA’ Gitlab pages.
  • This page and all subpages are strictly personal and must not be passed onto someone else.
  • Non-compliance with these rules can lead to severe sanctions.
Copyright © 2026-2027 - EPITA
\ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..00e3b1e --- /dev/null +++ b/README @@ -0,0 +1,26 @@ +𝑚 𝑣𝐴 +𝛼 +𝑣𝐴 = 6 m/s 𝛼 ° 𝑚 = 200 g 𝑔 = 10 m/s +2 +. +𝑓 = 0,2 N +𝑚 +𝑟 𝜃 +𝑓 = 𝜇𝑅 𝑅 +𝑣𝐴 +𝑚 = 0,1 kg 𝑔 = 10 m/s +2 +𝑟 = 1,6 m 𝑣𝐶 = 𝑣𝐴 = 3 m/s 𝜃 ° 𝐵𝐶 = 2 m +A B +C +α +ℎ +ℎ = 𝑟(1 − cos 𝜃) +𝑣𝐵 𝑟 𝑔 𝑣𝐴 𝜃 +𝜇 𝑟 𝜃 𝐵𝐶 +ℎ +A +O +B C +𝜃 +𝑟 diff --git a/assets.tar.gz b/assets.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3322abf3213ebed2accd234082787f9952c13419 GIT binary patch literal 1572 zcmV+<2HW``iwFoHtJ7%$|8#9|Uv7C~adBri0PR|9Z}K)2?&tgpkA8s&aVfVCohDJr zS~OZJF7Ng&3W))4A&C-)wVS%%K06M?PEw#3vi6;i1c~kAV<+)>{P@_FCBkTFJ03hc znbe51o6Yb_BzdjXI^2Dj-{~|i&Oq%f2MK(vd!)&;|EH)GT~R9*nv;Kr{^q~a{{SmW z1({H=FYwkQ&Rww-a^?K(*{QmV;ry;+8E^>|*wh0$tIvNeH zM!#vd$~j3Q8*(|yIkF8aFd_KS$0jMRtbS4y{NzGf6WJIPRl`}kx~F5uD-|~mGJ#qK z>{`0qsfHOvb*;ND+^5G(x*jx;(n}y65Rn z%HIkg!U|0t>z85LM}I*L0}I+h8d`9z(fdo~IbjH>zT@Gdm_;sS5Wga@AkB*!LZy}B%IR!;o_Ya87PNSo1nj;k*SW7LgR zR`ukfOfVRt$jb5nqjnLuZUU=V|Qk}lIs>g~`D)_@g}K^1{&_xidV-b`j!?B;GZWH;A? zZ&A*O=uj-B*5gq}jRQS259VbcnkRQjgyDNELFVK5pK((DS4;E1dPn+yKK>t3yTXp@ z7v4l@B3}>bRf!Z|a>)ftcn}Ak4en>dA>mER2QZ)`8f6Kt`Z0Yuj!C`Yk>5qVj(%FM z{+@0eN8t`M`Ya*#yXJo$bfHE@2-MeaW`GCrzgbW6zfN7ofAi&k*GFgciTv_PbL??5<|LU!vsmmLOusb&eZ zMsEX`kc@4l+nLI=Q`jM1&RWjY3Fiq?Y-5ceLXfE=@^4|hNCy7Z@t=Ho&v_sFKVtoV z(Ma;EFvFTBL{UP)fE zmyi2b-!BoIx7gZCf{rtIm?-VF!y(&VCY3gl2b3Kj|9?9PIOP8qwdDLy5JB$$=I#I7 zR!`y8ad>g`^3(lXh{L&Q-;k5=XXpQ`_qB1*|LZl$|NrCo&)|MK9&v%6ZTeNb|MC!l zPeco%Mr4@aGx`66=PZzcpiO>$b%T8LzTN-B@!wi4wf|4I1f~Dy=>OjalYzMTALp>3 zt?iglqh|o3slHkTHO2vKlf`joTp+eC6g`Y4Ec|-k=i>yZgQpekJ}N#DC*-_+M)_T50^ROZ?Aw{kNOx3$Ft; zF(~V7_qt*NV$_>pvO)$(R2P2a_pB z{-WgmQ}p~HdOA*CIzu085NCsr(Pq%@j8W*FiM$0_Kr$}I960b-+QM_}9Ud`js#WHi zE6LS@6e&`qNRc8%iWDhQ Wq)3q>MT(TKCjSE8903ymPyhgh?kh$B literal 0 HcmV?d00001 diff --git a/functional_market/Fundamentals/calculator.c b/functional_market/Fundamentals/calculator.c new file mode 100644 index 0000000..da76ea2 --- /dev/null +++ b/functional_market/Fundamentals/calculator.c @@ -0,0 +1,9 @@ +#include "calculator.h" + +int calculator(int a, int b, enum operation op) +{ + (void)a; + (void)b; + (void)op; + return 0; +} diff --git a/functional_market/Fundamentals/calculator.h b/functional_market/Fundamentals/calculator.h new file mode 100644 index 0000000..af762d7 --- /dev/null +++ b/functional_market/Fundamentals/calculator.h @@ -0,0 +1,17 @@ +#ifndef CALCULATOR_H +#define CALCULATOR_H + +typedef int (*operator)(int, int); + +enum operation +{ + ADD, + SUB, + MUL, + DIV, + MOD, +}; + +int calculator(int a, int b, enum operation op); + +#endif /* ! CALCULATOR_H */ diff --git a/functional_market/Fundamentals/crepe_stream.c b/functional_market/Fundamentals/crepe_stream.c new file mode 100644 index 0000000..f5a8863 --- /dev/null +++ b/functional_market/Fundamentals/crepe_stream.c @@ -0,0 +1,32 @@ +#include "crepe_stream.h" + +#include "toolbox.h" + +struct array *sort_by_prices(struct array *arr) +{ + (void)arr; + return NULL; +} + +struct array *names(struct array *arr) +{ + (void)arr; + return NULL; +} + +struct array *vegetarian(struct array *arr) +{ + (void)arr; + return NULL; +} + +int total_price(struct array *arr) +{ + (void)arr; + return 0; +} + +void print_menu(struct array *arr) +{ + (void)arr; +} diff --git a/functional_market/Fundamentals/crepe_stream.h b/functional_market/Fundamentals/crepe_stream.h new file mode 100644 index 0000000..6f8d97d --- /dev/null +++ b/functional_market/Fundamentals/crepe_stream.h @@ -0,0 +1,42 @@ +#ifndef CREPE_STREAM_H +#define CREPE_STREAM_H + +#include "toolbox.h" + +enum dough +{ + WHEAT, + BUCKWHEAT, +}; + +enum topping +{ + NOTHING, + + // Sweet + SUGAR, + CHOCOLATE, + WHIPPED_CREAM, + + // Savory + CHEESE, + MEAT, + EGG, +}; + +struct crepe +{ + char *name; + enum dough dough; + enum topping inside; + enum topping outside; + int price; +}; + +struct array *sort_by_prices(struct array *arr); +struct array *names(struct array *arr); +struct array *vegetarian(struct array *arr); +int total_price(struct array *arr); +void print_menu(struct array *arr); + +#endif /* ! CREPE_STREAM_H */ diff --git a/functional_market/Fundamentals/intro.h b/functional_market/Fundamentals/intro.h new file mode 100644 index 0000000..7c1f874 --- /dev/null +++ b/functional_market/Fundamentals/intro.h @@ -0,0 +1,7 @@ +#ifndef INTRO_H +#define INTRO_H + +int compute(int input, int (*executor)(int)); +void (*greet(char *name))(void); + +#endif /* ! INTRO_H */ diff --git a/functional_market/Fundamentals/test b/functional_market/Fundamentals/test new file mode 100755 index 0000000000000000000000000000000000000000..2b9a5f8ce80ce72ea2351a139e4fa8223027f3ad GIT binary patch literal 18712 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 m-#@tS!`BXEy)?GZ&0g_2=W + +typedef int (*comparator)(void *, void *); +typedef void (*mapper)(void *, void *); +typedef int (*predicate)(void *); +typedef void *(*reducer)(void *, void *); +typedef void (*acceptor)(void *); + +struct array +{ + void *data; + size_t len; + size_t elem_size; +}; + +struct array *sort(struct array *arr, comparator f); +struct array *map(struct array *arr, size_t output_size, mapper f); +struct array *filter(struct array *arr, predicate f); +void *reduce(struct array *arr, void *start_value, reducer f); +void foreach(struct array *arr, acceptor f); + +#endif /* ! TOOLBOX_H */ diff --git a/functional_market/Proficiencies/list.c b/functional_market/Proficiencies/list.c new file mode 100644 index 0000000..74c5c73 --- /dev/null +++ b/functional_market/Proficiencies/list.c @@ -0,0 +1,24 @@ +#include "list.h" + +void push_front(struct list **l, void *data, acceptor p, acceptor f) +{ + (void)l; + (void)data; + (void)p; + (void)f; +} + +void pop_front(struct list **l) +{ + (void)l; +} + +void print_list(struct list *l) +{ + (void)l; +} + +void destroy_list(struct list **l) +{ + (void)l; +} diff --git a/functional_market/Proficiencies/list.h b/functional_market/Proficiencies/list.h new file mode 100644 index 0000000..a77707b --- /dev/null +++ b/functional_market/Proficiencies/list.h @@ -0,0 +1,19 @@ +#ifndef LIST_H +#define LIST_H + +typedef void (*acceptor)(void*); + +struct list +{ + void *data; + struct list *next; + acceptor print; + acceptor free; +}; + +void push_front(struct list **l, void *data, acceptor p, acceptor f); +void pop_front(struct list **l); +void print_list(struct list *l); +void destroy_list(struct list **l); + +#endif /* ! LIST_H */ diff --git a/functional_market/Proficiencies/visitor.c b/functional_market/Proficiencies/visitor.c new file mode 100644 index 0000000..fee1492 --- /dev/null +++ b/functional_market/Proficiencies/visitor.c @@ -0,0 +1,22 @@ +#include "visitor.h" + +void visit(struct ast_node *node, visitor v) +{ + (void)node; + (void)v; +} + +void print_prefix(struct ast_node *node) +{ + (void)node; +} + +void print_infix(struct ast_node *node) +{ + (void)node; +} + +void print_suffix(struct ast_node *node) +{ + (void)node; +} diff --git a/functional_market/Proficiencies/visitor.h b/functional_market/Proficiencies/visitor.h new file mode 100644 index 0000000..e6c4e36 --- /dev/null +++ b/functional_market/Proficiencies/visitor.h @@ -0,0 +1,36 @@ +#ifndef VISITOR_H +#define VISITOR_H + +enum node_type +{ + // 0 operand + NUM, + + // 1 operand + POS, + NEG, + + // 2 operands + ADD, + SUB, + MUL, + DIV, + MOD, +}; + +struct ast_node +{ + int value; + enum node_type type; + struct ast_node *children; +}; + +typedef void(*visitor)(struct ast_node *); + +void visit(struct ast_node *node, visitor v); + +void print_prefix(struct ast_node *node); +void print_infix(struct ast_node *node); +void print_suffix(struct ast_node *node); + +#endif /* ! VISITOR_H */