I'm following up on this question. I made a few decisions about my model and implemented recommendations accordingly.
TL;DR the link
Uses a loop algorithm to return a Fibonacci number \$Fn\$ of any given ordinal position \$n\$.
Changes
- I'm now using a
BigInteger
type to avoid Integer Overflow. I can now return an arbitrarily large Fibonacci number. - Clarified private variable names.
Calculate
is now an internal method. Setting the OrdinalPosition recalculates the value automatically, so the client code is no longer responsible for syncing the object.- I added a more complete console implementation.
Questions
- Would this class benefit at all by actually inheriting from
BigInteger
? - Are the names better? They really stunk in my last version.
- Tear it apart. I can take it. No beginner tag on this one.
Fibonacci
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
namespace Challenges
{
class Fibonacci
{
private int ordinalPosition;
public int OrdinalPosition
{
get { return ordinalPosition; }
set
{
ordinalPosition = value;
Calculate();
}
}
public BigInteger Value { get; private set; }
private void Calculate()
{
if (this.OrdinalPosition <= 0)
{
throw new ArgumentOutOfRangeException("OrdinalPosition","Can't calculate Fn when n is less than or equal to zero.");
}
else if (this.OrdinalPosition == 1 || this.OrdinalPosition == 2)
{
this.Value = 1;
}
else
{
//initialize previous results
BigInteger previous1 = 1;
BigInteger previous2 = 1;
for (int i = 0; i < (this.OrdinalPosition - 2); i ++ )
{
this.Value = previous1 + previous2;
previous2 = previous1;
previous1 = this.Value;
}
}
}
//constructors
public Fibonacci(int n)
{
this.OrdinalPosition = n;
}
public Fibonacci(){}
}
}
Console Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
namespace Challenges
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("How many Fibbonacci numbers should I print?");
int input;
if (int.TryParse(Console.ReadLine(),out input))
{
WriteOkMesage();
WriteLotsOfFibbonacci(input);
}
else
{
WriteNotAnIntegerMessage();
}
Console.WriteLine(Environment.NewLine + "Let's just pick one at random.");
Console.WriteLine("What nth number Fibbonacci would you like?");
if (int.TryParse(Console.ReadLine(),out input))
{
WriteOkMesage();
WriteAFibbonacci(input);
}
else
{
WriteNotAnIntegerMessage();
}
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
static private void WriteAFibbonacci(int n)
{
try
{
Fibonacci fib = new Fibonacci(n);
Console.WriteLine("The answer is: " + fib.Value);
}
catch(ArgumentOutOfRangeException e)
{
WriteErrorMessage(e);
}
}
static private void WriteLotsOfFibbonacci(int numberToPrint)
{
Fibonacci fib = new Fibonacci();
try
{
for (int i = 1; i <= numberToPrint; i++)
{
fib.OrdinalPosition = i;
Console.WriteLine(fib.Value);
}
}
catch (ArgumentOutOfRangeException e)
{
WriteErrorMessage(e);
}
}
static private void WriteOkMesage()
{
Console.WriteLine("Okay!" + Environment.NewLine);
}
static private void WriteErrorMessage(Exception e)
{
Console.WriteLine(e.Source + " " + e.Message);
}
static private void WriteNotAnIntegerMessage()
{
Console.WriteLine("That's not an integer! I can't process that.");
}
}
}