public bool FindAnagram(string anagramHash, string inputPhrase, WordTree wordTree, CharNode currentNode, string anagram, int levels) { string anagramSoFar = anagram; string remainingInputPhrase = inputPhrase; // See if we can use the character var charIndex = inputPhrase.IndexOf(currentNode.Value); if (charIndex != -1) { anagramSoFar += currentNode.Value; remainingInputPhrase = inputPhrase.Remove(charIndex, 1); } else if (currentNode != wordTree.Root) { // oops this character doesn't exist in phrase, no point in going further to children return(false); } // We have covered every character of input phrase if (remainingInputPhrase.Length == 0) { // And we have reached the rabit hole depth, and this current node represents a word if (levels == RabitHoleDepth && currentNode.IsWord) { Console.Write("\rScanning anagrams: {0} ", anagramSoFar); var computeHash = CreateMD5(anagramSoFar); // See if this is it, if found lets roll if (computeHash.Equals(anagramHash)) { Console.WriteLine("matches the hash !!!"); this.SaveMessage(anagramHash, anagramSoFar); return(true); } } // keep looking return(false); } // Continue looking in children foreach (CharNode childNode in currentNode.Children) { if (FindAnagram(anagramHash, remainingInputPhrase, wordTree, childNode, anagramSoFar, levels)) { return(true); } } // We have a word, lets start over from the root if (currentNode.IsWord && levels < RabitHoleDepth) { if (FindAnagram(anagramHash, remainingInputPhrase, wordTree, wordTree.Root, anagramSoFar + " ", ++levels)) { return(true); } } return(false); }
/** * Finds an anagram matching the anagramHash using myDictionary */ public bool FindAnagrams(string anagramHash, string[] myDictionary, bool tryHarder = false) { string input = OriginalPhrase; // no. of spaces in input RabitHoleDepth = input.Count(c => c.Equals(' ')); if (tryHarder) { RabitHoleDepth++; } Console.WriteLine("Rabbit hole goes {0} level deep!!", RabitHoleDepth); char[] inputChars = input.Replace(" ", String.Empty).Distinct().OrderBy(c => c).ToArray(); // Lets get the count of all the input characters int[] charCounts = new int[inputChars.Length]; for (var k = 0; k < inputChars.Length; k++) { charCounts[k] = (byte)input.Count(c => c.Equals(inputChars[k])); } // Lets get all the valid remaining words var remainingWords = myDictionary.Where(s => { if (s.Except(inputChars).Any()) { return(false); } int l = 0; foreach (char ch in inputChars) { if (s.Count(c => c.Equals(ch)) > charCounts[l]) { return(false); } l++; } return(true); }).Distinct(); string anagram = String.Empty; // Compile the word list into word tree for faster traversal WordTree wt = new WordTree(); foreach (string word in remainingWords) { wt.CompileWord(word); } int levels = 0; return(FindAnagram(anagramHash, input.Replace(" ", String.Empty), wt, wt.Root, anagram, levels)); }