2
\$\begingroup\$

I was writing a simple function that would return the Fibonacci sequence up to the nth term and for whatever reason started wasting a lot of time on it. Here's what I came up with:

static IEnumerable<int> Fibonacci(int n)
{
    int last = 0, 
        oneBefore = 0;

    if (n > 0) yield return oneBefore = 0;
    if (n > 1) yield return last = 1;
    if (n > 2)
    {
        while (n-- - 2 > 0)
        {
            yield return last = oneBefore + (oneBefore = last);
        }
    }
}

This is pretty close to what I want, but it has those three ugly if branches at the top level. Initially, I was trying to do something like this for the 0 and 1 case:

yield return (new[] { 0, 1 }).Take(n);

So that it would nicely handle cases where n was 0, 1 or greater. Unfortunately C# doesn't allow mixing of returning complete enumerables with yield statements, so that didn't work.

So here are my questions for what I want to improve:

  • Is there a way I can avoid the if branches there and somehow elegantly and concisely deal with both degenerate cases?
  • Is there a way I can avoid having that variable initialization statement at the beginning of the function, or even better, avoid having to keep the two variables at all?
\$\endgroup\$
5
\$\begingroup\$

Consider breaking it up into two methods: one, Fibonacci(), that represents the infinite* Fibonacci sequence, and another, Fibonacci(int), that just returns Fibonacci().Take(n). This removes the branching.

An implementation might look like this:

static IEnumerable<int> Fibonacci(int n)
{
    return Fibonacci().Take(n);
}

static IEnumerable<int> Fibonacci()
{
    int a = 0;
    int b = 1;
    while (true)
    {
        yield return a;
        int c = a + b;
        a = b;
        b = c;
    }
}

* Well, the first 47 values that fit in an int.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.