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