private List <WordEquivalencyClassComposition> Recursive( WordEquivalencyClassComposition currentWord, string anagramCharPool, IList <WordEquivalencyClass> equivalencyClasses, Memo memo, int level) { var newCandidates = new List <WordEquivalencyClassComposition>(); foreach (var equivalencyClass in equivalencyClasses) { var newPartialPhraseComposition = new WordEquivalencyClassComposition(currentWord, new WordEquivalencyClass(equivalencyClass.CharPool, equivalencyClass.Words)); var remainder = anagramCharPool.SubtractChars(newPartialPhraseComposition.CharPool.Alphabetize()); // not a fit if (remainder == null) { newPartialPhraseComposition.IsDeadend = true; if (!memo.ContainsKey(newPartialPhraseComposition.CharPool)) { memo.AddDeadEnd(newPartialPhraseComposition); } continue; } // a fit if (remainder.Length == 0) { newPartialPhraseComposition.IsDeadend = false; memo.AddSolution(newPartialPhraseComposition); newCandidates.Add(newPartialPhraseComposition); continue; } // inconclusive if (remainder.Length > 0) { newPartialPhraseComposition.IsDeadend = false; // check new word against memo if (memo.ContainsKey(newPartialPhraseComposition.CharPool)) { //we have been here before... var val = memo[newPartialPhraseComposition.CharPool]; if (val == null) { //its a dead end! continue; } else { if (val.IsDeadend == false) { memo.GenerateAndAddFullSolution_FromIncomplete(newPartialPhraseComposition); continue; } else { throw new ArgumentException("I should not be here again!"); } } } var countBeforeRecursion = memo.SolutionCount; var candidates = Recursive(newPartialPhraseComposition, anagramCharPool, equivalencyClasses, memo, level + 1); var countAfterRecursion = memo.SolutionCount; if (countBeforeRecursion == countAfterRecursion) { newPartialPhraseComposition.IsDeadend = true; memo.AddDeadEnd(newPartialPhraseComposition); } else { newPartialPhraseComposition.IsDeadend = false; memo.AddSolvable(newPartialPhraseComposition); newCandidates.AddRange(candidates); } continue; } } return(newCandidates); }