#include #include #include #include #include #define DEFAULT_FILE "input.txt" #define STRBUF_LEN 300 #define ISDIGIT(X) (X >= '0' && X <= '9') #define NUM_ARR_LEN 300 #define NUM_DIFFS 300 bool all_zeroes(int *num_arr, int len) { int i = 0; for (i = 0; i < len; i++) { if (num_arr[i]) return false; } return true; } int parse_num(char *str) { bool isnegative = false; if (*str == '-') { isnegative = true; str++; } uint64_t num = 0; while (ISDIGIT(*str)) { num = (num * 10) + (*str - '0'); str++; } return isnegative ? -num : num; } int parse_nums(char *str, int *num_arr) { int i = 0; while (*str != '\n') { if (*str == ' ') str++; num_arr[i] = parse_num(str); i++; while (ISDIGIT(*str) || *str == '-') str++; } return i; } void print_arr(int *num_arr, int len) { int i = 0; for (i = 0; i < len; i++) { printf("%d ", num_arr[i]); } printf("\n"); } void calc_diff(int num_arr_len, int num_arr[num_arr_len], int diff_arr[num_arr_len - 1]) { int i = 0; for (i = 0; i < (num_arr_len - 1); i++) { diff_arr[i] = num_arr[i + 1] - num_arr[i]; } } int calc_all_diffs(int diffs_arr[NUM_DIFFS][NUM_ARR_LEN], int lens_arr[NUM_DIFFS]) { int k = 0; while (!all_zeroes(diffs_arr[k], lens_arr[k])) { calc_diff(lens_arr[k], diffs_arr[k], diffs_arr[k + 1]); lens_arr[k + 1] = lens_arr[k] - 1; k++; } memset(diffs_arr[k], 0, sizeof(int) * NUM_ARR_LEN); return k; } #define PREDICT_NEXT(num_arr, num_arr_len, diffs) (num_arr[num_arr_len - 1] + diffs[num_arr_len - 1]) int predict_next_val(int diffs_arr[NUM_DIFFS][NUM_ARR_LEN], int *lens_arr, int depth) { while (depth) { depth--; int len = lens_arr[depth]; int *current_arr = diffs_arr[depth]; int *diff = diffs_arr[depth + 1]; int current_arr_last_val = current_arr[len - 1]; int diff_last_val = diff[len - 1]; int next = current_arr_last_val + diff_last_val; diffs_arr[depth][len] = next; print_arr(diffs_arr[depth], lens_arr[depth] + 1); } return diffs_arr[0][lens_arr[0]]; } int main(int argc, char **argv) { // Get filename as an argument, if there is one char *path = (argc > 1) ? argv[1] : DEFAULT_FILE; if (!path) { printf("Requires input file.\n"); return 1; } FILE *file = fopen(path, "r"); char strbuf[STRBUF_LEN] = {0}; if (!file) { printf("Could not find file."); return 1; } // Begin challenge // diffs_arr[0] is a single line of the puzzle input // diffs_arr[0][0] is the first int of the first line int diffs_arr[NUM_DIFFS][NUM_ARR_LEN]; // Length of each diff arr int lens_arr[NUM_DIFFS] = {0}; int i = 0; uint64_t sum = 0; while (fgets(strbuf, STRBUF_LEN, file)) { if (strbuf[0] == '\n') break; lens_arr[0] = parse_nums(strbuf, diffs_arr[0]); int depth = calc_all_diffs(diffs_arr, lens_arr); int next_val = predict_next_val(diffs_arr, lens_arr, depth); sum += next_val; } printf("Sum: %lu\n", sum); return 0; }