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 @@ + + +
1.0.2 2026-04-06 10:42 2026-04-13 10:42 submit-* (limit: 3 per week) archi-* (limit: 2 per hour) 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
+firstname.lastname with your login. .gitignore file is mandatory. Tests folder. .gitignore file:*.a
+*.lib
+*.o
+*.obj
+*.out
+
+.idea/
+*~
+*.DotSettings.user
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+ fundamentals/intro.c input to a function pointer computer.int compute(int input, int (*executor)(int));
+ 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));
+}
+ compute(3, &next) = 4
+ name.# 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!
+ void (*greet(char *name))(void);
+ int main(int argc, char *argv[])
+{
+ (void)argc;
+ (*greet(argv[1]))();
+}
+ $ ./greet Isabelle
+Hello Isabelle!
+$ ./greet Toto
+I don't know you!
+ fundamentals/calculator.c if, for, while or switch.operator and put it into your calculator.h.a and b depending on op.enum operation
+{
+ ADD,
+ SUB,
+ MUL,
+ DIV,
+ MOD,
+};
+ int calculator(int a, int b, enum operation op);
+ #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));
+}
+ calculator(4, 6, 0) = 10
+ fundamentals/toolbox.c toolbox.h header file.data itself is allocated on the heap, not its elements.NULL array is treated as an empty array, not an error.data of an array is a void * is to allow any type of element,char * to have an easy access to each byte.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
+ #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;
+};
+ f on every element of arr.acceptor is a function that takes a pointer to an element of the array.void foreach(struct array *arr, acceptor f);
+ #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);
+}
+ 0
+1
+2
+3
+ arr sorted according to f.comparator is a function that takes two pointers to elements of the array,arr must change, you MUST return arr.struct array *sort(struct array *arr, comparator f);
+ #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);
+}
+ 3
+2
+1
+0
+ arr mapped according to f.mapper is a function that takes two pointers.arr must change, you MUST return arr.arr->data, and free the previous one.output_size is the size of an element after mapping.arr with it!struct array *map(struct array *arr, size_t output_size, mapper f);
+ #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);
+}
+ 1.0
+2.0
+3.0
+4.0
+ arr filtered according to if f is true.predicate is a function that takes a pointer to an element of the array, and returns a value:arr must change, you MUST return arr.struct array *filter(struct array *arr, predicate f);
+ #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);
+}
+ 1
+3
+ arr reduced by f.reducer is a function that takes two pointers.void *reduce(struct array *arr, void *start_value, reducer f);
+ #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);
+}
+ 6
+ fundamentals/crepe_stream.c MUST use your previous functions.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;
+};
+ <name>: $<price>
+- Made out of <dough>
+- Contains <inside topping> with <outside topping> on top
+ void print_menu(struct array *arr);
+ #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);
+}
+ 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
+ struct array *sort_by_prices(struct array *arr);
+ #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);
+}
+ 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
+ struct array *names(struct array *arr);
+ #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);
+}
+ Dairy
+Raclette
+Choco
+Sugary
+ struct array *vegetarian(struct array *arr);
+ #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);
+}
+ 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
+ int total_price(struct array *arr);
+ #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);
+}
+ 26
+ proficiencies/list.c NULL is considered an empty list.typedef void (*acceptor)(void*);
+
+struct list
+{
+ void *data;
+ struct list *next;
+ acceptor print;
+ acceptor free;
+};
+ l is NULL, don't do anything and return.void push_front(struct list **l, void *data, acceptor p, acceptor f);
+ l is NULL or empty, don't do anything and return.void pop_front(struct list **l);
+ 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);
+}
+ // Nothing
+ void print_list(struct list *l);
+ 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);
+}
+ 4 -> 42 -> 18
+ l is NULL, don't do anything and return.void destroy_list(struct list **l);
+ 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);
+}
+ 4 -> 42 -> 18
+ proficiencies/visitor.c ast_node are its operands, there may be 0, 1 or 2 depending on the type.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 *);
+ MUST NOT use any if, while, for or switch!v on node.void visit(struct ast_node *node, visitor v);
+ a as the first operandb as the second operandop as the operatorBinary operators:
+(a op b)
+Unary operators:
+opa
+Number:
+a
+ void print_infix(struct ast_node *node);
+ 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);
+}
+ (6 * -7)
+ a as the first operandb as the second operandop as the operatorBinary operators:
+op a b
+Unary operators:
+op a
+Number:
+a
+ void print_prefix(struct ast_node *node);
+ 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);
+}
+ * 6 - 7
+ a as the first operandb as the second operandop as the operatorBinary operators:
+a b op
+Unary operators:
+a op
+Number:
+a
+ void print_suffix(struct ast_node *node);
+ 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);
+}
+ 6 7 - *
+ 1.0.2 ] 2026-04-07 18:00:00 visitor.c > print: specified adding a newline 1.0.1 ] 2026-04-06 19:00:00 Guidelines > Includes: added authorized includes