using System.Collections.Generic;
public static void Main()
foreach (string[] anagramArray in MyLittleAnagramerV4.FindAnagrams("top", "read", "act", "dear", "spot", "cat", "dare", "stop"))
Console.WriteLine(string.Join(", ", anagramArray));
public class MyLittleAnagramerV4
public static IEnumerable<IEnumerable<string>> FindAnagrams(params string[] words)
var cache = new List<HashSet<char>>();
foreach (var word in words)
var set = new HashSet<char>(word.ToLower());
var results = new List<IEnumerable<string>>(words.Length / 2);
int processedWordIndexes = 0;
for (int wordIndex = 0; wordIndex < words.Length; wordIndex++)
if ((processedWordIndexes & (1 << wordIndex)) != 0)
var word = cache[wordIndex];
processedWordIndexes |= 1 << wordIndex;
var wordAnagramIndexes = 0;
var wordAnagramCount = 0;
for (int wordToCompareIndex = wordIndex; wordToCompareIndex < words.Length; wordToCompareIndex++)
var wordToCompare = cache[wordToCompareIndex];
if (IsAnagram(word, wordToCompare))
wordAnagramIndexes |= 1 << wordToCompareIndex;
if (wordIndex != wordToCompareIndex)
processedWordIndexes |= 1 << wordToCompareIndex;
var wordAnagrams = new string[wordAnagramCount];
for (int wordAnagramIndex = 0, count = 0; count < wordAnagramCount && wordAnagramIndex < int.MaxValue; wordAnagramIndex++)
if ((wordAnagramIndexes & (1 << wordAnagramIndex)) != 0)
wordAnagrams[count] = words[wordAnagramIndex];
results.Add(wordAnagrams);
public static bool IsAnagram(HashSet<char> left, HashSet<char> right)
if(left.Count != right.Count)
foreach(var @char in left)
if(!right.Contains(@char))