#include #include #include #include #include #define MAX_CHARS 1024 #define MAX_INITIAL_STONES 1024 #define MAX_LEAF_COUNT 16 typedef struct stone { uint64_t value; struct stone *leafs[2]; int leaf_count; } stone_t; void add_leaf(stone_t* root, stone_t* leaf); uint64_t call_on_leaf(stone_t *leaf, void (*cb)(stone_t*, void*), void* ctx); void blink(stone_t *leaf, void* ctx); int main() { char c, *p, *buf; buf = calloc(MAX_CHARS, sizeof(buf[0])); p = buf; while ((c = getchar()) != EOF) { *p++ = c; } size_t in = p - buf; int stone_count = 0; uint64_t *stones = calloc(MAX_INITIAL_STONES, sizeof(stones[0])); for (size_t i = 0; i < in;) { p = buf + i; sscanf(p, "%lu", &stones[stone_count++]); do { i++; } while(i < in && *(buf+i) != ' '); i++; } free(buf); //call_on_leaf(root, display, NULL); //printf("\n"); uint64_t sum = 0; #pragma omp parallel for for (int j = 0; j < stone_count; j++) { int blink_count = 75; stone_t *stone = calloc(1, sizeof(stone[0])); stone->value = stones[j]; uint64_t s = call_on_leaf(stone, blink, &blink_count); #pragma omp critical { sum += s; } } free(stones); printf("%lu\n", sum); } void add_leaf(stone_t* root, stone_t* leaf) { root->leafs[root->leaf_count++] = leaf; } uint64_t call_on_leaf(stone_t *leaf, void (*cb)(stone_t*, void*), void* ctx) { if (*(int*)ctx == 0) { free(leaf); return 1; } cb(leaf, ctx); uint64_t sum = 0; (*(int*)ctx)--; for (int i = 0; i < leaf->leaf_count; i++) { sum += call_on_leaf(leaf->leafs[i], cb, ctx); } (*(int*)ctx)++; free(leaf); return sum; } void blink(stone_t *leaf, void* ctx) { if (leaf->value == 0) { stone_t *next = calloc(1, sizeof(next[0])); next->value = 1; add_leaf(leaf, next); } else { // Split in two char buf[64]; sprintf(buf, "%lu", leaf->value); size_t len = strlen(buf); if (len % 2 == 0) { char left[32]; memcpy(left, buf, len / 2); left[len / 2] = '\0'; char right[32]; memcpy(right, buf + len / 2, len / 2); right[len / 2] = '\0'; stone_t *left_stone = calloc(1, sizeof(left_stone[0])); stone_t *right_stone = calloc(1, sizeof(right_stone[0])); sscanf(left, "%lu", &left_stone->value); sscanf(right, "%lu", &right_stone->value); add_leaf(leaf, left_stone); add_leaf(leaf, right_stone); } else { stone_t *next = calloc(1, sizeof(next[0])); next->value = leaf->value * 2024; add_leaf(leaf, next); } } }