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); }
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; } } }