Task: Longest common suffix

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node_t {
    char *elem;
    int length;
    struct node_t *next;
} node;

node *make_node(char *s) {
    node *t = malloc(sizeof(node));
    t->elem = s;
    t->length = strlen(s);
    t->next = NULL;
    return t;
}

void append_node(node *head, node *elem) {
    while (head->next != NULL) {
        head = head->next;
    }
    head->next = elem;
}

void print_node(node *n) {
    putc('[', stdout);
    while (n != NULL) {
        printf("`%s` ", n->elem);
        n = n->next;
    }
    putc(']', stdout);
}

char *lcs(node *list) {
    int minLen = INT_MAX;
    int i;

    char *res;
    node *ptr;

    if (list == NULL) {
        return "";
    }
    if (list->next == NULL) {
        return list->elem;
    }

    for (ptr = list; ptr != NULL; ptr = ptr->next) {
        minLen = min(minLen, ptr->length);
    }
    if (minLen == 0) {
        return "";
    }

    res = "";
    for (i = 1; i < minLen; i++) {
        char *suffix = &list->elem[list->length - i];

        for (ptr = list->next; ptr != NULL; ptr = ptr->next) {
            char *e = &ptr->elem[ptr->length - i];
            if (strcmp(suffix, e) != 0) {
                return res;
            }
        }

        res = suffix;
    }

    return res;
}

void test(node *n) {
    print_node(n);
    printf(" -> `%s`\n", lcs(n));
}

void case1() {
    node *n = make_node("baabababc");
    append_node(n, make_node("baabc"));
    append_node(n, make_node("bbbabc"));
    test(n);
}

void case2() {
    node *n = make_node("baabababc");
    append_node(n, make_node("baabc"));
    append_node(n, make_node("bbbazc"));
    test(n);
}

void case3() {
    node *n = make_node("Sunday");
    append_node(n, make_node("Monday"));
    append_node(n, make_node("Tuesday"));
    append_node(n, make_node("Wednesday"));
    append_node(n, make_node("Thursday"));
    append_node(n, make_node("Friday"));
    append_node(n, make_node("Saturday"));
    test(n);
}

void case4() {
    node *n = make_node("longest");
    append_node(n, make_node("common"));
    append_node(n, make_node("suffix"));
    test(n);
}

void case5() {
    node *n = make_node("suffix");
    test(n);
}

void case6() {
    node *n = make_node("");
    test(n);
}

int main() {
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    return 0;
}


C++: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>

std::string lcs(const std::vector<std::string>& strs) {
    std::vector<std::string::const_reverse_iterator> backs;
    std::string s;
    
    if (strs.size() == 0) return "";
    if (strs.size() == 1) return strs[0];
    
    for (auto& str : strs) backs.push_back(str.crbegin());
    
    while (backs[0] != strs[0].crend()) {
        char ch = *backs[0]++;
        for (std::size_t i = 1; i<strs.size(); i++) {
            if (backs[i] == strs[i].crend()) goto done;
            if (*backs[i] != ch) goto done;
            backs[i]++;
        }
        s.push_back(ch);
    }
    
done:
    reverse(s.begin(), s.end());
    return s;
}

void test(const std::vector<std::string>& strs) {
    std::cout << "[";
    for (std::size_t i = 0; i<strs.size(); i++) {
        std::cout << '"' << strs[i] << '"';
        if (i != strs.size()-1) std::cout << ", ";
    }
    std::cout << "] -> `" << lcs(strs) << "`\n";
}

int main() {
    std::vector<std::string> t1 = {"baabababc", "baabc", "bbabc"};
    std::vector<std::string> t2 = {"baabababc", "baabc", "bbazc"};
    std::vector<std::string> t3 = 
        {"Sunday", "Monday", "Tuesday", "Wednesday", "Friday", "Saturday"};
    std::vector<std::string> t4 = {"longest", "common", "suffix"};
    std::vector<std::string> t5 = {""};
    std::vector<std::string> t6 = {};
    std::vector<std::string> t7 = {"foo", "foo", "foo", "foo"};

    std::vector<std::vector<std::string>> tests = {t1,t2,t3,t4,t5,t6,t7};
    
    for (auto t : tests) test(t);
    return 0;
}