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

#define MAXWORDLEN 30
#define MAXWORDS   1000000

struct line {
     char word[MAXWORDLEN];
     char sorted[MAXWORDLEN];
     int length;
};

struct pair {
     char first[MAXWORDLEN];
     char second[MAXWORDLEN];
     int length;
};

int comp_chars(const void *a, const void *b);
int comp_sorted(const void *a, const void *b);
int comp_len(const void *a, const void *b);

int main(int argc, char *argv[])
{
     /* Check correct no of arguments */
     if (argc != 2 && argc != 3) {
          printf("Usage: uniq_anag words_list number_of_pairs\n");
          printf("If no number given, default is one.\n");
          return -1;
     }

     /* Declarations */
     FILE *wordlist;
     struct line *lines = calloc(MAXWORDS, sizeof(struct line));
     int i, j;
     char c;
     int no_of_words;
     int no_to_return = (argc == 2 ? 1 : atoi(argv[2]));
     struct pair *pairs = calloc(MAXWORDS, sizeof(struct pair));
     
     /* Open the file */
     wordlist = fopen(argv[1], "r");
     /* Get the words */
     i = j = 0;
     while ((c = getc(wordlist)) != EOF) {
          if (c != '\n') {
               lines[i].word[j] = c;
               lines[i].sorted[j  ] = c;
          }
          else {
               j = 0;
                 i;
          }
     }
     no_of_words = i;

     /* Order the letters in the second copy */
     for (i = 0; i < no_of_words;   i) {
          lines[i].length = strlen(lines[i].word);
          qsort(lines[i].sorted, lines[i].length, sizeof(char), comp_chars);
     }

     /* Sort the lines by the sorted words */
     qsort(lines, no_of_words, sizeof(struct line), comp_sorted);

     /* Look for pairs */
     char to_comp[2][MAXWORDLEN];
     strcpy(to_comp[0], lines[0].sorted);
     int matches = 0;
     j = 0;
     for (i = 1; i < no_of_words;   i) {
          strcpy(to_comp[i%2], lines[i].sorted);
          if (strcmp(to_comp[0],to_comp[1]) == 0)
               matches  ;
          else {
               if (matches == 1) {
                    strcpy(pairs[j].first, lines[i-2].word);
                    strcpy(pairs[j].second, lines[i-1].word);
                    pairs[j  ].length = lines[i-1].length;
               }
               matches = 0;
          }
     }
     int no_of_pairs = j;
     
     /* Sort the pairs we've found */
     qsort(pairs, no_of_pairs, sizeof(struct pair), comp_len);
     
     /* Print results */
     for (i = 0; i < no_to_return; i  ) {
          if (pairs[i].length == 0)
               break;
          printf("%s %s\n", pairs[i].first, pairs[i].second);
     }

     /* Clean up */
     free((void *)lines);
     fclose(wordlist);
     return 0;
}

int comp_chars(const void *a, const void *b)
{
     if (*(char*)a < *(char*)b)
          return -1;
     else if (*(char*)a == *(char*)b)
          return 0;
     else
          return 1;
}

int comp_sorted(const void *a, const void *b)
{
     char sorted[2][MAXWORDLEN];
     strcpy(sorted[0],(*(struct line *)a).sorted);
     strcpy(sorted[1],(*(struct line *)b).sorted);
     return strcmp(sorted[0],sorted[1]);
}

int comp_len(const void *a, const void *b)
{
     int lengths[2];
     lengths[0] = (*(struct pair *)a).length;
     lengths[1] = (*(struct pair *)b).length;
     if (lengths[0] < lengths[1])
          return 1;
     else if (lengths[0] == lengths[1])
          return 0;
     else
          return -1;
}