puzzle.c (2079B)
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 12 #define STR_LEN 16384 13 #define FISH_VARIANTS 8 14 #define FISHES_SIZE 9 15 #define FISH_COMMON 6 16 17 void make_fishes(size_t *fishes, const char *str); 18 size_t sum_fishes(size_t *orig_fishes, int days); 19 20 /* ****************************************************************** */ 21 22 void puzzle(const char *filename, size_t *result1, size_t *result2) { 23 FILE *infile = fopen(filename, "r"); 24 if (infile == NULL) { 25 fprintf(stderr, "fopen() error: %s\n", strerror(errno)); 26 return; 27 } 28 29 char buf[STR_LEN] = {0}; 30 unsigned int line_num = 0; 31 32 size_t fishes[FISHES_SIZE] = {0}; 33 34 while (fgets(buf, STR_LEN, infile) != NULL) { 35 make_fishes(fishes, buf); 36 ++line_num; 37 bzero(buf, STR_LEN); 38 } 39 40 *result1 = sum_fishes(fishes, 80); 41 *result2 = sum_fishes(fishes, 256); 42 43 // mutiny! ignoring feof/ferror. 44 fclose(infile); 45 } 46 47 void make_fishes(size_t *fishes, const char *str) { 48 assert(fishes != NULL); 49 assert(str != NULL); 50 char *tmp = strndup(str, STR_LEN); 51 char *token = NULL; 52 assert(tmp != NULL); 53 54 while ((token = strsep(&tmp, ",")) != NULL) { 55 int val = atoi(token); 56 assert(val < FISH_VARIANTS); 57 fishes[val]++; 58 } 59 60 free(tmp); 61 } 62 63 size_t sum_fishes(size_t *orig_fishes, int days) { 64 assert(orig_fishes != NULL); 65 size_t fishes[FISHES_SIZE]; 66 memcpy(fishes, orig_fishes, sizeof(size_t) * FISHES_SIZE); 67 68 for (int day = 1; day <= days; ++day) { 69 // took me an eternity to see the pattern 70 // thanks for help from friends from the #lobsters-advent 71 // fixed it without using matrices multiplication 72 73 // [a, b, c, d, e, f, g, h, i] -> [b, c, d, e, f, g, h+a, i, a] 74 size_t fish_0 = fishes[0]; 75 for (int i = 0; i < FISH_VARIANTS; ++i) { 76 if (i == FISH_COMMON) { 77 fishes[i] = fishes[i+1] + fish_0; 78 } else { 79 fishes[i] = fishes[i+1]; 80 } 81 } 82 fishes[FISH_VARIANTS] = fish_0; 83 } 84 85 size_t result = 0; 86 for (int i = 0; i < FISHES_SIZE; ++i) { 87 result += fishes[i]; 88 } 89 90 return result; 91 }