04-median.c - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
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 } |