Task: Anagrams_Deranged anagrams

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>


const char *freq = "zqxjkvbpygfwmucldrhsnioate";
int char_to_idx[128];


struct word {
	const char *w;
	struct word *next;
};

union node {
	union node *down[10];
	struct word *list[10];
};

int deranged(const char *s1, const char *s2)
{
	int i;
	for (i = 0; s1[i]; i++)
		if (s1[i] == s2[i]) return 0;
	return 1;
}

int count_letters(const char *s, unsigned char *c)
{
	int i, len;
	memset(c, 0, 26);
	for (len = i = 0; s[i]; i++) {
		if (s[i] < 'a' || s[i] > 'z')
			return 0;
		len++, c[char_to_idx[(unsigned char)s[i]]]++;
	}
	return len;
}

const char * insert(union node *root, const char *s, unsigned char *cnt)
{
	int i;
	union node *n;
	struct word *v, *w = 0;

	for (i = 0; i < 25; i++, root = n) {
		if (!(n = root->down[cnt[i]]))
			root->down[cnt[i]] = n = calloc(1, sizeof(union node));
	}

	w = malloc(sizeof(struct word));
	w->w = s;
	w->next = root->list[cnt[25]];
	root->list[cnt[25]] = w;

	for (v = w->next; v; v = v->next) {
		if (deranged(w->w, v->w))
			return v->w;
	}
	return 0;
}

int main(int c, char **v)
{
	int i, j = 0;
	char *words;
	struct stat st;

	int fd = open(c < 2 ? "unixdict.txt" : v[1], O_RDONLY);
	if (fstat(fd, &st) < 0) return 1;

	words = malloc(st.st_size);
	read(fd, words, st.st_size);
	close(fd);

	union node root = {{0}};
	unsigned char cnt[26];
	int best_len = 0;
	const char *b1, *b2;

	for (i = 0; freq[i]; i++)
		char_to_idx[(unsigned char)freq[i]] = i;

	
	for (i = j = 0; i < st.st_size; i++) {
		if (words[i] != '\n') continue;
		words[i] = '\0';

		if (i - j > best_len) {
			count_letters(words + j, cnt);
			const char *match = insert(&root, words + j, cnt);

			if (match) {
				best_len = i - j;
				b1 = words + j;
				b2 = match;
			}
		}

		j = ++i;
	}

	if (best_len) printf("longest derangement: %s %s\n", b1, b2);

	return 0;
}











Ada: with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Generic_Array_Sort;
with Ada.Containers.Indefinite_Vectors;
procedure Danagrams is
   package StringVector is new Ada.Containers.Indefinite_Vectors
      (Positive, String);
   procedure StrSort is new Ada.Containers.Generic_Array_Sort
      (Index_Type => Positive,
      Element_Type => Character,
      Array_Type => String);
   function Derange (s1 : String; s2 : String) return Boolean is begin
      for i in s1'Range loop
         if (s1 (i) = s2 (i)) then return False; end if;
      end loop;
      return True;
   end Derange;
   File : File_Type;
   len, foundlen : Positive := 1;
   Vect, SVect : StringVector.Vector;
   index, p1, p2 : StringVector.Extended_Index := 0;
begin
   Open (File, In_File, "unixdict.txt");
   while not End_Of_File (File) loop
      declare str : String := Get_Line (File);
      begin
         len := str'Length;
         if len > foundlen then
            Vect.Append (str);
            StrSort (str);
            index := 0;
            loop 
               index := SVect.Find_Index (str, index + 1);
               exit when index = StringVector.No_Index;
               if Derange (Vect.Last_Element, Vect.Element (index)) then
                     p1 := Vect.Last_Index; p2 := index;
                     foundlen := len;
               end if;
            end loop;
            SVect.Append (str);
         end if;
      end;
   end loop;
   Close (File);
   Put_Line (Vect.Element (p1) & " " & Vect.Element (p2));
end Danagrams;