// Returns the smallest 'cats[cat].counter+counter' on all ancestors of 'cat'. int find_minimum_relationship(CatID cat, int counter) { if (cat == NIL) return COUNTER_SENTINEL; else { return min_counter( add_counter(counter, cats[cat].counter), min_counter( find_minimum_relationship(cats[cat].sire, counter + 1), find_minimum_relationship(cats[cat].dam, counter + 1))); } }
// Sets the 'counter' on all ancestors of 'cat' based on 'counter'. void mark_ancestors(CatID cat, int counter) { if (cat == NIL) return; else { cats[cat].counter = min_counter(counter, cats[cat].counter); mark_ancestors(cats[cat].sire, counter + 1); mark_ancestors(cats[cat].dam, counter + 1); } }
static uint64_t counter_var(int from, int up_to) { uint64_t avg_ = avg_counter(from, up_to); uint64_t max_ = max_counter(from, up_to) - avg_; uint64_t min_ = avg_ - min_counter(from, up_to); uint64_t worst = min_; if (max_ > min_) worst = max_; return (worst * 100) / avg_; }
// Sets the 'counter' on the descendants of 'cat'. void mark_descendants(CatID cat, int max_depth, int curr_depth) { if (cat == NIL) return; else if (curr_depth > max_depth) return; else { // mark self cats[cat].counter = min_counter(curr_depth, cats[cat].counter); // recur on children by looping though the eldest's siblings for (CatID child = cats[cat].eldest_child; child != NIL; child = get_sibling(child, is_male(cat))) { mark_descendants(child, max_depth, curr_depth + 1); } } }
// Prints "<cat1> is the <relationship> of <cat2>.\n" void print_relationship(CatID cat1, int count1, CatID cat2, int count2) { assert(count1 != COUNTER_SENTINEL); assert(count2 != COUNTER_SENTINEL); printf("%d is the ", cats[cat1].tableEntry); //printf("%d is the ", cats[cat1].tableEntry); if (count1 == 0 && count2 == 0) { printf("same as"); } else if (count1 == 0) { print_great_grand(count2 - 1); printf(is_male(cats[cat1].tableEntry) ? "father of" : "mother of"); } else if (count2 == 0) { print_great_grand(count1 - 1); printf(is_male(cats[cat1].tableEntry) ? "son of" : "daughter of"); } else if (count1 == 1 && count2 == 1) { printf(is_male(cats[cat1].tableEntry) ? "brother of" : "sister of"); } else if (count1 == 1) { print_great_grand(count2 - 2); printf(is_male(cats[cat1].tableEntry) ? "uncle of" : "aunt of"); } else if (count2 == 1) { print_great_grand(count1 - 2); printf(is_male(cats[cat1].tableEntry) ? "nephew of" : "niece of"); } else { int i = min_counter(count1, count2) - 1; int j = abs(count1 - count2); print_ordinal(i); printf(" cousin"); if (j > 0) printf(", %d time%s removed", j, j == 1 ? "" : "s"); printf(" of"); } printf(" %d.\n", cats[cat2].tableEntry); //printf(" eldest_child: %d.\n", cats[cat1].eldest_child); }