2019 day 6: remove dead code, trie contains object ptr instead of object

This commit is contained in:
2022-09-28 18:43:00 +02:00
parent a201283599
commit 0004b2091e
2 changed files with 77 additions and 142 deletions

View File

@@ -67,3 +67,18 @@ aoc-c : res=10987514
aoc-c : res=14195011 aoc-c : res=14195011
time: 0:00.00 real, 0.00 user, 0.00 sys time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+87 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

View File

@@ -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") * Copyright (C) 2021 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later. * 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 * @child: array of pointers to node_t children of current node
* @str: current string (for debug) * @str: current string (for debug)
* @is_object: 1: this is an object, 0 if not * @is_object: 1: this is an object, 0 if not
* @data: pointer to an object * @data: object data
*/ */
typedef struct trie { typedef struct trie {
struct trie *child[TRIESIZE]; struct trie *child[TRIESIZE];
//char str[8];
int is_object; int is_object;
object_t data; object_t data;
} trie_t; } trie_t;
/** /**
* parent_t - list of parents for an object * parent_t - list of parents for an object
* @object - address of parent object * @object: address of object
* @list - next parent * @list: next parent
* *
* For example, if A orbits around B, which orbits around COM, list will be: * For example, if A orbits around B, which orbits around COM, list will be:
* head -> COM -> B -> A * head -> COM -> B -> A
@@ -70,166 +69,109 @@ typedef struct {
struct list_head list; struct list_head list;
} parent_t; } 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) static trie_t *trie_get(trie_t *parent, char *name, int pos)
{ {
trie_t *trie; 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))) { if ((trie = pool_get(pool_tries))) {
for (int i = 0; i < TRIESIZE; ++i) for (int i = 0; i < TRIESIZE; ++i)
trie->child[i] = NULL; trie->child[i] = NULL;
//*trie->str = 0;
trie->is_object = 0; trie->is_object = 0;
if (parent) { if (parent)
int index = c2index(name[pos]); parent->child[c2index(name[pos])] = trie;
parent->child[index] = trie;
log(3, "setting parent %p[%c] to %p\n", parent, name[pos], trie);
//strncpy(trie->str, name, pos + 1);
}
} }
log(3, "\tnew trie=%p total = %d\n", trie, count);
return trie; 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) static trie_t *trie_find(trie_t *root, char *name)
{ {
int len = strlen(name); int len = strlen(name);
trie_t *cur = root;
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
int ind = c2index(name[i]); int ind = c2index(name[i]);
cur = cur->child[ind] ? root = root->child[ind] ? root->child[ind]: trie_get(root, name, i);
cur->child[ind]:
trie_get(cur, name, i);
} }
if (!cur->is_object) { return root;
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;
} }
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; trie_t *trie = trie_find(root, name);
log_f(3, "object = %p - %s\n", ret, ret->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; 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 *obj;
object_t *obj2 = object_find(root, name2);
parent_t *parent, *parent1, *parent2; parent_t *parent, *parent1, *parent2;
LIST_HEAD(list1); LIST_HEAD(list1);
LIST_HEAD(list2); LIST_HEAD(list2);
int count1 = 0, count2 = 0; pool_t *pool_parents = pool_create("parents", 1024, sizeof(parent_t));
while (obj1->parent) { int count = 0;
count1++;
obj1 = obj1->parent; /* 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 = pool_get(pool_parents);
parent->object = obj1; parent->object = obj;
list_add(&parent->list, &list1); list_add(&parent->list, &list1);
} }
while (obj2->parent) { obj = object_find(root, name2);
count2++; while (obj->parent) {
obj2 = obj2->parent; count++;
obj = obj->parent;
parent = pool_get(pool_parents); parent = pool_get(pool_parents);
parent->object = obj2; parent->object = obj;
list_add(&parent->list, &list2); list_add(&parent->list, &list2);
} }
/* skip common parents in the two lists
*/
parent1 = list_first_entry_or_null(&list1, parent_t, list); parent1 = list_first_entry_or_null(&list1, parent_t, list);
parent2 = list_first_entry_or_null(&list2, parent_t, list); parent2 = list_first_entry_or_null(&list2, parent_t, list);
while (parent1->object == parent2->object) { while (parent1->object == parent2->object) {
count1--; count -= 2;
count2--;
parent = parent1;
parent1 = list_next_entry(parent1, list); parent1 = list_next_entry(parent1, list);
//list_del(parent1->list.prev);
parent2 = list_next_entry(parent2, list); parent2 = list_next_entry(parent2, list);
//list_del(parent2->list.prev);
} }
printf ("common ancestor = %s\n", parent->object->name); pool_destroy(pool_parents);
printf("count1 = %d count2 = %d\n", count1, count2); return count;
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);
} }
static void parse(trie_t *root) static void parse(trie_t *root)
{ {
char *star, *planet; char str1[8], str2[8];
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);
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) static int usage(char *prg)
@@ -256,35 +198,13 @@ int main(int ac, char **av)
} }
if (optind < ac) if (optind < ac)
return usage(*av); 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); 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); 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, printf("%s : res=%d\n", *av,
part == 1 ? orbit_count(object_find(root, "COM"), 0) : part == 1 ? part1(object_find(root, "COM"), 0) :
count_path(root, "YOU", "SAN")); part2(root, "YOU", "SAN"));
//ancestor_find(root, "YOU", "SAN");
pool_destroy(pool_tries); pool_destroy(pool_tries);
exit (0); exit (0);
} }