Day11 tree
This commit is contained in:
BIN
day11/c/day11
BIN
day11/c/day11
Binary file not shown.
109
day11/c/day11.c
109
day11/c/day11.c
@@ -2,6 +2,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <omp.h>
|
||||
|
||||
#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 iterate_ll(stone_t *leaf, void (*cb)(stone_t*, void*), void* ctx) {
|
||||
if (leaf == NULL) {
|
||||
return;
|
||||
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) {
|
||||
//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)++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user