2

I am having trouble with somwhow implementing a partial recursive function (at least in my mind though).

for any given p and arbitrary maxsteps = 100, calculate L:

enter image description here

12
  • 4
    How do you know when to stop? Is the function always like this, with that exact number of levels? Commented May 27, 2019 at 8:33
  • Updated the question, there is a maxsteps parameter also. Commented May 27, 2019 at 8:34
  • 2
    What is the maxsteps value for the given example? Commented May 27, 2019 at 8:34
  • 1
    Using recursion you may hit arbitrary limits imposed by the OS (StackOverflowException). Without recursion the limits are only the precision of the numeric type (double) Commented May 27, 2019 at 8:40
  • 3
    Basically, I'm wondering if maxsteps == 1 would return 1 / (p+1) or 1 / (p + 1 / (p + 1)). Commented May 27, 2019 at 8:43

3 Answers 3

7

You could pass the maxsteps down to the recursive function and subtract 1 on each step until you reach 0, with is the end condition:

public double L(double p, int maxSteps)
{
    if (maxSteps == 0)
    {
        return 1 / (p + 1);
    }
    return 1 / (p + L(p, maxSteps - 1));
}
Sign up to request clarification or add additional context in comments.

Comments

4

I appreciate you want a recursive function, but I figured I'd provide a non-recursive alternative in case it turns out to be preferred:

private static double CalculateL(double p, int maxsteps)
{
    double val = 1 / (p + 1);
    for (int i = 1; i <= maxsteps; ++i)
    {
        val = 1 / (p + val);
    }
    return val;
}

I'm not 100% sure about maxsteps, based on the other answers. If the answer isn't right, then you probably want < maxsteps where I've got <= maxsteps.

Also, please read Is floating point math broken? if you're expecting very precise results.

9 Comments

I'd certainly go with this approach as I don't think this problem needs recursion at all (why to give hard time to stack)
You could also wrap expression into (local) function.
@Lasse Oops, yes. You're right. I've corrected it to match the others.
Well, for all we know, your result was the right one.
You may be right, but in that case I would say that the right approach would probably be to specify an epsilon limit instead, instructing the algorithm to stop when the change to the value is less than some predefined small limit, instead of specifying exactly how many steps to run it. But yes, if you provide a sufficiently high number, +/- 1 step won't matter (that much).
|
2

There I left you the code for the recursive approach:

class Program
{
    static void Main(string[] args)
    {
        double recursiveL = CalculateL(100, 100);
        double notRecursiveLWrong = NotRecursiveCalculateLWrong(100, 100);
        double notRecursiveLRight = NotRecursiveCalculateLRight(100, 100);
    }

    private static double CalculateL(double p, int maxSteps)
    {
        if (maxSteps == 0)
        {
            return (1 / (p + 1));
        }
        else
        {
            return (1 / (p + CalculateL(p, maxSteps - 1)));
        }
    }

    private static double NotRecursiveCalculateLWrong(double p, int maxSteps)
    {
        double result = 0;
        for (int i = 0; i < maxSteps; i++)
        {
            result = (1 / (p + result));
        }
        return result;
    }


    private static double NotRecursiveCalculateLRight(double p, int maxSteps)
    {
        double result = 1 / (p + 1);
        for (int i = 0; i < maxSteps; i++)
        {
            result = (1 / (p + result));
        }
        return result;
    }
}

While making it I was thinking about the fact that for this problem, recursion isn't needed and now I can see that I'm not the only one.

I added my not recursive approach.


Edit:

If you try my code you will see that every method returns the same value, WATCHOUT, this is cause of the low precision in floating points.

The correct approach is NotRecursiveCalculateLRight which is stated in @John 's answer.

3 Comments

How is this different from this answer?
I made it while he posted his answer. Anyway I added another solution.
@MarcoSalerno Well you added another solution which is also provided already. This post contains two answers which are both already proposed. This answer does not add anything and should be removed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.