示例#1
0
 private bool DoneEnumeratingSummedExpansionPaths(ExpansionTermStack stack)
 {
     //If there's only one item left on the stack, we're back at the starting point
     //(or the starting point is in the top row, and we never moved anywhere).
     //Either way, we are therefore done.
     return(stack.Count <= 1);
 }
示例#2
0
        public IEnumerable <Expansion> EnumerateExpansionPaths(ExpansionTerm pathStartingPoint, bool capToMaximum)
        {
            if (!this.Contains(pathStartingPoint))
            {
                throw new ArgumentException(
                          "The " + nameof(TermOptionsMatrix) + " '" + this + "' "
                          + "does not contain provided " + nameof(pathStartingPoint) + " '" + pathStartingPoint + "'."
                          );
            }

            var stack = new ExpansionTermStack();

            stack.Push(pathStartingPoint);

            //To start with, keep moving up, adding each element to the stack, until the top row is reached
            while (stack.Peek().ThreeExponent > 0)
            {
                var termAbove = stack.Peek().StepBy(threeExpStep: -1, twoExpStep: 0);
                stack.Push(termAbove);
            }

            //Then check if that resulted in a path that isn't too big
            if (!capToMaximum || stack.Sum <= this.Maximum)
            {
                yield return(new Expansion(stack.ToList().AsReadOnly()));
            }
            else
            {
                yield break;                 //The stack currently holds the lowest possible path; if that doesn't fit in Maximum, no paths will
            }

            while (true)
            {
                if (DoneEnumeratingExpansionPaths(stack))
                {
                    yield break;
                }

                ExpansionTerm termToRight;
                if (this.TryGetNextInRow(stack.Peek(), out termToRight) && (!capToMaximum || stack.SumWithAlternateHead(termToRight) <= this.Maximum))
                {
                    stack.Pop();
                    stack.Push(termToRight);

                    if (capToMaximum && stack.SumWithoutHead + MinimumPathSum(stack.Peek()) > this.Maximum)
                    {
                        //If true, the shortest path from the current position is too big. As moving to the right always
                        //results in a higher term, all other paths from the current position, and from all positions to the right
                        //of the current one, will also be too big. This is only true given the *current* path stored in the stack,
                        //so to try different paths, pop() to move back down (and probably to the left) by one, and then loop around
                        //to try moving to the right from there
                        stack.Pop();
                        continue;
                    }
                    else
                    {
                        //The first route, which goes straight to the top, is the path with the minimum
                        //sum, which we've already checked is be less than this.Maximum, so take that route
                        while (stack.Peek().ThreeExponent > 0)
                        {
                            stack.Push(stack.Peek().StepBy(threeExpStep: -1, twoExpStep: 0));
                        }

                        //	Console.WriteLine("#12: " + stack.Peek() + ", " + stack.SumWithoutHead + ", " + MinimumPathSum(stack.Peek()));
                        yield return(new Expansion(stack.ToList().AsReadOnly()));

                        //Now loop around again to try moving to the right
                        continue;
                    }
                }
                else
                {
                    //Can't move to the right, so move back down by one instead & loop around to try again
                    stack.Pop();
                    continue;
                }
            }
        }