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..3416121 100644 --- a/2019/day06/aoc-c.c +++ b/2019/day06/aoc-c.c @@ -1,4 +1,4 @@ -/* aoc-c.c: Advent of Code 2019, day 4 parts 1 & 2 +/* aoc-c.c: Advent of Code 2019, day 6 parts 1 & 2 * * Copyright (C) 2021 Bruno Raoult ("br") * Licensed under the GNU General Public License v3.0 or later. @@ -48,19 +48,18 @@ typedef struct object { * @child: array of pointers to node_t children of current node * @str: current string (for debug) * @is_object: 1: this is an object, 0 if not - * @data: pointer to an object + * @data: object data */ typedef struct trie { struct trie *child[TRIESIZE]; - //char str[8]; int is_object; object_t data; } trie_t; /** * parent_t - list of parents for an object - * @object - address of parent object - * @list - next parent + * @object: address of object + * @list: next parent * * For example, if A orbits around B, which orbits around COM, list will be: * head -> COM -> B -> A @@ -70,166 +69,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) @@ -256,35 +198,13 @@ int main(int ac, char **av) } if (optind < ac) return usage(*av); - pool_tries = pool_create("tries", 1024, sizeof(trie_t)); - pool_parents = pool_create("parents", 1024, sizeof(parent_t)); + pool_tries = pool_create("tries", 1024, sizeof(trie_t)); trie_t *root = trie_get(NULL, NULL, 0); - /* - printf("size = %d\n", TRIESIZE); - printf("0 = %d\n", c2index('0')); - printf(" 0 = %c\n", index2c(0)); - printf("1 = %d\n", c2index('1')); - printf(" 1 = %c\n", index2c(1)); - printf("9 = %d\n", c2index('9')); - printf(" 8 = %c\n", index2c(8)); - printf("A = %d\n", c2index('A')); - printf(" A = %c\n", index2c(9)); - printf("Z = %d\n", c2index('Z')); - printf(" Z = %c\n", index2c(34)); - */ - //trie_find(root, "COM"); - //trie_find(root, "CAM"); - //trie_print(root, 0); - //exit(0); parse(root); - object_t *root_obj = object_find(root, "COM"); - trie_print(root, 0); - tree_print(root_obj, 0); printf("%s : res=%d\n", *av, - part == 1 ? orbit_count(object_find(root, "COM"), 0) : - count_path(root, "YOU", "SAN")); - //ancestor_find(root, "YOU", "SAN"); + part == 1 ? part1(object_find(root, "COM"), 0) : + part2(root, "YOU", "SAN")); pool_destroy(pool_tries); exit (0); }