Fibonacci Algorithm Refactoring

I have not used a statically typed language for many years and set myself the task of speeding up work with C #. I am using my regular trick after fifteen exercises here http://www.jobsnake.com/seek/articles/index.cgi?openarticle&8533 as my first task.

I just finished the second Fibonacci task, which didn’t take much time and works great, but, in my opinion, looks ugly, and I’m sure that it could be achieved in a much smaller number of lines of more elegant code.

I usually like to learn pair programming with someone who already knows what they are doing, but this option is not open to me today, so I hope the publication will be the next best one.

So, for all C # Jedi, if you are going to reorganize the code below, what would it look like?

using System; using System.Collections; namespace Exercises { class MainClass { public static void Main(string[] args) { Console.WriteLine("Find all fibinacci numbers between:"); int from = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("And:"); int to = Convert.ToInt32(Console.ReadLine()); Fibonacci fibonacci = new Fibonacci(); fibonacci.PrintArrayList(fibonacci.Between(from, to)); } } class Fibonacci { public ArrayList Between(int from, int to) { int last = 1; int penultimate = 0; ArrayList results = new ArrayList(); results.Add(penultimate); results.Add(last); while(last<to) { int fib = last + penultimate; penultimate = last; last = fib; if (fib>from && fib<to) results.Add(fib.ToString()); } return results; } public void PrintArrayList(ArrayList arrayList) { Console.WriteLine("Your Fibonacci sequence:"); Console.Write(arrayList[0]); for(int i = 1; i<arrayList.Count; i++) { Console.Write("," + arrayList[i]); } Console.WriteLine(""); } } } 

Hello,

Chris

+9
c # refactoring
Jan 02 '09 at 10:19
source share
4 answers

As an iterator block:

 using System; using System.Collections.Generic; using System.Linq; static class Program { static IEnumerable<long> Fibonacci() { long n = 0, m = 1; yield return 0; yield return 1; while (true) { long tmp = n + m; n = m; m = tmp; yield return m; } } static void Main() { foreach (long i in Fibonacci().Take(10)) { Console.WriteLine(i); } } } 

Now this is completely lazy, and using LINQ Skip / Take , etc. makes it easy to easily manage startup and shutdown. For example, for your request between:

 foreach (long i in Fibonacci().SkipWhile(x=>x < from).TakeWhile(x=>x <= to)) {...} 
+45
Jan 02 '09 at 10:21
source share

If you prefer recursion over loop:

 public static void Main(string[] args) { Func<int, int> fib = null; fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n; int start = 1; int end = 10; var numbers = Enumerable.Range(start, end).Select(fib); foreach (var number in numbers) { Console.WriteLine(number); } } 
+4
Jan 02 '09 at 11:46
source share

I would change the type of IEnumerable<int> to IEnumerable<Int64> , as it will start to overflow from 50

+2
Jan 2 '09 at 11:49
source share

For those who have not succumbed to Linq-ed, like me, the "Simple Jack" Version. I'm so banned from the Jedi Club;)

 static List<int> GetAllFibonacciNumbersUpto(int y) { List<int> theFibonacciSeq = new List<int>(); theFibonacciSeq.Add(0); theFibonacciSeq.Add(1); int F_of_n_minus_2 = 0; int F_of_n_minus_1 = 1; while (F_of_n_minus_2 <= y) { theFibonacciSeq.Add(F_of_n_minus_1 + F_of_n_minus_2); F_of_n_minus_2 = F_of_n_minus_1; F_of_n_minus_1 = theFibonacciSeq.Last<int>(); } return theFibonacciSeq; } 

now that we have it aside ...

 // read in some limits int x = 0; int y = 6785; foreach (int iNumber in GetAllFibonacciNumbersUpto(y).FindAll(element => (element >= x) && (element <= y))) Console.Write(iNumber + ","); Console.WriteLine(); 
-one
Jan 02 '09 at 11:42
source share



All Articles