Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring Fibonacci Algorithm

Tags:

c#

refactoring

I haven't used a statically typed language in many years and have set myself the task of getting up to speed with C#. I'm using my usual trick of following the fifteen exercises here http://www.jobsnake.com/seek/articles/index.cgi?openarticle&8533 as my first task.

I've just finished the second Fibonacci task which didn't take to long and works just fine but in my opinion looks ugly and I'm sure could be achieved in far fewer lines of more elegant code.

I usually like to learn by pair programming with someone who already knows what they're doing, but that option isn't open to me today, so I'm hoping posting here will be the next best thing.

So to all the C# Jedi's out there, if you were going to refactor 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("");
        }

    }
}

Regards,

Chris

like image 301
ChrisInCambo Avatar asked Jan 02 '09 10:01

ChrisInCambo


People also ask

What is the algorithm for Fibonacci?

How to Generate Fibonacci Series? The Fibonacci numbers upto certain term can be represented as: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144….. or 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…. Eighth Term = Sixth + Seventh = 5+8 = 13 … and so on to infinity!

How do you speed up Fibonacci?

Summary: The two fast Fibonacci algorithms are matrix exponentiation and fast doubling, each having an asymptotic complexity of Θ(logn) bigint arithmetic operations. Both algorithms use multiplication, so they become even faster when Karatsuba multiplication is used.

How do you calculate Fibonacci numbers without recursion or iteration?

The logic of calculating nth Fibonacci number is implemented in this method and it does that without using recursion. It uses a simple for loop to iterate until the nth number and calculate Fibonacci number using the following formula : f(n) = f(n-1) + f(n-2);

How do you check whether a number is Fibonacci or not in JavaScript?

A number is Fibonacci if and only if one or both of (5*n2 + 4) or (5*n2 – 4) is a perfect square (Source: Wiki).


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

This is now fully lazy, and using LINQ's Skip/Take etc allows you to control the start/end easily. For example, for your "between" query:

foreach (long i in Fibonacci().SkipWhile(x=>x < from).TakeWhile(x=>x <= to)) {...}
like image 115
Marc Gravell Avatar answered Oct 31 '22 01:10

Marc Gravell


If you prefer recursion instead of the 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);
    }
}
like image 27
Paco Avatar answered Oct 31 '22 02:10

Paco


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

like image 23
Codingday Avatar answered Oct 31 '22 02:10

Codingday