Task: Alternade words

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

#define WORD_BUF_SIZE 30
#define MIN_WORD_SIZE 6


void fail(void) {
    fprintf(stderr, "%s\n", strerror(errno));
    exit(42);
}


struct trie_node {
    char ch, final;
    struct trie_node *parent, *sibling, *root, *child; 
};

struct trie_node *alloc_node() {
    struct trie_node *t = calloc(1, sizeof(struct trie_node));
    if (t == NULL) fail();
    return t;
}

struct trie_node *make_sibling(struct trie_node *node) {
    struct trie_node *t = alloc_node();
    node->sibling = t;
    t->ch = node->ch;
    t->parent = node->parent;
    t->root = node->root;
    return t;
}

struct trie_node *make_child(struct trie_node *node, char ch) {
    struct trie_node *t = alloc_node();
    t->parent = node;
    t->ch = ch;
    t->root = node->root;
    node->child = t;
    return t;
}


struct trie_node *add_word(struct trie_node *root, const char *word) {
    struct trie_node *cur = root;
    for (; *word; word++) {
        while (cur->child == NULL || cur->child->ch != *word) {
            if (cur->child == NULL) {
                
                make_child(cur, *word);
            } else {
                
                if (cur->sibling == NULL) make_sibling(cur);
                cur = cur->sibling;
            }
        }
        
        
        cur = cur->child;
    }
    cur->final = 1; 
    return cur;
}


struct trie_node *find_word(struct trie_node *root, const char *word) {
    struct trie_node *cur = root;
    for (; *word && cur; word++) {
        while (cur != NULL && cur->child != NULL && cur->child->ch != *word) {
            cur = cur->sibling;
        }
        if (cur == NULL) return NULL; 
        cur = cur->child;
    }
    if (cur && cur->final) return cur;
    else return NULL;
}


void scan_trie(struct trie_node *node, void callback(struct trie_node *)) {
    if (node == NULL) return;
    if (node->final) callback(node);
    scan_trie(node->child, callback);
    scan_trie(node->sibling, callback);
}


char *get_word(struct trie_node *node, char *buffer) {
    char t, *ch = buffer, *s = buffer;
    for (; node != NULL; node=node->parent) *ch++ = node->ch;
    for (ch-=2; ch >= s; ch--, s++) *ch ^= *s ^= *ch ^= *s;
    return buffer;
}


void check_alternade(struct trie_node *node) {
    static char word[WORD_BUF_SIZE], even[WORD_BUF_SIZE], odd[WORD_BUF_SIZE];
    char *p_even = even, *p_odd = odd;
    int i;
    
    
    if (strlen(get_word(node, word)) < MIN_WORD_SIZE) return;
    
    
    for (i=0; word[i]; i++) {
        if (i & 1) *p_odd++ = word[i];
        else *p_even++ = word[i];
    }
    *p_odd = *p_even = '\0';
        
    
    if (find_word(node->root, even) && find_word(node->root, odd)) {
        printf("%-20s%-10s%-10s\n", word, even, odd);
    }
}
          
int main(void) {
    struct trie_node *root = alloc_node();
    root->root = root;
    char word[WORD_BUF_SIZE], *nl;
    
    
    while (!feof(stdin)) {
        fgets(word, WORD_BUF_SIZE, stdin);
        if (nl = strchr(word, '\n')) *nl = '\0';  
        add_word(root, word);
    }
    
    
    scan_trie(root, check_alternade);
    return 0;
}





Java: import java.io.*;
import java.util.*;

public class AlternadeWords {
    public static void main(String[] args) {
        try {
            Set<String> dictionary = new TreeSet<>();
            try (BufferedReader reader = new BufferedReader(new FileReader("unixdict.txt"))) {
                String line;
                while ((line = reader.readLine()) != null)
                    dictionary.add(line);
            }
            StringBuilder word1 = new StringBuilder();
            StringBuilder word2 = new StringBuilder();
            for (String word : dictionary) {
                int length = word.length();
                if (length < 6)
                    continue;
                word1.setLength(0);
                word2.setLength(0);
                for (int i = 0; i < length; i += 2) {
                    word1.append(word.charAt(i));
                    if (i + 1 < length)
                        word2.append(word.charAt(i + 1));
                }
                String w1 = word1.toString();
                String w2 = word2.toString();
                if (dictionary.contains(w1) && dictionary.contains(w2))
                    System.out.printf("%-10s%-6s%s\n", word, w1, w2);
            }
        } catch (Exception e)  {
            e.printStackTrace();
        }
    }
}