For a lark, I thought I'd do this one in ANSI C. I decided to break the rules by adding additional arguments to the required functions to make the test more friendly to C:
func_callback.h
PHP Code:
/* Programming Challenge 20
* Due to the difficulty of implementing generalized arguments in C,
* only an integer compatible version of the functions exist. */
#ifndef FUNC_CALLBACK_H
#define FUNC_CALLBACK_H 1
#define TRUE 1
#define FALSE 0
typedef unsigned char boolean;
typedef boolean (*TestFunc) (int);
typedef int (*CombineFunc) (int, int);
/* remove entries which do not match criteria specified by user supplied
* function 'f' and return an array containing only those matches. */
int *filter (const TestFunc f, int *arr, const int sz, int *result_sz);
/* reduce array 'arr' by applying user supplied function 'f' into one result,
* starting with value 'start' */
int reduce (const CombineFunc f, int *arr, const int sz, const int start);
#endif /* FUNC_CALLBACK_H */
func_callback.c
PHP Code:
#include "func_callback.h"
#include <stdlib.h>
int *
filter (const TestFunc f, int *arr, const int sz, int *result_sz)
{
int i;
int x = 0;
int *tmp = malloc (sizeof (int) * sz);
if (!tmp) return NULL;
for (i = 0; i < sz; i++)
if (f (arr[i]))
tmp[x++] = arr[i++];
tmp = realloc (tmp, sizeof (int) * x);
*result_sz = !tmp ? 0 : x;
return tmp;
}
int
reduce (const CombineFunc f, int *arr, const int sz, const int start)
{
int i;
int result = start;
for (i = 0; i < sz; i++)
result = f (result, arr[i]);
return result;
}
The following is the code used to test the above:
func_cb_main.c
PHP Code:
#include "func_callback.h"
#include <stdio.h>
#include <stdlib.h>
/* "user" defined functions for use with filter and reduce */
static boolean
isOdd (const int num)
{
return (num % 2);
}
static boolean
isEven (const int num)
{
return !(num % 2) && num != 0;
}
static int
add (const int x, const int y)
{
return x + y;
}
static int
sub (const int x, const int y)
{
return x - y;
}
int
main (void)
{
int test_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *result_arr;
int result = 0;
int i;
int sz;
result_arr = filter (isEven, test_arr, sizeof(test_arr) / sizeof (int), &sz);
printf ("Printing even numbers from array:\n");
for (i = 0; i < sz; i++)
printf ("%d ", result_arr[i]);
printf ("\n");
free(result_arr);
result_arr = filter (isOdd, test_arr, sizeof(test_arr) / sizeof (int), &sz);
printf ("Printing odd numbers from array:\n");
for (i = 0; i < sz; i++)
printf ("%d ", result_arr[i]);
printf ("\n");
free(result_arr);
result_arr = NULL;
result = reduce (add, test_arr, 10, 0);
printf ("reduce (add) returned a result of %d\n", result);
result = reduce (sub, test_arr, 10, 20);
printf ("reduce (sub) returned a result of %d\n", result);
return 0;
}
Use whatever compile flags you want. I tested with:
Code:
gcc -Wall -Wextra -ansi -pedantic func_callback.c func_cb_main.c && ./a.out
Results:
Code:
Printing even numbers from array:
2 4 6 8
Printing odd numbers from array:
1 3 5 7 9
reduce (add) returned a result of 45
reduce (sub) returned a result of -25
Bookmarks