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

#define WORD_SIZE (32   + 1)
#define TEXT_SIZE (1000 + 1)
#define SUCCESS   (0)
#define FAILURE   (-1)

typedef struct tagNode
{
    char word[WORD_SIZE];
    unsigned int wordFrequencyCnt;
    struct tagNode *next;
}Node;

typedef struct tagLinkedList
{
    Node *head;
    Node *tail;
}LinkedList;

void InitializeList(LinkedList *pList);
void FreeList(LinkedList *pList);
int InputTextInList(LinkedList *pList);
void AddHead(LinkedList *pList, char* pStr);
int CheckDuplication(LinkedList *pList, char* pStr, Node **pNode);
int GetMostFrequently(LinkedList *pList, char *pStr);
int GetMaxLengthWord(LinkedList *pList, char *pStr);

LinkedList gLinkedList;

int main(void)
{
    char mostFrequentlyWord[WORD_SIZE];
    char maxLengthWord[WORD_SIZE];
    
    InitializeList(&gLinkedList);
    
    if(InputTextInList(&gLinkedList) == FAILURE)
    {
        return FAILURE;
    }

    if((GetMostFrequently(&gLinkedList, &mostFrequentlyWord[0]) == FAILURE) ||
    (GetMaxLengthWord(&gLinkedList, &maxLengthWord[0]) == FAILURE))
    {
        return FAILURE;
    }
    printf("%s %s\n", &mostFrequentlyWord[0], &maxLengthWord[0]);
    
    FreeList(&gLinkedList);
    
    return SUCCESS;
}


void InitializeList(LinkedList *pList)
{
    pList->head = NULL;
    pList->tail = NULL;
    
    return;
}


void FreeList(LinkedList *pList)
{
    Node *current = pList->head;
    Node *next;
    while (current != NULL) 
    {
        next = current->next;
        free(current);
        current = next;
    }
    
    return;
}


int InputTextInList(LinkedList *pList)
{
    char str[WORD_SIZE];
    char ch;
    unsigned int textSizeCnt = 0;
    unsigned int wordSizeCnt = 0;
    
    while(1)
    {
        if(textSizeCnt >= TEXT_SIZE)
        {
            return FAILURE;
        }
        
        ch = getchar();
        textSizeCnt++;
        if((ch == ' ') || (ch == '\n'))
        {
            if(wordSizeCnt >= WORD_SIZE)
            {
                return FAILURE;
            }
            
            str[wordSizeCnt] = '\0';
            wordSizeCnt = 0;
            AddHead(pList, str);
            if(ch == '\n')
            {
                break;
            }                
        }
        else
        {
            str[wordSizeCnt] = ch;
            wordSizeCnt++;
        }
    }
    
    return SUCCESS;
}


void AddHead(LinkedList *pList, char* pStr)
{
    Node *node;
    Node *pTarget = NULL;
    
    CheckDuplication(pList, pStr, &pTarget);
    if(pTarget != NULL)
    {
        pTarget->wordFrequencyCnt++;
        return;
    }
    
    node = (Node*)malloc(sizeof(Node));
    strcpy(&node->word[0], pStr);
    node->wordFrequencyCnt = 1;
    
    
    if (pList->head == NULL) 
    {
        pList->tail = node;
        node->next = NULL;
    }
    else 
    {
        node->next = pList->head;
    }
    
    pList->head = node;
    
    return;
}


int CheckDuplication(LinkedList *pList, char* pStr, Node **pNode)
{
    Node *current = pList->head;
    while (current != NULL) 
    {
        if(strcmp(current->word, pStr) == 0)
        {
            *pNode = current;
            return SUCCESS;
        }
        current = current->next;
    }
    
    return FAILURE;
}


int GetMostFrequently(LinkedList *pList, char *pStr)
{
    Node *current = pList->head;
    unsigned max = 0;
    int rslt = FAILURE;
    
    while (current != NULL) 
    {
        if(current->wordFrequencyCnt > max)
        {
            max = current->wordFrequencyCnt;
            strcpy(pStr, current->word);
            rslt = SUCCESS;
        }
        current = current->next;
    }
    
    return rslt;
}


int GetMaxLengthWord(LinkedList *pList, char *pStr)
{
    Node *current = pList->head;
    unsigned max = 0;
    unsigned int len;
    int rslt = FAILURE;
    
    while (current != NULL) 
    {
        len = strlen(current->word);
        if(len > max)
        {
            max = len;
            strcpy(pStr, current->word);
            rslt = SUCCESS;
        }
        current = current->next;
    }
    
    return rslt;
}

Measured memory_bytes: 1756