simplify part 2: use depths difference instead of two parent lists
This commit is contained in:
@@ -76,9 +76,9 @@ aoc-c : res=14195011
|
|||||||
compiling aoc-c.c
|
compiling aoc-c.c
|
||||||
aoc-c : res=453028
|
aoc-c : res=453028
|
||||||
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+429
|
context-switch: 0+1, page-faults: 0+417
|
||||||
|
|
||||||
+++++++++++++++++ part 2
|
+++++++++++++++++ part 2
|
||||||
aoc-c : res=562
|
aoc-c : res=562
|
||||||
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+436
|
context-switch: 0+1, page-faults: 0+417
|
||||||
|
@@ -116,20 +116,6 @@ typedef struct trie {
|
|||||||
object_t *object;
|
object_t *object;
|
||||||
} trie_t;
|
} trie_t;
|
||||||
|
|
||||||
/**
|
|
||||||
* parent_t - list of parents for an object
|
|
||||||
* @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.
|
|
||||||
* This is used only in part 2 (to find common ancestor of two objects).
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
object_t *object;
|
|
||||||
struct list_head list;
|
|
||||||
} parent_t;
|
|
||||||
|
|
||||||
static pool_t *pool_tries, *pool_objects;
|
static pool_t *pool_tries, *pool_objects;
|
||||||
|
|
||||||
static trie_t *trie_get(trie_t *parent, char *name, int pos)
|
static trie_t *trie_get(trie_t *parent, char *name, int pos)
|
||||||
@@ -181,44 +167,43 @@ static int part1(object_t *object, int depth)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_depth(object_t *obj)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
for (; obj; obj = obj->parent)
|
||||||
|
res++;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int part2(trie_t *root, char *name1, char *name2)
|
static int part2(trie_t *root, char *name1, char *name2)
|
||||||
{
|
{
|
||||||
object_t *obj;
|
object_t *obj1, *obj2;
|
||||||
parent_t *parent, *parent1, *parent2;
|
int count = 0, depth1, depth2;
|
||||||
LIST_HEAD(list1);
|
|
||||||
LIST_HEAD(list2);
|
|
||||||
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
|
/* build a list of nodes from root to the two objects
|
||||||
*/
|
*/
|
||||||
obj = object_find(root, name1);
|
obj1 = object_find(root, name1);
|
||||||
while (obj->parent) {
|
depth1 = get_depth(obj1);
|
||||||
count++;
|
obj2 = object_find(root, name2);
|
||||||
obj = obj->parent;
|
depth2 = get_depth(obj2);
|
||||||
parent = pool_get(pool_parents);
|
while (obj1 != obj2) {
|
||||||
parent->object = obj;
|
if (depth1 > depth2) {
|
||||||
list_add(&parent->list, &list1);
|
obj1 = obj1->parent;
|
||||||
|
depth1--;
|
||||||
|
count++;
|
||||||
|
} else if (depth2 > depth1) {
|
||||||
|
obj2 = obj2->parent;
|
||||||
|
depth2--;
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
obj1 = obj1->parent;
|
||||||
|
depth1--;
|
||||||
|
obj2 = obj2->parent;
|
||||||
|
depth2--;
|
||||||
|
count +=2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
obj = object_find(root, name2);
|
return count - 2; /* coz' we want objects parents */
|
||||||
while (obj->parent) {
|
|
||||||
count++;
|
|
||||||
obj = obj->parent;
|
|
||||||
parent = pool_get(pool_parents);
|
|
||||||
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) {
|
|
||||||
count -= 2;
|
|
||||||
parent1 = list_next_entry(parent1, list);
|
|
||||||
parent2 = list_next_entry(parent2, list);
|
|
||||||
}
|
|
||||||
pool_destroy(pool_parents);
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse(trie_t *root)
|
static void parse(trie_t *root)
|
||||||
|
Reference in New Issue
Block a user