From 8b23c4146ed5b6060cee38142010441c422e039b Mon Sep 17 00:00:00 2001
From: Mactavish <maczhanchao@yahoo.com>
Date: Thu, 4 May 2023 15:56:06 +0200
Subject: [PATCH] update README for higher-order functions

---
 exercises/higher-oder-func/README.md | 74 +++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/exercises/higher-oder-func/README.md b/exercises/higher-oder-func/README.md
index ea7405e..369d0f3 100644
--- a/exercises/higher-oder-func/README.md
+++ b/exercises/higher-oder-func/README.md
@@ -12,9 +12,81 @@ You will implement the following functions:
 * `filter`: filter a given array with a predicate function to a new array. 
 * `reduce`: "reduce" the array with a given initial accumulator and a reducer function to a final value.
 
+### Map
+
+`map` takes a pointer to the target array, the length of the target array, the size of each element in the array and a pointer to a transformer function as parameters.
+
+It should return a pointer to a newly allocated array, in which every element will be transformed using the transformer function.
+
+For example:
+
+```c
+int double_it(void *elem) {
+    *((int *)elem) *= 2;
+}
+
+int arr[] = {1, 2, 3, 4, 5};
+int *new_arr = map(arr, 5, sizeof int, double_it);
+
+// the new_arr will be {2, 4, 6, 8, 9} and the old array arr is not affected
+```
+
+### Filter
+
+`filter` takes a pointer to the target array, the length of the target array, the size of each element in the array, a pointer to a `size_t` variable that stores the size of the filtered array and a pointer to a predicate function as parameters.
+
+It should return a pointer to a newly allocated array which contains only those elements that fulfill the requirements posed by the predicate function.
+
+For example:
+
+```c
+bool is_even(void *elem) {
+    return  *((int *)elem) % 2 == 0;
+}
+
+int arr[] = {1, 2, 3, 4, 5};
+size_t new_size = 0;
+int *new_arr = filter(arr, 5, sizeof int, &new_size, is_even);
+
+// the new_arr will be {2, 4} and the old array arr is not affected, new_size will be 2
+```
+
+The parameter `new_size` is necessary, otherwise there is no way of knowing the size of the filtered array since we can only deduct the size of an array only from a pointer.
+
+### Reduce
+
+`reduce` takes a pointer to the target array, the length of the target array, the size of each element in the array, a pointer to the initial accumulator variable and a pointer to a reducer function as parameters.
+
+It should return a pointer to that initial accumulator.
+
+The purpose of `reduce` is to apply a given function to a sequence of elements from left to right and reduces it to a single value using a so called accumulator.
+
+For example:
+
+```c
+void* sum_int(void *acc, void *elem) {
+  int *acc_ptr = (int *)acc;
+  int *elem_ptr = (int *)elem;
+  *acc_ptr += *elem_ptr;
+  return acc_ptr;
+}
+
+int arr[] = {1, 2, 3, 4, 5};
+int acc = 0;
+int *result = reduce(arr, 5, sizeof int, &acc, sum_int);
+
+// acc will be 1+2+3+4+5 = 15 and result actually points to acc
+```
+
 ## Tips
 
-TBD
+We want the `map`, `filter` and `reduce` functions to be as generic as they can, so as you can see, the return values and the parameters of the given functions are all using `void *` pointers.
+
+For `map` and `filter`, you will have to use `malloc` or `calloc` to allocate a new array. If the given `length` is 0, then just return a `NULL`.
+
+In order to use the transformer/predicate/reducer function, you will have to calculate the offset of the element with the give `size`. Because you don't have information of the `type` of the array elements, so you have to calculate the offset of the elements manually.
+
+Because we only have `void *` pointer to the elements, we can cast it into `char *` and then calculate the offset per bytes.
 
 ## Testing
 
-- 
GitLab