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); }