diff --git a/day11/c/day11 b/day11/c/day11 new file mode 100755 index 0000000..0417e22 Binary files /dev/null and b/day11/c/day11 differ diff --git a/day11/c/day11.c b/day11/c/day11.c new file mode 100644 index 0000000..ba416b3 --- /dev/null +++ b/day11/c/day11.c @@ -0,0 +1,131 @@ +#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 *prev; + struct stone *next; +} stone_t; + +void deallocate_ll(stone_t *leaf); +void iterate_ll(stone_t *, 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; + + 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++; + } + + stone_t *head; + + for (int i = 0; i < stone_count; i++) { + stone_t *stone = calloc(1, sizeof(stone[0])); + stone->value = stones[i]; + if (i == 0) { + head = stone; + continue; + } + 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); +} + +void deallocate_ll(stone_t *leaf) { + if (leaf == NULL) { + return; + } + stone_t* next = leaf->next; + free(leaf); + deallocate_ll(next); +} + +void iterate_ll(stone_t *leaf, void (*cb)(stone_t*, void*), void* ctx) { + if (leaf == NULL) { + return; + } + + cb(leaf, ctx); + iterate_ll(leaf->next, cb, ctx); +} + +void blink(stone_t *leaf, void* ctx) { + if (leaf->value == 0) { + leaf->value = 1; + } 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])); + 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; + } else { + leaf->value *= 2024; + } + } +} + +void count(stone_t *leaf, void* ctx) { + (*(uint64_t*)ctx)++; +} diff --git a/day11/input.txt b/day11/input.txt new file mode 100644 index 0000000..bbc2705 --- /dev/null +++ b/day11/input.txt @@ -0,0 +1 @@ +112 1110 163902 0 7656027 83039 9 74 diff --git a/day11/sample.txt b/day11/sample.txt new file mode 100644 index 0000000..9b26c84 --- /dev/null +++ b/day11/sample.txt @@ -0,0 +1 @@ +125 17