advent2021

Advent of Code 2021 Solutions
git clone git://bsandro.tech/advent2021
Log | Files | Refs | README | LICENSE

puzzle.c (1533B)


      1 #define _DEFAULT_SOURCE
      2 
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <errno.h>
      6 #include <string.h>
      7 #include <strings.h>
      8 #include <stdbool.h>
      9 #include <assert.h>
     10 #include <time.h>
     11 #include <math.h>
     12 
     13 #include "util.h"
     14 
     15 #define STR_LEN 16384
     16 
     17 static int compare(const void *l, const void *r) {
     18 	long long d = *(long long *)l - *(long long *)r;
     19 	if (d > 0) return 1;
     20 	if (d < 0) return -1;
     21 	return 0;
     22 }
     23 
     24 void puzzle(const char *filename, size_t *result1, size_t *result2) {
     25 	FILE *infile = fopen(filename, "r");
     26 	if (infile == NULL) {
     27 		fprintf(stderr, "fopen() error: %s\n", strerror(errno));
     28 		return;
     29 	}
     30 
     31 	char buf[STR_LEN] = {0};
     32 	unsigned int line_num = 0;
     33 
     34 	struct array_t numbers = { .data = NULL };
     35 	array_init(&numbers, sizeof(long long), 100);
     36 
     37 	while (fgets(buf, STR_LEN, infile) != NULL) {
     38 		parse_numbers_array_ll(&numbers, buf, ",");
     39 		++line_num;
     40 		bzero(buf, STR_LEN);
     41 	}
     42 
     43 	qsort(numbers.data, numbers.count, numbers.elem_size, compare);
     44 
     45 	// median average
     46 	size_t index = numbers.count / 2;
     47 	long long *data = (long long *)numbers.data;
     48 	long long mid = data[index];
     49 	for (size_t i = 0; i < numbers.count; ++i) {
     50 		*result1 += llabs(data[i] - mid);
     51 	}
     52 
     53 	// mean average
     54 	double sum = 0;
     55 	for (size_t i = 0; i < numbers.count; ++i) {
     56 		sum += data[i];
     57 	}
     58 	long long avg = floor((sum + 1) / (double)numbers.count);
     59 	for (size_t i = 0; i < numbers.count; ++i) {
     60 		long long dist = llabs(data[i] - avg);
     61 		*result2 += dist * (1 + dist) / 2;
     62 	}
     63 
     64 	// mutiny! ignoring feof/ferror.
     65 	free(numbers.data);
     66 	fclose(infile);
     67 }