patterncsharpMajor
PI Calculator, Interview Challenge
Viewed 0 times
interviewcalculatorchallenge
Problem
Greg Beech says here that he asks C# candidates to produce a formula that calculates PI Given that Pi can be estimated using the function \$4 * (1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \dots)\$.
I'm far from C# interview ready, but I like the challenge. Here is my attempt at the formula. Let me know if there is a better way to do it.
I'm far from C# interview ready, but I like the challenge. Here is my attempt at the formula. Let me know if there is a better way to do it.
using System;
class MainApp
{
static void Main ()
{
double number = 0;
double pi;
int i = 1;
do
{
if ((i/2) % 2 == 0)
{
number += (double)(1) / i;
}
else
{
number -= (double)(1) / i;
}
pi = 4 * number;
i += 2;
} while (Math.Round(pi,5) != 3.14159);
Console.Clear();
Console.WriteLine("Pi can be found using the formula 4 * (1 - 1/3 + 1/5 - 1/7 + ...) with {0} iterations.\n" +
"At this point 4 is multiplied by: {1} to get {2}\n" +
"This Rounds up to: {3}",i,number,pi,Math.Round(pi,5));
Console.ReadKey();
}
}Solution
In an interview it usually doesn't matter if you actually solve the problem. What is most important is the way you (try to) solve it. If they don't tell you it should be the possibly fastest solution ever you should not optimize it prematurely but instead show that you know how to write SOLID code like encapsulate propertly, make the code testable etc. show that you know the techniques.
Here you could split the logic up into multiple methods for example you could have one generating the alternating sequence
then you can work on the PI itself and use it for the actual calculation which is then as simple as a LINQ expression:
There's all kind of stuff you can show you are familiar with in this simple task like DI or strategy pattern:
or even more advanced DI and encapsulation
or you can add an interface to show you know what abstraction means:
Is this an overkill? It might be but it shows me that you are able to write modular and testable code. Writing short code is a good thing too but if you write only five lines inside a
Here you could split the logic up into multiple methods for example you could have one generating the alternating sequence
[1, -3, 5, -7, 9, -11, ...] that you can validate with a test:public static IEnumerable AlternatingSequence()
{
var i = 1;
yield return i;
var b = false;
while (true) yield return ((b = !b) ? -1 : 1) * (i = i + 2);
}then you can work on the PI itself and use it for the actual calculation which is then as simple as a LINQ expression:
public static double EstimatePI(int sumLength)
{
return (4 * AlternatingSequence().Take(sumLength).Sum(x => 1.0 / x));
}
var pi = EstimatePI(500_000).Dump(); // 3,14159065358969There's all kind of stuff you can show you are familiar with in this simple task like DI or strategy pattern:
public static double EstimatePI(int sumLength, IEnumerable sequenceGenerator)
{
return (4 * sequenceGenerator.Take(sumLength).Sum(x => 1.0 / x));
}
var pi = EstimatePI(500_000, AlternatingSequence);or even more advanced DI and encapsulation
class PiCalculator
{
private readonly IEnumerable _sequenceGenerator;
public PiCalculator(IEnumerable sequenceGenerator)
{
_sequenceGenerator = sequenceGenerator;
}
public double EstimatePi(int sumLength)
{
...
}
}or you can add an interface to show you know what abstraction means:
interface IPiCalculator
{
double EstimatePi(int sumLength);
}Is this an overkill? It might be but it shows me that you are able to write modular and testable code. Writing short code is a good thing too but if you write only five lines inside a
Main in a job interview, you'll go home without any prospects of getting the job. Again, in an inteview you should sell your coding skills and not show how smart you are in solving something with a fewest possible lines of code that no one can verify.Code Snippets
public static IEnumerable<int> AlternatingSequence()
{
var i = 1;
yield return i;
var b = false;
while (true) yield return ((b = !b) ? -1 : 1) * (i = i + 2);
}public static double EstimatePI(int sumLength)
{
return (4 * AlternatingSequence().Take(sumLength).Sum(x => 1.0 / x));
}
var pi = EstimatePI(500_000).Dump(); // 3,14159065358969public static double EstimatePI(int sumLength, IEnumerable<int> sequenceGenerator)
{
return (4 * sequenceGenerator.Take(sumLength).Sum(x => 1.0 / x));
}
var pi = EstimatePI(500_000, AlternatingSequence);class PiCalculator
{
private readonly IEnumerable<int> _sequenceGenerator;
public PiCalculator(IEnumerable<int> sequenceGenerator)
{
_sequenceGenerator = sequenceGenerator;
}
public double EstimatePi(int sumLength)
{
...
}
}interface IPiCalculator
{
double EstimatePi(int sumLength);
}Context
StackExchange Code Review Q#158541, answer score: 37
Revisions (0)
No revisions yet.