locked
Interview Question for C# RRS feed

  • Question

  • Implement the following function and test it (C#):

    protected int GetSum(int from, int to)

    {

    // add the numbers from “from” to “to” all together and return the result.

    }

    Monday, January 7, 2013 8:53 PM

Answers

  • this should do it

    protected int GetSum(int from, int to)

    {

         int result = 0;

         for (int idx = from; idx <= to; idx++)
         {
              result = result + idx;
         }

         return result

    }


    Monday, January 7, 2013 9:22 PM

All replies

  • No offense, but it has to be a joke ..?

    Classified SR-2 | 2x Xeon W5580 - 3.20 GHz | 12x 2GB Kingston KHX2000C9D3T1K3/6GX | 2x MARS II/2DIS/3GD5 | SAMSUNG 830 MZ-7PC512D/AM 2.5" 512GB SATA III MLC | 4x Spinpoint F3EG HD503HI 500GB 5400 16MB SATA 3.0Gb/s |

    Monday, January 7, 2013 9:05 PM
  • They probably interviewed and got this as a question.  Not a joke just a basic weeder question. 

    They probably care more about the persons other qualities BUT they just want to make sure they know at least something.

    Monday, January 7, 2013 9:17 PM
  • this should do it

    protected int GetSum(int from, int to)

    {

         int result = 0;

         for (int idx = from; idx <= to; idx++)
         {
              result = result + idx;
         }

         return result

    }


    Monday, January 7, 2013 9:22 PM
  • Quite trivial:

    {
        Enumerable.Range(1, 4).Sum()
    }

    EDIT: not so trivial at all, here is the fixed version:

    long GetSum(int from, int to)
    {
    	if (from > to)
    		throw new InvalidOperationException();
    	else
    		return Enumerable.Range(from, to).Select(i => (long)i).Sum();
    }

    Notice the conversion from int to long, this is necessary since large sums of ints may not be expressible as ints, but could be expressed as longs.

    It really tells a lot about the person solving it :)


    Toni Petrina
    My blog: Toni codes .NET
    If a post answers your question, please click "Mark As Answer" on that post and "Vote as Helpful"


    Monday, January 7, 2013 9:40 PM
  • I don't think it's a joke at all.  There's plenty to discuss with such a function.

    If I were interviewing I'd look to see if the candidate implemented with a loop, or with a constant time mathematical evaluation of the sum.  ((to*(to+1)-(from*(from-1)))/2

    In apart from the actual expression to be computed, and the associated potential "off-by-one" errors, there are numerous other gotchas.  Like what does it mean when from > to, or when the sum is larger than the maximum value that can be represented using an int (or smaller than the minimum value).  Eliminating vagueness by fully specifying the function is the first step.

    The candidate may also show a knowledge of "unchecked" expressions.

    Testing it is even more interesting.  Does the candidate show knowledge of unit testing frameworks?  Or do they simply write a function that makes a bunch of run-time checks and/or assertions.  How to test a "protected" function may even be discussion-worthy.

    Furthermore, the test cases chosen will show how well the candidate grasps what can happen with such a function.  {from < to}, {from == to} and {from > to} are all interesting cases worth testing.  Ranges with an odd or even number of elements are interesting due to potential rounding errors.  Large spans are interesting.  Ranges whose sum are just above, below or equal to a signed or unsigned integer maximum are interesting.  Sums that are negative or zero are interesting too.  sums where {from < 0 < to} are interesting as well.


    • Edited by Wyck Monday, January 7, 2013 9:44 PM typo.
    • Proposed as answer by Reed Copsey, JrMVP Monday, January 7, 2013 10:07 PM
    Monday, January 7, 2013 9:41 PM
  • Generally speaking, this is a perfect solution :)

    What about when from is larger than to? Because the question did not fully specify about the order whether "from" and "to" means from smaller number to larger number or from larger number to smaller number, I would not think your solution isn't fully completed. I know this isn't really the case in normal life but hey it is a interview question so you should at least add a comment saying it assumes from is always smaller or equals to to.

    Regards,

    Monday, January 7, 2013 10:31 PM
  • It is interesting that everyone (attempts) to answer the small part of the question (how do I code this) but nobody actually shows any answer to the part which should be written first (the tests).  I am not going to either.  The tests, of course, would probably represent more lines of code than the actual system under test.

    Wyck makes the point that there is a constant time solution available.  i would be pleased to see a candidate present that.  Unfortunately, the constant time expression version, the Enumerable.Range version and the for loop versions presented all fail if from=to=int.MaxValue (and other extreme values).  from=int.MinValue, to = int.MaxValue is well defined (the result should be int.MinValue) but no method presented so far can handle it correctly.  Perhaps VendorX knows an obvious solution that everyone else has missed?

    The suggestions for possible tests are very important and would reveal some of the problems with all of the solutions presented so far.

    Does anyone have some tests which address a wide variety of input values and an implementation which gives 'correct' results for those tests that they would like to share?

    I note that the return type of GetSum is int which implies some limits on acceptable input values.


    Paul Linton

    Monday, January 7, 2013 11:03 PM
  • OK, I guess I have to either put up or shut up.  Here are my tests

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void Zeroes()
        {
            Assert.AreEqual(0, Summer.GetSum(0, 0));
        }
    
        [TestMethod]
        public void EqualValues()
        {
            Assert.AreEqual(10, Summer.GetSum(10,10));
        }
    
        [TestMethod]
        public void MaxValues()
        {
            Assert.AreEqual(int.MaxValue, Summer.GetSum(int.MaxValue, int.MaxValue));
        }
    
        [TestMethod]
        public void MinValues()
        {
            Assert.AreEqual(int.MinValue, Summer.GetSum(int.MinValue, int.MinValue));
        }
    
        [TestMethod]
        public void SpanZero()
        {
            Assert.AreEqual(int.MinValue, Summer.GetSum(int.MinValue, int.MaxValue));
        }
    
        [TestMethod]
        public void Boring()
        {
            Assert.AreEqual(1 + 2 + 3 + 4 + 5, Summer.GetSum(1, 5));
        }
    
        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void ExceptionallyBig()
        {
            Assert.AreEqual(0, Summer.GetSum(int.MaxValue - 1, int.MaxValue));
        }
    
        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void ExceptionallySmall()
        {
            Assert.AreEqual(0, Summer.GetSum(int.MinValue, int.MinValue + 1));
        }
    
        [TestMethod]
        public void ReverseBoring()
        {
            Assert.AreEqual(1 + 2 + 3 + 4 + 5, Summer.GetSum(5, 1));
        }
    
        [TestMethod]
        public void ReverseSpanZero()
        {
            Assert.AreEqual(int.MinValue, Summer.GetSum(int.MaxValue, int.MinValue));
        }
    }

    And here is the code which passes these tests.

    public static class Summer
    {
        public static int GetSum(int from, int to)
        {
            long start = Math.Min(from, to);
            long end = Math.Max(from, to);
            long result = (end * (end + 1) - start * (start - 1)) / 2;
    
            if (result <= int.MaxValue && result >= int.MinValue)
                return (int)result;
    
            throw new Exception("Result is outside range of an int");
        }
    }
    

    I have made some decisions like throwing an Exception of the result does not fit in an int and swapping the inputs if from > to. Others could make different decisions, but the tests would need to reflect those decisions.

    << I have just noticed that a couple of posts which give incorrect answers (and have no tests at all) have been marked as 'Correct' for this thread.  One of the 'Correct' answers actually goes into an infinte loop if given particular legitimate input (from = to = int.MaxValue is not good for the 'for' loop version) >>


    Paul Linton

    • Proposed as answer by Mr. Javaman II Monday, January 7, 2013 11:55 PM
    Monday, January 7, 2013 11:30 PM
  • Paul's answer looks closest to the best to me personally...

      There's only a total of 6 permutations per integer parameter on input. Actually 5 because MAX + 1 is not valid.  Correct me if I'm wrong but that gives us 5!-1 total permutations.  Obviously they most likely wouldn't expect Test Cases that detailed for an interview.  But it's the only way to assess the method entirely.

    As far as the implementation of the method with no other details on limits, we see the need for good input parm validation. For example one may be INT.MAXValue but the other would have to be zero!  Looks like a good candiate for Code Contracts.


    JP Cowboy Coders Unite!

    Tuesday, January 8, 2013 12:02 AM
  • Mr Javaman - what do you see as the 5 permutations per integer parameter?

    If one input parameter is int.MaxValue then the other may be int.MaxValue, int.MinValue or int.MinValue+1, anything else (including zero) produces a value outside the range of an int.  I don't think that you can check parameter validity before actually computing the result.  For example,

    GetSum(50000, 82430); OK

    GetSum(50000, 82431); Not OK

    (I will concede that someone who is better than me at mathematics probably could come up with some way of checking the parameters without doing the actual calculation, but I suspect that the parameter checking would be way more intensive than just doing the computation and checking the result)


    Paul Linton

    Tuesday, January 8, 2013 12:26 AM
  • Good question, typically all boundary conditions tests for ints are summed up as follows:

    Min, Min-1, Min+1, Max, Max-1, Max+1 and the special instance of Null.

    So then the question for the MAX ranges is simple but what is min?  Can we have negative integers in the program above?

    Max+1 is out, so that leaves 5 and the special case of Null.  (6 total permuations per parm) 6!-1 permutations. We know that some of the permutations put the result > MAX so there are many less permutations than 6!-1.

    Note that the output is an INT so the sum of either paremeters can never be MAX+1...  This introduces a sliding max value relationship between parm 1 and 2, but.... Any test combining the two to exceed the output max is all that's needed to see if the code was bullet proof.  Don't need to test every single combination of Parm1 + Parm2 = MAX+1...


    JP Cowboy Coders Unite!

    Tuesday, January 8, 2013 4:08 AM
  • Paul: what if from = to?

    -A


    • Edited by achalk Thursday, August 8, 2013 7:52 PM
    Thursday, August 8, 2013 7:52 PM
  • Paul: what if from = to?

    -A



    Add a test, run it.  Red, green, refactor.

    Paul Linton

    Thursday, August 8, 2013 10:09 PM
  • Thanks so much for your thoughts. I never know when they want the quick answer (those interviewers suggest I will over-analyze and over-complicate) or if they want a solid response. If they could tell me what they think after I answer, it would help me determine if they want a dev to build a ton of prototypes with pressured deadlines or well-built products.
    Thursday, March 27, 2014 3:56 PM
  • public int GetSum( int xFrom, int xTo ) {
    if (xFrom == xTo) {
    return xTo;
    } else {
    return xFrom + GetSum( xFrom+1, xTo );
    }
    }
    Friday, May 9, 2014 12:49 PM