Calculate the Sum without highest and lowest number in Java
The challenge
Sum all the numbers of the array except the highest and the lowest element (the value, not the index!).
(The highest/lowest element is respectively only one element at each edge, even if there are more than one with the same value!)
Example:
{ 6, 2, 1, 8, 10 } => 16
{ 1, 1, 11, 2, 3 } => 6
If array is empty, null or None, or if only 1 Element exists, return 0.
The solution in Java code
Option 1 (first pass):
public class Solution {
public static int sum(int[] numbers) {
// catch some edge cases
if (numbers==null || numbers.length<3) return 0;
// sort the array
java.util.Arrays.sort(numbers);
// sum up elements excluding the first and last
int sum = 0;
for(int i=1;i<numbers.length-1;i++) {
sum += numbers[i];
}
return sum;
}
}
Option 2 (using IntStream
):
import static java.util.stream.IntStream.of;
public class Solution {
public static int sum(int[] numbers) {
return (numbers == null || numbers.length <= 2) ? 0 : of(numbers).sum() - of(numbers).max().getAsInt() - of(numbers).min().getAsInt();
}
}
Option 3 (using streams
):
import java.util.Arrays;
public class Solution {
public static int sum(int[] numbers) {
if(numbers == null || numbers.length < 2) return 0;
Arrays.sort(numbers);
return Arrays.stream(numbers).skip(1).limit(numbers.length-2).sum();
}
}
Test cases to validate our code solution
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class SolutionTest {
@Test
public void BasicTests() {
assertEquals(16, Solution.sum(new int[] { 6, 2, 1, 8, 10}));
}
}
More extensive test cases to catch edge-cases
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
import java.util.*;
public class SolutionTest {
@Test
public void SumOnlyOneElement() {
assertEquals(0, Solution.sum(new int[] { 6 }));
}
@Test
public void SumOnlyTwoElements() {
assertEquals(0, Solution.sum(new int[] { 6, 7 }));
}
@Test
public void SumPositives() {
assertEquals(16, Solution.sum(new int[] { 6, 2, 1, 8, 10 }));
}
@Test
public void SumPositivesWithDoubleMax() {
assertEquals(17, Solution.sum(new int[] { 6, 0, 1, 10, 10 }));
}
@Test
public void SumNegatives() {
assertEquals(-28, Solution.sum(new int[] { -6, -20, -1, -10, -12}));
}
@Test
public void SumMixed() {
assertEquals(3, Solution.sum(new int[] { -6, 20, -1, 10, -12}));
}
@Test
public void SumEmptyArray() {
assertEquals(0, Solution.sum(new int[0]));
}
@Test
public void SumNullArray() {
assertEquals(0, Solution.sum(null));
}
@Test
public void SumRandom() {
for(int r=0; r<20;r++)
{
int[] numbers = new int[6];
for(int i=0; i< numbers.length; i++)
{
numbers[i] = (int)Math.floor(Math.random() * 1100 - 500);
}
int sum = 0;
for(int i = 0 ; i < numbers.length; i++) {
sum += numbers[i];
}
int min = Arrays.stream(numbers).min().getAsInt();
int max = Arrays.stream(numbers).max().getAsInt();
int expected = sum - min - max;
assertEquals(expected, Solution.sum(numbers));
}
}
}