From a8c603e8e58109869cdbc2cb1c344183c7cdff3b Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Wed, 13 Apr 2016 12:07:56 -0400 Subject: [PATCH] ex18 --- lcthw-remnants-2/.gitignore | 23 +------- lcthw-remnants-2/ex18.c | 111 ++++++++++++++++++++++++++++++++++++ lcthw-remnants-2/runtests | 8 +++ 3 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 lcthw-remnants-2/ex18.c diff --git a/lcthw-remnants-2/.gitignore b/lcthw-remnants-2/.gitignore index 976020d..6f17809 100644 --- a/lcthw-remnants-2/.gitignore +++ b/lcthw-remnants-2/.gitignore @@ -1,20 +1,3 @@ -ex1 -ex3 -ex4 -ex5 -ex6 -ex7 -ex8 -ex9 -ex9-ec -ex10 -ex11 -ex12 -ex13 -ex14 -ex15 -ex16 -ex17 -db.dat -ex17-ec -ex17-ec2 +*.dat +ex* +!ex*.c diff --git a/lcthw-remnants-2/ex18.c b/lcthw-remnants-2/ex18.c new file mode 100644 index 0000000..4de105a --- /dev/null +++ b/lcthw-remnants-2/ex18.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include + +/** Our old friend die from ex17. */ +void die(const char *message) +{ + if(errno) { + perror(message); + } else { + printf("ERROR: %s\n", message); + } + + exit(1); +} + +// a typedef creates a fake type, in this +// case for a function pointer +typedef int (*compare_cb)(int a, int b); + +/** + * A classic bubble sort function that uses the + * compare_cb to do the sorting. + */ +int *bubble_sort(int *numbers, int count, compare_cb cmp) +{ + int temp = 0; + int i = 0; + int j = 0; + int *target = malloc(count * sizeof(int)); + + if(!target) die("Memory error."); + + memcpy(target, numbers, count * sizeof(int)); + + for(i = 0; i < count; i++) { + for(j = 0; j < count - 1; j++) { + if(cmp(target[j], target[j+1]) > 0) { + temp = target[j+1]; + target[j+1] = target[j]; + target[j] = temp; + } + } + } + + return target; +} + +int sorted_order(int a, int b) +{ + return a - b; +} + +int reverse_order(int a, int b) +{ + return b - a; +} + +int strange_order(int a, int b) +{ + if(a == 0 || b == 0) { + return 0; + } else { + return a % b; + } +} + +/** + * Used to test that we are sorting things correctly + * by doing the sort and printing it out. + */ +void test_sorting(int *numbers, int count, compare_cb cmp) +{ + int i = 0; + int *sorted = bubble_sort(numbers, count, cmp); + + if(!sorted) die("Failed to sort as requested."); + + for(i = 0; i < count; i++) { + printf("%d ", sorted[i]); + } + printf("\n"); + + free(sorted); +} + +int main(int argc, char *argv[]) +{ + if(argc < 2) die("USAGE: ex18 4 3 1 5 6"); + + int count = argc - 1; + int i = 0; + char **inputs = argv + 1; + + int *numbers = malloc(count * sizeof(int)); + if(!numbers) die("Memory error."); + + for(i = 0; i < count; i++) { + numbers[i] = atoi(inputs[i]); + } + + test_sorting(numbers, count, sorted_order); + test_sorting(numbers, count, reverse_order); + test_sorting(numbers, count, strange_order); + + free(numbers); + + return 0; +} + diff --git a/lcthw-remnants-2/runtests b/lcthw-remnants-2/runtests index c8f6e28..0640266 100755 --- a/lcthw-remnants-2/runtests +++ b/lcthw-remnants-2/runtests @@ -18,6 +18,14 @@ test_ex17-ec() { echo "OK" } +test_ex18() { + local output=$(./ex18 4 1 7 3 2 0 8) + [[ "${output}" =~ '0 1 2 3 4 7 8' ]] + [[ "${output}" =~ '8 7 4 3 2 1 0' ]] + [[ "${output}" =~ '3 4 2 7 1 0 8' ]] + echo "OK" +} + main() { for ex in $(./list-exercises) ; do func_name="test_${ex}"