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 }