public static long Problem15(int n, int m, Dictionary <string, long> Memo) { if (Memo == null) { Memo = new Dictionary <string, long>(); } if (m == 1 || n == 1) { return(1); } string Key = $"{m},{n}"; if (Memo.ContainsKey(Key)) { return(Memo[Key]); } else { long Result = Problem15(m - 1, n, Memo) + Problem15(m, n - 1, Memo); Memo[Key] = Result; return(Result); } }
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); }