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?
1 Answer 1
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
.
Explore related questions
See similar questions with these tags.