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 }