Files
AdventOfCode2023/09/09.c
2023-12-09 23:09:07 -05:00

185 lines
3.8 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#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
#define REVERSE_ARR 1
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;
}
void reverse_arr(int *num_arr, int len)
{
int i = 0;
int temp;
for (i = 0; i < (len / 2); i++)
{
temp = num_arr[i];
num_arr[i] = num_arr[len - i - 1];
num_arr[len - i - 1] = temp;
}
}
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++;
}
#if (REVERSE_ARR)
int k = 0;
int temp;
for (k = 0; k < (i / 2); k++)
{
temp = num_arr[k];
num_arr[k] = num_arr[i - k - 1];
num_arr[i - k - 1] = temp;
}
#endif
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;
}