예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }