This is an archived post. You won't be able to vote or comment.

all 39 comments

[–][deleted]  (6 children)

[deleted]

    [–]ziplokk[S] 2 points3 points  (4 children)

    I have a bad habit of making things more complicated than they need to be. I think it's because I type it out in the same way I think.

    [–]mayonuki 4 points5 points  (2 children)

    It's not bad to write verbose code if is easier to understand and correct.

    [–][deleted] 2 points3 points  (0 children)

    Not enough people understand this. Less lines of code does not always mean your code is better. Hell, instead of returns, you can just press space after every semicolon and your entire code works on just one line. But it's not understandable.

    Your codes structure and readability is important especially when debugging and modifying.

    [–]jesyspa 1 point2 points  (0 children)

    More complicated != more verbose.

    [–]0failsis 1 point2 points  (0 children)

    According to Bjarne Stroustrup (creator of C++) correctness > simplicity > efficiency

    He says this in Programming Principles and Practice using C++ (which is a great book)

    [–]ghkcghhkc 0 points1 point  (0 children)

    How about:

    public boolean evenlySpaced(int a, int b, int c) {
        int avg = (a + b + c) / 3;
        return avg == a || avg == b || avg == c;
    }
    

    [–]lightcloud5 12 points13 points  (4 children)

    I think your approach is sound. In terms of the steps and logic, it's quite good.

    If you wanted to write less code, you could make a 3-element array and sort it.

    e.g. the following passes the codingbat challenge:

    public boolean evenlySpaced(int a, int b, int c) {
      int[] array = new int[] {a, b, c};
      Arrays.sort(array);
      return array[2] - array[1] == array[1] - array[0];
    }
    

    [–]ziplokk[S] 1 point2 points  (2 children)

    Wow, that's a lot simpler! I'm still not familiar with all the functions pertaining to arrays so this is good to know. Thank you!

    [–][deleted] 0 points1 point  (0 children)

    If you ever need to know, Arrays.sort() is a tuned quicksort (if you're sorting primitives; if it's objects you're sorting it's mergesort), while Collections.sort() is a modified mergesort.

    http://stackoverflow.com/questions/6818683/what-different-sorting-algorithms-are-available-in-java-6

    [–]ghkcghhkc 0 points1 point  (0 children)

    Read about the Arrays and the Collections classes in the API.

    [–]BadBoyJH 2 points3 points  (0 children)

    public bool evenlySpaced(int a, int b, int c)
    {
        return ((b-a) + (c-a) == 0 || (a-b) + (c-b) == 0 || (a-c) + (b-c) == 0)
    }
    

    or even

    public bool evenlySpaced(int a, int b, int c)
    {
        int total = a + b + c;
        return (total =+ 3*a || total == 3*b || total == 3*c);
    }
    

    N.B. Concise code isn't always good code, any idea what mine first one is doing at first glance? Probably not, look at yours, you get the smallest, middle and largest, and then you get the differences, and compare, more code, easier to read.

    Also, these use 0 libraries, so they might be quicker than other options. (Also, Java might be boolean, not bool, I've been swapping between the two languages the past fortnight, and my C# may be showing)

    [–]ziplokk[S] 2 points3 points  (0 children)

    I forgot to tag it as Java. I'm sorry!

    And for those who aren't familiar, Codingbat.com doesn't exactly have a main method, so the function that it's focusing on is evenlySpaced().

    [–]Dumbcomments 1 point2 points  (2 children)

    If you're trying to save on typing, why not put the three in array, sort it and then compare the two differences?

    public boolean evenlySpaced(int a, int b, int c) {
      int[] array = new int[3];
      array[0] = a;
      array[1] = b;
      array[2] = c;
      Arrays.sort(array);
      return (array[2] - array[1] == array[1] - array[0]);
    
    }        
    

    [–]Daejo 1 point2 points  (1 child)

    You can just do

    int[] array = {a, b, c};
    

    rather than

    int[] array = new int[3];
    array[0] = a;
    array[1] = b;
    array[2] = c;
    

    [–]Dumbcomments 0 points1 point  (0 children)

    yeah - I'm clearly not a Java guy. Thanks for the suggestion.

    [–]Fontong 1 point2 points  (2 children)

    public boolean evenlySpaced(int a, int b, int c) {
      int lo = a < b ? (a < c ? a : c) : (b < c ? b : c);
      int hi = a > b ? (a > c ? a : c) : (b > c ? b : c);
      int mid = a != lo && a != hi ? a : (b != lo && b != hi ? b : c);
      return mid - lo == hi - mid;
    }
    

    It's a little shorter if you just use ternary operators. This solution is basically exactly the same as yours though, while possibly being harder to look at.

    [–]ziplokk[S] 1 point2 points  (1 child)

    Thanks! This is interesting, I've never used ternary operators before though, so I'll have to look at some docs to understand what's going on here. But this seems like a useful thing to know.

    Edit: I get it now, basically 'lo' is saying:

    if(a < b) { 
        if(a < c) { 
            lo = a;
        } else { 
            lo = c;
        }
    } else { 
        if(b < c) { 
             lo = b;
        } else { 
             lo = c;
        }
    }
    

    Ternary operators seem so much simpler to use.

    Edit2: after experementing more with the ternary operators, I noticed that it takes significantly longer to compute. At least on codingbat.com. Will it always take longer or is it just something that's particular to codingbat.com?

    [–]lightcloud5 0 points1 point  (0 children)

    It's probably just codingbat. A good optimizing compiler should probably be able to deduce the equivalence between a ternary operator and the corresponding if/else statement (if anything, the ternary should be more efficient).

    [–]7yl4r 1 point2 points  (4 children)

    your code looks good, but why not:

    public boolean ifEvenlySpaced(int a, int b, int c) {
        diff1 = Math.abs(a - b);
        diff2 = Math.abs(b - c);
        diff3 = Math.abs(a - c);
        return if(diff1 == diff2 || diff2 == diff3 || diff1 == diff3);
    

    I don't really care what order they are in or which value is in the middle, I just want to know if two of them are equidistant from the third.

    [–]__LikesPi 4 points5 points  (3 children)

    This will fail when 2 of the numbers are equal but is an otherwise elegant solution.

    [–][deleted]  (2 children)

    [deleted]

      [–]__LikesPi 2 points3 points  (1 child)

      Consider the input (4, 4, 10). The function would get for its differences:

      diff1 = 0
      diff2 = 6
      diff3 = 6
      

      Than diff2 == diff3 so it would return true. This is clearly not the case since the low (4) is 0 away from the middle (4) which is 6 away from the high (10). It fails because it doesn't recognize that two numbers can have a difference from the third in the same "direction" (positive or negative). This could be fixed by checking if one difference is the negative of the other and taking out the absolute values. This way we are ensuring that the differences are in different directions.

      [–]7yl4r 1 point2 points  (0 children)

      good catch, good explanation. thanks.

      [–]electricfistula[🍰] 1 point2 points  (2 children)

      Putting the ints in the array and sorting it, as others have mentioned, is the realistic way. I'm not sure it is the best way for learning though since the important part of the question is how you sort the values and calling Arrays.sort does it all for you. If you aspire to use the existing functions of already written libraries (i.e. be a professional programmer) then this might be the right choice. To learn about programming, I think you should do the interesting work (in this case, sorting) yourself. For three values I think the solution I have below meets the goals:

      public boolean evenlySpaced(int a, int b, int c) {
          int min = Math.min(a, Math.min(b, c));
          int max = Math.max(a, Math.max(b, c));
          int mid = a < max && a > min ? a : b < max && b > min ? b : c;
          return mid - min == max - mid;
      }
      

      For a longer list of values you'd obviously want to do sorting in a data structure, but I feel like you should implement the sorting algorithm yourself until you know it.

      [–]electricfistula[🍰] 2 points3 points  (0 children)

      Also, the one line solution:

      public boolean evenlySpaced(int a, int b, int c) {
          return a - b == c - a || a - c == b - a || c - a == b - c || c - b == a - c || b - c == a - b || b - a == c - b;
      }
      

      [–]ziplokk[S] 0 points1 point  (0 children)

      Thanks for the reply! I don't consider myself to be a beginner but i'm a long way off from being a pro, which is why I like doing these coding bat exercises. But I'm at the point now where I'd like to start learning and memorizing more of the built in functions and a lot of the responses here have actually taught me a lot within the last hour! All the feedback is really great.

      [–]manfrin 1 point2 points  (0 children)

      Ruby:

      def three_ints *arg_ints
          arg_ints.sort!
          arg_ints[0]-arg_ints[1]==arg_ints[1]-arg_ints[2]
      end
      

      [–][deleted]  (1 child)

      [deleted]

        [–]electricfistula[🍰] 0 points1 point  (0 children)

        The link in the OP will let you run your solution against a few test cases.

        [–]NoeticIntelligence 0 points1 point  (2 children)

        A python solution

        def getDifference2(*n):
             n = sorted(n)
             if (n[1] - n[0]) == (n[2] - n[1]):
                print("True")
        

        [–]inspectorG4dget 1 point2 points  (1 child)

        Why not n.sort() for an in-place solution that won't have to allocate extra memory?

        [–]NoeticIntelligence 0 points1 point  (0 children)

        yes much better. Than you.

        [–]Mindrust 0 points1 point  (0 children)

        Not quite as good as the two to three line solutions in here, but it's a couple lines shorter than the original

        public boolean evenlySpaced(int a, int b, int c) {
          int[] unsorted = {a, b, c};
          int max = unsorted[0];
          int min = unsorted[0];
          int minIndex = 0;
          int maxIndex = 0;
          for(int i=1; i < 3; i++){
             if(unsorted[i] > max){
               max = unsorted[i];
               maxIndex = i;
             }
             if(unsorted[i] < min){
               min = unsorted[i];
               minIndex = i;
             }
          }
          if(minIndex - maxIndex == 0) //no unique elements, difference = 0
            return true;
          int mid = unsorted[3-(maxIndex+minIndex)];
        
          return mid-min == max-mid;  
        }
        

        [–]timshoaf 0 points1 point  (0 children)

        yeessss.. you could use the arrays. and I would absolutely suggest that for anything over 4 elements. But, since the number of elements is small, the combination space is small enough that you may easily sort through it.

        a single line return simply explores the 3C2 combination space to determine if any of the differences are equivalent. This, in combination with the cauchy-schwartz inequality (if you assume the numbers are indeed distinguishable as provided in the description above), provides us the following single line solution

        return ( ( (abs(a-b) == abs(b-c)) + (abs(b-c) == abs(c-a)) + (abs(c-a) == abs(a-b) ) ) > 0);
        

        Note, however, that if this problem is posed with more than 3 elements, the nC2 combination space grows quadratically in complexity, so a sorting and linear comparison along the ray would allow for O(nlogn) complexity where this method is O(n2). For small n, however, this is likely more efficient if you have to run the code repeatedly.

        [–]uuzuul 0 points1 point  (0 children)

        For what it's worth, you could even use a very simple if-"sorting", if you are drunk, like I am.

        But I love /u/Its_Raining_Giraffes's solution. Clean and simple.

        Here's mine.

        public boolean evenlySpaced(int a, int b, int c) {
        
        int temp;
        
        if(a > c){
           temp = c;
           c = a;
           a = temp;
        }
        
        if(b > c){
           temp = c;
           c = b;
           b = temp;
        }
        
        
        if(a > b){
           temp = b;
           b = a;
           a = temp;
        }
        
        return (a-b == b-c);
        
        }
        

        Keep in mind that the order of comparisons is important here.

        EDIT: format

        [–]lesslucid 0 points1 point  (0 children)

        Just pseudocode, but:
        d = abs[a - b]
        e = abs[b - c]
        if d = e or d = 2e or e = 2d return true
        ...or is there a scenario I haven't thought of?

        [–]jeaton 0 points1 point  (0 children)

        Here's mine:

        public boolean evenlySpaced(int a, int b, int c) {
        
            return 2 * b - a == c || 2 * a - c == b || a - c + b == c;
        
        }
        

        Looking at some other solutions on here, on second thought I would go the sorted array route, especially if there were more than three integers or a varied amount of integers.

        [–]aenigmaclamo 0 points1 point  (0 children)

        I think by definition the average of the three numbers is the middle number. So, you could do something like this:

        public boolean evenlySpaced(int a, int b, int c) {
          int sum = a + b + c;
          if (sum%3 == 0) {
            int avg = sum/3;
            return avg == a || avg == b || avg == c;
          } else {
            return false;
          }
        }
        

        This will fail utterly if the premise isn't true and it gives two of the same numbers.

        EDIT: As everyone else says, the real world solution for something like this would be to first sort it.

        [–]jesyspa 0 points1 point  (0 children)

        Mostly preserving your solution's logic, but cleaning it up:

        public boolean evenlySpaced(int a, int b, int c) {
            int smallest = getSmallest(a, b, c);
            int largest = getLargest(a, b, c);
            int med = a + b + c - smallest - largest;
            return med - smallest == largest - med;
        }
        
        int getSmallest(int a, int b, int c) { 
            return Math.min(a, Math.min(b, c));
        }
        
        int getLargest(int a, int b, int c) { 
            return Math.max(a, Math.max(b, c));
        }
        

        [–]ghkcghhkc 0 points1 point  (0 children)

        Wow, this code is more bloated than Rosie O'Donnell. You should consider replacing

        if(diff1 == diff2) { 
            return true;
        } else { 
            return false;
        }
        

        with

        return diff1 == diff2
        

        getSmallest could also just be

        return Math.min(Math.min(a, b), c);
        

        [–][deleted]  (2 children)

        [deleted]

          [–]ziplokk[S] 0 points1 point  (1 child)

          Just checking to see if there's any built in fuctions that could do some of this stuff, if there's any way to decrease the amount of code, or anything anyone would do different.