Aaaaaaaaaaaaaaagh

This commit is contained in:
Bill Rossi 2024-12-11 16:10:55 -05:00
parent 80a315131b
commit 81b2f98dbf

View File

@ -0,0 +1,141 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <limits.h>
#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;
}