diff --git a/exercises/higher-oder-func/higher_order_func.c b/exercises/higher-oder-func/higher_order_func.c
index 973f971f658d57d5d44dfe53582e130fed044506..6af8f04be548abc62c4df0aadc4f10fb7ffb49f0 100644
--- a/exercises/higher-oder-func/higher_order_func.c
+++ b/exercises/higher-oder-func/higher_order_func.c
@@ -3,15 +3,60 @@
 #include <string.h>
 
 void *map(void *array, size_t n, size_t size, void (*fn)(void *elem)) {
-  // TODO: implement me!
+  if (n == 0) {
+    return NULL;
+  }
+  void *result = malloc(n * size);
+  // copy original array to result byte by byte
+  memcpy((char *)result, (char *)array, n * size);
+  for (size_t i = 0; i < n; i++) {
+    // cast it to char* to make it byte addressable
+    fn((char *)result + i * size);
+  }
+  return result;
 }
 
 void *filter(void *array, size_t n, size_t size, size_t *new_size,
              bool (*pred)(void *elem)) {
-  // TODO: implement me!
+  *new_size = 0;
+  size_t count = 0;
+
+  if (n == 0) {
+    return NULL;
+  }
+
+  for (size_t i = 0; i < n; i++) {
+    void *element = (char *)array + i * size;
+    if (pred(element)) {
+      count++;
+    }
+  }
+  if (count == 0) {
+    return NULL;
+  }
+  void *result = malloc(count * size);
+  count = 0;
+  for (size_t i = 0; i < n; i++) {
+    void *element = (char *)array + i * size;
+    if (pred(element)) {
+      void *result_element = (char *)result + count * size;
+      memcpy(result_element, element, size);
+      count++;
+    }
+  }
+  *new_size = count;
+  return result;
 }
 
 void *reduce(void *array, size_t n, size_t size, void *initial_value,
              void *(*reducer)(void *acc, void *elem)) {
-  // TODO: implement me!
+  if (n == 0) {
+    return initial_value;
+  }
+  void *accumulator = initial_value;
+  for (size_t i = 0; i < n; i++) {
+    void *element = (char *)array + i * size;
+    accumulator = reducer(accumulator, element);
+  }
+  return accumulator;
 }
diff --git a/exercises/process/mysystem.c b/exercises/process/mysystem.c
index 1d8c8ea6a3c84b240d8c09afa761cbcbe9c7febc..60008ee1c33f11af77efce815046856426db3d73 100644
--- a/exercises/process/mysystem.c
+++ b/exercises/process/mysystem.c
@@ -7,13 +7,13 @@
  * a given shell command.
  */
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/wait.h>
 #include <unistd.h>
-#include <errno.h>
 
 // The max-length shell command the user can enter
 static const size_t COMMAND_MAX_LEN = 2048;
@@ -34,7 +34,17 @@ static const size_t COMMAND_MAX_LEN = 2048;
  */
 // Uncomment when implemented
 static int mysystem(char *command) {
-  // TODO: implement this function
+  pid_t pidOrZero = fork();
+  if (pidOrZero == 0) {
+    char *arguments[] = {"/bin/sh", "-c", command, NULL};
+    execvp(arguments[0], arguments);
+    // If the child gets here, there was an error
+    exit(errno);
+  }
+  // If we are the parent, wait for the child
+  int status;
+  waitpid(pidOrZero, &status, 0);
+  return WIFEXITED(status) ? WEXITSTATUS(status) : -WTERMSIG(status);
 }
 
 int main(int argc, char *argv[]) {
@@ -52,7 +62,7 @@ int main(int argc, char *argv[]) {
     command[strlen(command) - 1] = '\0';
 
     // TODO: use mysystem instead of system
-    int commandReturnCode = system(command);
+    int commandReturnCode = mysystem(command);
     printf("return code = %d\n", commandReturnCode);
   }