advent2023

Advent of Code 2023 solutions
git clone git://bsandro.tech/advent2023
Log | Files | Refs | LICENSE

puzzle.c (2106B)


      1 #define _DEFAULT_SOURCE
      2 
      3 #include <limits.h>
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <errno.h>
      7 #include <string.h>
      8 #include <strings.h>
      9 #include <assert.h>
     10 #include <stdbool.h>
     11 #include <inttypes.h>
     12 
     13 #define STR_LEN 2048
     14 
     15 typedef struct IntArray {
     16 	int *values;
     17 	int len;
     18 } IntArray;
     19 void IntArray_Add(IntArray *a, int v) {
     20 	a->len++;
     21 	a->values = reallocarray(a->values, a->len, sizeof(int));
     22 	a->values[a->len-1] = v;
     23 }
     24 bool IntArray_Same(IntArray *a) {
     25 	if (a->len <= 0) return false;
     26 	int v = a->values[0];
     27 	for (int i=0; i<a->len; ++i) {
     28 		if (a->values[i]!=v) {
     29 			return false;
     30 		}
     31 	}
     32 	return true;
     33 }
     34 void IntArray_Print(IntArray *a) {
     35 	for (int i=0; i<a->len; ++i) {
     36 		printf("v:%2d (%p)\n", a->values[i], a->values+i);
     37 	}
     38 }
     39 
     40 int IntArray_Diff(IntArray *a) {
     41 	if (IntArray_Same(a)) return a->values[0];
     42 	if (a->len==1) { printf("error: array of len 1\n"); exit(-1); }
     43 	IntArray n = {0};
     44 	for (int i=1; i<a->len; ++i) {
     45 		IntArray_Add(&n, a->values[i] - a->values[i-1]);
     46 	}
     47 	int diff = IntArray_Diff(&n);
     48 	return a->values[a->len-1]+diff;
     49 }
     50 
     51 int IntArray_Rdiff(IntArray *a) {
     52 	if (IntArray_Same(a)) return a->values[0];
     53 	if (a->len==1) { printf("error: array of len 1\n"); exit(-1); }
     54 	IntArray n = {0};
     55 	for (int i=0; i<a->len-1; ++i) {
     56 		IntArray_Add(&n, a->values[i+1] - a->values[i]);
     57 	}
     58 	int diff = IntArray_Rdiff(&n);
     59 	return a->values[0]-diff;
     60 }
     61 
     62 void puzzle(const char *filename, long long *result1, long long *result2) {
     63 	FILE *infile = fopen(filename, "r");
     64 	if (infile == NULL) {
     65 		fprintf(stderr, "fopen() error: %s\n", strerror(errno));
     66 		return;
     67 	}
     68 
     69 	char buf[STR_LEN] = {0};
     70 	unsigned int line_num = 0;
     71 	*result1 = 0;
     72 	*result2 = 0;
     73 
     74 	while (fgets(buf, STR_LEN, infile) != NULL) {
     75 		IntArray readings = {0};
     76 		char *s = strndup(buf, STR_LEN);
     77 		for (char *t; (t=strsep(&s, " "));) {
     78 			IntArray_Add(&readings, atoi(t));
     79 		}
     80 		free(s);
     81 
     82 		int diff1 = IntArray_Diff(&readings);
     83 		*result1 += diff1;
     84 
     85 		int diff2 = IntArray_Rdiff(&readings);
     86 		*result2 += diff2;
     87 		//@todo list_free ?
     88 		++line_num;
     89 		bzero(buf, STR_LEN);
     90 	}
     91 
     92 	// mutiny! ignoring feof/ferror.
     93 	fclose(infile);
     94 }