I hope that since you asked...
Is there a way I could have avoided the 'o' counter in my for loop and instead selected the array in a different way?
... you're open to completely different approaches. If that's correct, I reckon that there is a simpler way to do this.
Just slice that array
Actually, you almost get it when you did:
inArr.sort();
As you'll see, sorting the array is the key here. If you stop to think, after sorting (in ascending order) your array:
minSum
is just the sum of all elements except the last one;
maxSum
is just the sum of all elements except the first one.
That being said, you can sort your array...
arr.sort();
... and, after that, using a very basic function to sum elements, like reduce
...
function sum(subArr) {
return subArr.reduce(function(a, b) {
return a + b;
}, 0);
}
... that you call on different slices of the array:
var minSum = sum(arr.slice(0, -1))//all elements except the last one
var maxSum = sum(arr.slice(1))//all elements except the first one
Here is the demo, with different arrays:
function miniMaxSum(arr) {
arr.sort();
var minSum = sum(arr.slice(0, -1))
var maxSum = sum(arr.slice(1))
console.log(minSum, maxSum)
}
function sum(subArr) {
return subArr.reduce(function(a, b) {
return a + b;
}, 0);
}
miniMaxSum([1, 4, 2, 5, 3])
miniMaxSum([42, 24, 12, 57, 3])
miniMaxSum([100, 102, 101, 103, 104])
It gets simpler
The solution above, using reduce
, works with an array of any length:
function miniMaxSum(arr) {
arr.sort();
var minSum = sum(arr.slice(0, -1))
var maxSum = sum(arr.slice(1))
console.log(minSum, maxSum)
}
function sum(subArr) {
return subArr.reduce(function(a, b) {
return a + b;
}, 0);
}
miniMaxSum([1, 4, 7, 5, 3, 8, 6, 2])
However, as the the challenge says that you'll always be given five integers, and as your very solution only accepts an array with 5 integers...
i >= arr.length - 4, o < 4
... this could be even simpler, dropping both the reduce
and the for
loop:
function miniMaxSum(arr) {
arr.sort();
var minSum = arr[0] + arr[1] + arr[2] + arr[3]
var maxSum = arr[1] + arr[2] + arr[3] + arr[4]
console.log(minSum, maxSum)
}
miniMaxSum([1, 4, 2, 5, 3])
miniMaxSum([42, 24, 12, 57, 3])
miniMaxSum([100, 102, 101, 103, 104])
It gets even more simple: no sort
Using sort
can greatly increase the time complexity. The good news is that there is a solution without sort
. It's based on this simple logic, as described in this other answer:
minSum
is just the sum of all elements except the smallest one;
maxSum
is just the sum of all elements except the biggest one.
Therefore, you just need to sum all elements, then subtract the smaller one to get minSum
and subtract the biggest one to get maxSum
.
So, here is yet another solution, without any sort
:
function miniMaxSum(arr) {
var min = Infinity,
max = -Infinity,
count = 0;
for (var i = 0; i < arr.length; i++) {
count += arr[i];
min = arr[i] < min ? arr[i] : min;
max = arr[i] > max ? arr[i] : max;
}
console.log(count - min, count - max)
}
miniMaxSum([1, 4, 2, 5, 3])
miniMaxSum([42, 24, 12, 57, 3])
miniMaxSum([100, 102, 101, 103, 104])
Performance
Regarding the performance, your code (for
loop) is around 5% faster than mine (reduce
), have a look here:
https://jsperf.com/minmaxsum
I believe 5% is not a big value, but if you are ultra-concerned about performance, stick with the for
loop.
Of course, the simple solution (just adding the elements of the array) is, as expected, faster than both:
https://jsperf.com/minmaxsum-v2/1
Funnily enough, the "no sort" version doesn't seem to be that fast in the JSPerf test:
https://jsperf.com/min-max-sum-v3/1
PS: be careful with the names: in your snippet you have a parameter named inArr
, but there is no arr
anywhere.
i
ando
? Print them out if it helps. BTW the comma operator is unhelpful in the termination condition of the loop. \$\endgroup\$