diff --git a/day11/c/day11 b/day11/c/day11 index 0417e22..b1c6e4d 100755 Binary files a/day11/c/day11 and b/day11/c/day11 differ diff --git a/day11/c/day11.c b/day11/c/day11.c index ba416b3..9026f59 100644 --- a/day11/c/day11.c +++ b/day11/c/day11.c @@ -2,6 +2,7 @@ #include #include #include +#include #define MAX_CHARS 1024 #define MAX_INITIAL_STONES 1024 @@ -9,18 +10,14 @@ typedef struct stone { uint64_t value; - struct stone *prev; - struct stone *next; + struct stone *leafs[2]; + int leaf_count; } stone_t; -void deallocate_ll(stone_t *leaf); -void iterate_ll(stone_t *, void (*cb)(stone_t*, void*), void* ctx); +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 display(stone_t *stone, void* ctx) { - printf("%lu ", stone->value); -} void blink(stone_t *leaf, void* ctx); -void count(stone_t *leaf, void* ctx); int main() { char c, *p, *buf; @@ -46,59 +43,62 @@ int main() { i++; } - stone_t *head; + free(buf); - for (int i = 0; i < stone_count; i++) { + //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[i]; - if (i == 0) { - head = stone; - continue; + stone->value = stones[j]; + uint64_t s = call_on_leaf(stone, blink, &blink_count); +#pragma omp critical + { + sum += s; } - stone_t *tmp = head; - while(tmp->next != NULL) tmp = tmp->next; - tmp->next = stone; - stone->prev = tmp; } free(stones); - free(buf); - int blink_count = 75; - for (int i = 0; i < blink_count; i++) { - iterate_ll(head, blink, NULL); - while(head->prev != NULL) head = head->prev; - printf("%i\n", i); - } - uint64_t cnt = 0; - iterate_ll(head, count, &cnt); - - printf("%lu\n", cnt); - - deallocate_ll(head); + printf("%lu\n", sum); } -void deallocate_ll(stone_t *leaf) { - if (leaf == NULL) { - return; - } - stone_t* next = leaf->next; - free(leaf); - deallocate_ll(next); +void add_leaf(stone_t* root, stone_t* leaf) { + root->leafs[root->leaf_count++] = leaf; } -void iterate_ll(stone_t *leaf, void (*cb)(stone_t*, void*), void* ctx) { - if (leaf == NULL) { - return; - } - +uint64_t call_on_leaf(stone_t *leaf, void (*cb)(stone_t*, void*), void* ctx) { + //printf("%lu\n", leaf->value); cb(leaf, ctx); - iterate_ll(leaf->next, cb, ctx); + + if (*(int*)ctx == 0) { + for (int i = 0; i < leaf->leaf_count; i++) { + free(leaf->leafs[i]); + } + free(leaf); + return 1; + } + + 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) { - leaf->value = 1; + stone_t *next = calloc(1, sizeof(next[0])); + next->value = 1; + add_leaf(leaf, next); } else { // Split in two char buf[64]; @@ -112,20 +112,15 @@ void blink(stone_t *leaf, void* ctx) { 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", &leaf->value); - if (leaf->prev) { - left_stone->prev = leaf->prev; - leaf->prev->next = left_stone; - } - leaf->prev = left_stone; - left_stone->next = leaf; + sscanf(right, "%lu", &right_stone->value); + add_leaf(leaf, left_stone); + add_leaf(leaf, right_stone); } else { - leaf->value *= 2024; + stone_t *next = calloc(1, sizeof(next[0])); + next->value = leaf->value * 2024; + add_leaf(leaf, next); } } } - -void count(stone_t *leaf, void* ctx) { - (*(uint64_t*)ctx)++; -}