#include #include #include #include #include #include "../../lib/aoc.h" typedef long long stone; typedef struct Stones { stone first; stone second; } Stones; typedef struct StonePile { stone value; long long count; } StonePile; int sort_stone_piles(const void *a, const void *b) { return ((*(StonePile*) a).value - (*(StonePile*) b).value) % INT_MAX; } int num_digits(stone s) { stone comp = 10; int digits = 1; while (s >= comp) { digits++; comp *= 10; } return digits; } int num_children(stone s, int generations_remaining) { if (generations_remaining == 0) return 1; int next_gen = generations_remaining - 1; int stone_num_digits = num_digits(s); int nc; if (s == 0ll) { nc = num_children(1, next_gen); } else if (stone_num_digits % 2 == 0) { stone comp = 10; for (int i = 1; i < stone_num_digits / 2; i++) comp *= 10; nc = num_children(s / comp, next_gen) + num_children(s % comp, next_gen); } else { nc = num_children(s * 2024, next_gen); } return nc; } Stones change(stone s) { Stones stones; int stone_num_digits = num_digits(s); if (s == 0ll) { stones.first = 1; stones.second = -1; } else if (stone_num_digits % 2 == 0) { stone comp = 10; for (int i = 1; i < stone_num_digits / 2; i++) comp *= 10; stones.first = s / comp; stones.second = s % comp; } else { stones.first = s * 2024; stones.second = -1; } return stones; } int main() { char *input = aoc_read_input(); StonePile stone_array[50000], next_stone_array[50000]; int stone_count = 0, next_stone_count = 0; char *current_token = strtok(input, " "); long long stone_count_sum = 0ll; long long big_stone_count_sum = 0ll; while (current_token != NULL) { stone_array[stone_count].value = atoll(current_token); stone_array[stone_count].count = 1ll; stone_count++; current_token = strtok(NULL, " "); } for (int i = 0; i < 75; i++) { next_stone_count = 0; for (int j = 0; j < stone_count; j++) { Stones s = change(stone_array[j].value); next_stone_array[next_stone_count].value = s.first; next_stone_array[next_stone_count].count = stone_array[j].count; next_stone_count++; if (s.second != -1) { next_stone_array[next_stone_count].value = s.second; next_stone_array[next_stone_count].count = stone_array[j].count; next_stone_count++; } } qsort(next_stone_array, next_stone_count, sizeof(StonePile), sort_stone_piles); stone_array[0].count = next_stone_array[0].count; stone_array[0].value = next_stone_array[0].value; stone_count = 1; for (int j = 1; j < next_stone_count; j++) { if (next_stone_array[j].value == stone_array[stone_count - 1].value) { stone_array[stone_count - 1].count += next_stone_array[j].count; } else { stone_count++; stone_array[stone_count - 1].value = next_stone_array[j].value; stone_array[stone_count - 1].count = next_stone_array[j].count; } } if (i == 24) { stone_count_sum = 0; for (int j = 0; j < stone_count; j++) { stone_count_sum += stone_array[j].count; } } if (i == 74) { big_stone_count_sum = 0; for (int j = 0; j < stone_count; j++) { big_stone_count_sum += stone_array[j].count; } } } printf("Part 1: %lld\n", stone_count_sum); printf("Part 2: %lld\n", big_stone_count_sum); aoc_free(); return 0; }