diff --git a/2019/RESULTS.txt b/2019/RESULTS.txt index 6bd3ea6..954c085 100644 --- a/2019/RESULTS.txt +++ b/2019/RESULTS.txt @@ -67,3 +67,18 @@ aoc-c : res=10987514 aoc-c : res=14195011 time: 0:00.00 real, 0.00 user, 0.00 sys context-switch: 0+1, page-faults: 0+87 + +========================================= +================= day06 ================= +========================================= + ++++++++++++++++++ part 1 +compiling aoc-c.c +aoc-c : res=453028 + time: 0:00.00 real, 0.00 user, 0.00 sys + context-switch: 0+1, page-faults: 0+429 + ++++++++++++++++++ part 2 +aoc-c : res=562 + time: 0:00.00 real, 0.00 user, 0.00 sys + context-switch: 0+1, page-faults: 0+436 diff --git a/2019/day06/aoc-c.c b/2019/day06/aoc-c.c index e4308de..33d4d4b 100644 --- a/2019/day06/aoc-c.c +++ b/2019/day06/aoc-c.c @@ -70,166 +70,109 @@ typedef struct { struct list_head list; } parent_t; -static pool_t *pool_tries, *pool_parents; +static pool_t *pool_tries; static trie_t *trie_get(trie_t *parent, char *name, int pos) { trie_t *trie; - static int count = 0; - count++; - log_f(3, "parent=%p name=%s pos=%d\n", parent, name, pos); if ((trie = pool_get(pool_tries))) { for (int i = 0; i < TRIESIZE; ++i) trie->child[i] = NULL; - //*trie->str = 0; trie->is_object = 0; - if (parent) { - int index = c2index(name[pos]); - parent->child[index] = trie; - log(3, "setting parent %p[%c] to %p\n", parent, name[pos], trie); - //strncpy(trie->str, name, pos + 1); - } + if (parent) + parent->child[c2index(name[pos])] = trie; } - log(3, "\tnew trie=%p total = %d\n", trie, count); return trie; } -static void trie_print(trie_t *trie, int depth) -{ - if (depth == 0) - log_f(3, "root=%p depth=%d\n", trie, depth); - if (trie->is_object) { - printf("%*sOBJECT %s parent=%s\n", depth * 4, "", trie->data.name, - trie->data.parent? trie->data.parent->name: "NIL"); - } - for (int i = 0; i < TRIESIZE; ++i) { - if (trie->child[i]) { - printf("%*s+%c\n", depth * 4, "", index2c(i)); - trie_print(trie->child[i], depth + 1); - } - } -} - -static void tree_print(object_t *object, int depth) -{ - if (depth == 0) - log_f(3, "root=%p depth=%d\n", object, depth); - printf("%*sOBJECT %s\n", depth * 4, "", object->name); - if (!list_empty(&object->child)) { - object_t *cur; - list_for_each_entry(cur, &object->child, sibling) { - tree_print(cur, depth + 1); - } - } -} - -static int orbit_count(object_t *object, int depth) -{ - int ret = depth; - if (!list_empty(&object->child)) { - object_t *cur; - list_for_each_entry(cur, &object->child, sibling) { - ret += orbit_count(cur, depth + 1); - } - } - return ret; -} - static trie_t *trie_find(trie_t *root, char *name) { int len = strlen(name); - trie_t *cur = root; for (int i = 0; i < len; ++i) { int ind = c2index(name[i]); - cur = cur->child[ind] ? - cur->child[ind]: - trie_get(cur, name, i); + root = root->child[ind] ? root->child[ind]: trie_get(root, name, i); } - if (!cur->is_object) { - cur->data.parent = NULL; - cur->is_object = 1; - strcpy(cur->data.name, name); - INIT_LIST_HEAD(&cur->data.child); - INIT_LIST_HEAD(&cur->data.sibling); - } - return cur; + return root; } -static object_t *object_find(trie_t *root, char *object) +static object_t *object_find(trie_t *root, char *name) { - object_t *ret = &trie_find(root, object)->data; - log_f(3, "object = %p - %s\n", ret, ret->name); + trie_t *trie = trie_find(root, name); + if (!trie->is_object) { + trie->data.parent = NULL; + trie->is_object = 1; + strcpy(trie->data.name, name); + INIT_LIST_HEAD(&trie->data.child); + INIT_LIST_HEAD(&trie->data.sibling); + } + return &trie->data; +} + +static int part1(object_t *object, int depth) +{ + int ret = depth; + object_t *cur; + + if (!list_empty(&object->child)) + list_for_each_entry(cur, &object->child, sibling) + ret += part1(cur, depth + 1); return ret; } -static int count_path(trie_t *root, char *name1, char *name2) +static int part2(trie_t *root, char *name1, char *name2) { - object_t *obj1 = object_find(root, name1); - object_t *obj2 = object_find(root, name2); + object_t *obj; parent_t *parent, *parent1, *parent2; LIST_HEAD(list1); LIST_HEAD(list2); - int count1 = 0, count2 = 0; - while (obj1->parent) { - count1++; - obj1 = obj1->parent; + pool_t *pool_parents = pool_create("parents", 1024, sizeof(parent_t)); + int count = 0; + + /* build a list of nodes from root to the two objects + */ + obj = object_find(root, name1); + while (obj->parent) { + count++; + obj = obj->parent; parent = pool_get(pool_parents); - parent->object = obj1; + parent->object = obj; list_add(&parent->list, &list1); } - while (obj2->parent) { - count2++; - obj2 = obj2->parent; + obj = object_find(root, name2); + while (obj->parent) { + count++; + obj = obj->parent; parent = pool_get(pool_parents); - parent->object = obj2; + parent->object = obj; list_add(&parent->list, &list2); } + /* skip common parents in the two lists + */ parent1 = list_first_entry_or_null(&list1, parent_t, list); parent2 = list_first_entry_or_null(&list2, parent_t, list); while (parent1->object == parent2->object) { - count1--; - count2--; - parent = parent1; + count -= 2; parent1 = list_next_entry(parent1, list); - //list_del(parent1->list.prev); parent2 = list_next_entry(parent2, list); - //list_del(parent2->list.prev); } - printf ("common ancestor = %s\n", parent->object->name); - printf("count1 = %d count2 = %d\n", count1, count2); - return count1 + count2; -} - -static void object_link(trie_t *root, char *star, char *planet) -{ - object_t *st, *pl; - log_f(3, "linking planet %s to star %s\n", planet, star); - st = object_find(root, star); - pl = object_find(root, planet); - pl->parent = st; - list_add(&pl->sibling, &st->child); + pool_destroy(pool_parents); + return count; } static void parse(trie_t *root) { - char *star, *planet; - - size_t alloc = 0; - ssize_t buflen; - char *buf = NULL; - - while ((buflen = getline(&buf, &alloc, stdin)) > 0) { - star = strtok(buf, ")\n"); - planet = strtok(NULL, ")\n"); - printf ("read [%s][%s]\n", star, planet); - object_link(root, star, planet); - //hash = hash_string(NULL, star, strlen(star)); - //log(3, "hash(%s) = %u\n", star, hash); + char str1[8], str2[8]; + while (scanf(" %7[^)])%s", str1, str2) == 2) { + object_t *star = object_find(root, str1); + object_t *planet = object_find(root, str2); + /* link planet to star, add planet to star's planets list + */ + planet->parent = star; + list_add(&planet->sibling, &star->child); } - free(buf); } static int usage(char *prg)