namespace BKTest
{
public class Pie
{
/// <summary>
/// Estimates pi based on the number of fractions we desire it to estimate by.
/// The way I view it: you basically have 4 * (element0 + element1 + element2 etc.)
/// where element0, element1 etc are instances of the Element class.
/// I use a factory method to instantiate the element types and use polymorphism to differentiate
/// between the two different types of elements that are currently out there: Element0 and the others: Element1, Element2 etc .
/// Element zero is different because you can't divide by zero! (This probably won't make any sense)
/// Till you attempt the problem yourself.
///
/// </summary>
/// <param name="elementCount"></param>
/// <returns></returns>
public double Estimate(int elementCount)
{
ElementCollection ec = new ElementCollection(elementCount);
return 4 * ec.AddAllElements();
}
}
public class ElementCollection
{
private int elementCount;
public ElementCollection(int elementCount)
{
this.elementCount = elementCount;
}
public double AddAllElements()
{
double result = 0.0;
for (int i = 0; i < elementCount + 1; i++)
{
ElementN element = ElementFactory(i);
result += element.Value();
}
return result;
}
public ElementN ElementFactory(int i)
{
if (i == 0)
{
return new Element0(i);
}
else
{
bool even = (i % 2 == 0);
if (even)
{
return new ElementEven(i);
}
else
{
return new ElementOdd(i);
}
}
}
public class Element0 : ElementN
{
public Element0(int elementCount)
: base(elementCount)
{
}
public override int Sign()
{
return 1;
}
public override double PosivitveValue()
{
return 1.0;
}
}
public class ElementEven : ElementN
{
public ElementEven(int elementCount)
: base(elementCount)
{
}
public override int Sign()
{
return 1;
}
}
public class ElementOdd : ElementN
{
public ElementOdd(int elementCount)
: base(elementCount)
{
}
public override int Sign()
{
return -1;
}
}
public abstract class ElementN
{
private int elementCount;
public ElementN(int elementCount)
{
this.elementCount = elementCount;
}
virtual public double Value()
{
return Sign() * PosivitveValue();
}
virtual public double PosivitveValue()
{
return ((1.0) / (2.0 * elementCount + 1));
}
/// <summary>
/// Either the sign is positive or negative
/// We could probably put this into its own class
/// and have a factory method but we'll keep it like this for the moment
/// till one day change requires us to change it. After all, a sign can only
/// either be positive or negative. (apparently you can also multiple by the
/// square root of (-1) but that's another matter.
/// </summary>
/// <returns></returns>
abstract public int Sign();
}
}
}
using NUnit.Framework;
namespace BKTest
{
[TestFixture]
internal class PieTest
{
[Test]
[TestCase(0, 4)]
[TestCase(1, 4 * (1 - 1.00 / 3.0))]
[TestCase(2, 4 * (1 - 1.00 / 3.0 + 1 / 5.0))]
[TestCase(3, 4 * (1 - 1.00 / 3.0 + 1 / 5.0 - 1 / 7.0))]
[TestCase(4, 4 * (1 - 1.00 / 3.0 + 1 / 5.0 - 1 / 7.0 + 1 / 9.0))]
public void Estimate_1Parameter_expect_fourMinusOneThird(int input, double output)
{
// set up
double result = new Pie().Estimate(input);
Assert.AreEqual(output, result);
}
}
}