04-median.c (1167B)
1 /* Calculates the median of $@ */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 #include <zahl.h> 7 8 int 9 main(int argc, char *argv[]) 10 { 11 struct zahl *values; 12 z_t med, medmod; 13 jmp_buf env; 14 char *buf, *argv0; 15 int i, j; 16 17 argv0 = *argv++, argc--; 18 19 if (!argc) { 20 fprintf(stderr, 21 "%s: cannot calculate median of the empty bag\n", 22 argv0); 23 return 1; 24 } 25 26 values = calloc(argc, sizeof(*values)); 27 if (!values) 28 return perror(argv0), 1; 29 30 if (setjmp(env)) 31 return zperror(argv0), 1; 32 33 zsetup(env); 34 zinit(med); 35 zinit(medmod); 36 37 /* Since `values` where allocated with 38 * `calloc` it is already cleared and 39 * `zinit` is not necessary. */ 40 41 for (i = 0; i < argc; i++) 42 zsets(&values[i], argv[i]); 43 44 qsort(values, argc, sizeof(*values), 45 (int (*)(const void *, const void *))zcmp); 46 i = argc / 2; 47 j = i - !(argc & 1); 48 zadd(med, &values[i], &values[j]); 49 zsetu(medmod, 2); 50 zdivmod(med, medmod, med, medmod); 51 52 printf("%s%s\n", buf = zstr(med, NULL, 0), 53 (const char *[]){"", ".5"}[zodd(medmod)]); 54 free(buf); 55 56 zfree(medmod); 57 zfree(med); 58 for (i = 0; i < argc; i++) 59 zfree(&values[i]); 60 free(values); 61 zunsetup(); 62 return 0; 63 }