Recently I had an interview which asked to write a method to calculate the answer from a prefix formatted string.
The feedback from the interview was that I should have used Linq
I am a bit confused where I should have used linq and was wondering if anyone could help me.
The Problem
The signature method should be:
int Calculate(string expression)
I didn't need to validate the input but was given some examples of
My Solution - from memory
So I created unit tests and developed the code in a TDD manor
[TestFixture]
public class UnitTest1
{
[Test]
public void TestMethod_Add()
{
var calculator = new Calculator();
var result = calculator.Calculate("+ 4 2");
var expected = 6;
Assert.AreEqual(expected, result);
}
[Test]
public void TestMethod_Sub()
{
var calculator = new Calculator();
var result = calculator.Calculate("- 2 10");
var expected = -8;
Assert.AreEqual(expected, result);
}
[Test]
public void TestMethod1_mult()
{
var calculator = new Calculator();
var result = calculator.Calculate("* 10 -20");
var expected = -200;
Assert.AreEqual(expected, result);
}
[Test]
public void TestMethod1_div()
{
var calculator = new Calculator();
var result = calculator.Calculate("/ 6 2");
var expected = 3;
Assert.AreEqual(expected, result);
}
and created the follow code something like this:
public class Calculator
{
public int Calculate(string expression)
{
var tokens = expression.Split(' ');
var symbol = tokens[0];
var num1 = int.Parse(tokens[1]);
var num2 = int.Parse(tokens[2]);
switch (symbol)
{
case "+":
return num1 + num2;
case "-":
return num1 - num2;
case "*":
return num1 * num2;
case "/":
return num1 / num2;
default:
throw new NotImplementedException("Symbol has not been implemented");
}
}
}
This is as much LINQ as I can stuff into it:
int Calculate(string expression) {
var operations = new Dictionary<char, Func<int, int, int>> {
{ '+', (a, b) => a + b },
{ '-', (a, b) => a - b },
{ '*', (a, b) => a * b },
{ '/', (a, b) => a / b },
};
return expression
.Substring(2)
.Split(' ')
.Select(o => int.Parse(o))
.Aggregate(operations[expression[0]])
;
}
As an added bonus, this can effortlessly handle such expressions as "* 1 2 3 4 5"
(5!, which as we all know is 120) or "/ 1729 7 13 19"
(in case you like to do your factoring in reverse).
This is half in jest. I would not consider this an appropriate implementation in production for a Calculate
method that explicitly has to handle only two values. If your interviewer was just looking for how clever you could make something, though, this could have scored you points. (And if they were just looking for how clever you could make something for a trivial problem, be glad you didn't get the job -- maintenance at that company could be a bad thing.)
(Note to self: figure out some really neat way to split the string using SelectMany
somehow.)
Maybe they wanted to see something like this (but I like your answer ;-) )
int Calculate(string expression)
{
char symbol = expression.First();
int[] numbers = Array.ConvertAll(expression.Substring(2).Split(' '), p => int.Parse(p));
switch (symbol)
{
case '+':
return numbers.Aggregate((a, b) => a + b);
case '-':
return numbers.Aggregate((a, b) => a - b);
case '*':
return numbers.Aggregate((a, b) => a * b);
case '/':
return numbers.Aggregate((a, b) => a / b);
default:
return 0;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With