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

#define MAXWORD 40
#define ALPHABET 26
#define N 50000

struct anagramword
{
    char word[MAXWORD];
    unsigned short histo[ALPHABET];
};

// prototype
void pp(struct anagramword *, int );
void func3(struct anagramword *, int, int);
int cmp(unsigned short *, unsigned short *, int );


void pp(struct anagramword *a, int n)
{
    int i;
    while (n--)
    {
        for ( i = 0; i < ALPHABET; ++i)
            printf("%d", a->histo[i]);
        printf("  word = %s\n", a->word);
        ++a;
    }
}

void func3(struct anagramword *a, int from, int to)
{
    int i;
    if (from == to)return;
    printf("The word \"%s\" %d anagrams : ", a[from].word, to - from);
    for ( i = from + 1; i <= to; ++i)
    {
        printf("%s, ", a[i].word);
    }
    putchar('\n');
}

int cmp(unsigned short *a, unsigned short *b, int n)
{

    // int i;
    // for ( i = 0; i < ALPHABET; ++i)
    //   printf("%d%d ", a[i], b[i]);
    // putchar('\n');

    while (n--)
    {
        // printf("a b = %d %d\n", *a,*b);
        if (*a < *b)
            return -1;
        if (*a > *b)
            return 1;
        ++a;
        ++b;
    }
    return 0;
}

int main(int argc, char const *argv[])
{
    char buf[100],c;
    struct   anagramword *data;
    struct   anagramword tmp;
    FILE *fp;
    int i, j, k, dataCount;

    data = (struct anagramword *)malloc(sizeof(struct anagramword) * N);

    // 1. argv[1]を使い、Textファイルから単語を読み込む
    // http://s...content-available-to-author-only...s.jp/~c_cpp_homework/cgi-bin/joyful/joyful.cgi?
    // にテキストファイル2つアップしました。本来は一つのファイルですが、容量制限の為、分割してます。

    // ヒストグラム(histo)をクリア
    for ( i = 0; i < N; ++i)
        for ( j = 0; j < ALPHABET; ++j)
            data[i].histo[j] = 0;

    fp = fopen(argv[1], "r");
    i = 0;
    while ((fgets(buf, 100, fp)) != NULL)
    {
        buf[strlen(buf) - 1] = '\0';

        // printf("%d %s\n", i, buf);

        // 2. 挿入ソートを使って、下記のような構造体に保管する
        // struct anagramword {
        // char word[MAXWORD];
        // unsigned short histo[ALPHABET];
        // };

        sprintf(data[i].word, "%s", buf);

        for ( j = 0; buf[j]; ++j)
        {
            c = tolower(buf[j]);
            if ((c >= 'a') && (c <= 'z'))
                data[i].histo[c - 'a']++;
        }

        for ( j = 0; j < i; ++j)
            if (cmp(data[j].histo, data[i].histo, ALPHABET) == 1)break;

        if (j < i)   /* swap & shift */
        {
            tmp = data[i];
            for ( k = i; k > j; --k)
                data[k] = data[k - 1];
            data[j] = tmp;
        }
        ++i;
    }
    dataCount = i;
    // printf("dataCount = %d\n", dataCount);

    // 3. データをもとにアナグラムとその数を記したリストをtxtに出力
    // 例)
    // The word "ATM" 4 anagrams : ATM’s mast mat’s mats
    // The word "evkl" 4 anagrams : evil, live, veil, vile
    // …

    // pp(data, dataCount);

    int max = 0, maxi;
    {
        int    from = 0;
        for ( i = 0; i < dataCount - 1; ++i)
        {
            if (cmp(data[i].histo, data[i + 1].histo, ALPHABET) == 0)
            {
                continue;
            }
            func3(data, from, i);
            if (max < i - from)
            {
                max = i - from;
                maxi = from;
            }
            from = i + 1;
        }
        func3(data, from, i);
        if (max < i - from)
        {
            max = i - from;
            maxi = from;
        }
    }

    // 4.最大値を持ったアナグラムとその最大値を出力
    printf("最大値を持ったアナグラム = %s, 最大値 = %d\n" , data[ maxi].word   , max);

    return 0;
}
