diff --git a/README.md b/README.md index e896818..97d4842 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ CSCI3431-Assignment 1 ===================== - - > Goal: A simple C program to calculate the mean and median of input numbers. + > Description: A simple C program to calculate the mean, median, and sorted list of input numbers. ## Intro @@ -31,7 +30,10 @@ Be sure to compile with `gcc -Wall` ## Usage ```bash -$./sort 1 4 9 2 3 1 7 4 8 -./sort: Sorted output is: -1 1 2 3 4 4 7 8 9 +$./mm 1 4 9 2 3 1 7 4 8 +./a.out: The median is 4.000000 +./a.out: The mean is 4.333333 +./a.out: Sorted output is: +1 1 2 3 4 4 7 8 9 +./a.out: FIN. ``` diff --git a/mm.c b/mm.c new file mode 100644 index 0000000..a83d23a --- /dev/null +++ b/mm.c @@ -0,0 +1,120 @@ +#include +#include + +#define debug 0 + +// Comparison function for qsort() +int numcmp (const void *a, const void *b) { + int x = *((int*) a); + int y = *((int*) b); + if (x > y) return 1; + if (x < y) return -1; + return 0; +} + +/*/ + * Takes a pointer to an + * array, the length of the array, and the size + * of the array elements (double or int), + * and returns a double, the average of the + * elements. + */ +double mean(const void *a, int length, int size){ + double sum = 0.0; + switch(size){ // What type of array do we have? + // Add up the elements + case sizeof(int): + for (int i = 0; i < length; i++) + sum += *((int*)(a + i*size)); + break; + case sizeof(double): + for (int i = 0; i < length; i++) + sum += *((double*) (a + i*size)); + break; + default: // Exit with error on incorrect input + exit(-1); + } + return (double) sum / length; // Return the average +} + +/*/ Takes a pointer to a sorted array of ints and the + * length of the array and returns a double,the median + * value, or the average of the two median values + */ +double median(const int *a, int length){ + if (length % 2 == 0) + // Find the average of the two median numbers + return (double) (*((int*) (a + length/2) - 1) + *((int*) (a + length/2))) / 2; + else + // Return the median number + return *((int*) (a + (length+1)/2 - 1)); +} + +int main(int argc, char *argv[]) { + + int i, length, *pt; + + // Check for proper usage + if (argc < 2) { + fprintf(stderr, "%s: Aborting, not enough arguments.\n", argv[0]); + return (-1); + } + + // Determine amount of numbers from argc + length = argc - 1; +#if debug + fprintf(stderr, "%s: DEBUG: %d numbers were passed.\n", argv[0], length); +#endif + + // Allocate memory for array of number (and error check) + if ((pt = malloc(length * sizeof(int))) == NULL) { + fprintf(stderr, "%s: Could not allocate memory.\n", argv[0]); + } + + // Read numbers into array + for (i = 0; i < length; i++) { + pt[i] = (int) strtol(argv[i+1], NULL, 10); + } + + // Sort numbers + qsort(pt, length, sizeof(int), numcmp); + + int rc = fork(); + double m; + + // Exit with error if fork() failed + if (rc < 0) + exit(-1); + // the child calculates the median + else if (rc == 0){ + // Calculate the median + m = median(pt, length); + + // Print the median: + fprintf(stdout, "%s: The median is %f \n", argv[0], m); + + // the child has terminated normally + exit(0); + } + //--------- Parent code -----------// + + // wait for the child to finish + // Don't bother recording the status + wait(NULL); + + // Calculate the mean + m = mean(pt, length, sizeof(int)); + + // Print the mean: + fprintf(stdout, "%s: The mean is %f \n", argv[0], m); + + // Print out sorted numbers + fprintf(stdout, "%s: Sorted output is: \n", argv[0]); + for (i=0; i