I am working through this coding challenge on Free Code Camp
We'll pass you an array of two numbers.
Return the sum of those two numbers and all numbers between them.
The lowest number will not always e first.
They suggest to use Math.max(), Math.min(), Array.reduce()
, however I began working through a solution which did not use any of those methods—but soon discovered maybe I should have because my version began to look a little clunky.
function sumAll(arr){
var index0 = arr[0], index1 = arr[1], counter = 0, sum = 0, val;
if(index0 < index1){
counter += index0;
while(counter <= index1){
val = index0++;
sum += val;
counter++;
}
} else if(index0 > index1){
counter = 1;
counter += index0;
while(counter >= index1){
val = index1 + 1;
sum += val;
counter--;
}
}
return sum;
}
Basically this works save for when you try:
sumAll([10, 5]) //I get 42, rather than 45
So my two questions are the following:
Am I correct in the fact it's getting clunky? And should I have used the aforementioned methods which were remended? I think I just got excited when stuff when I got things to work but now I feel I am going down a rabbit hole with another potential condition..
Thanks in advance!
I am working through this coding challenge on Free Code Camp
We'll pass you an array of two numbers.
Return the sum of those two numbers and all numbers between them.
The lowest number will not always e first.
They suggest to use Math.max(), Math.min(), Array.reduce()
, however I began working through a solution which did not use any of those methods—but soon discovered maybe I should have because my version began to look a little clunky.
function sumAll(arr){
var index0 = arr[0], index1 = arr[1], counter = 0, sum = 0, val;
if(index0 < index1){
counter += index0;
while(counter <= index1){
val = index0++;
sum += val;
counter++;
}
} else if(index0 > index1){
counter = 1;
counter += index0;
while(counter >= index1){
val = index1 + 1;
sum += val;
counter--;
}
}
return sum;
}
Basically this works save for when you try:
sumAll([10, 5]) //I get 42, rather than 45
So my two questions are the following:
Am I correct in the fact it's getting clunky? And should I have used the aforementioned methods which were remended? I think I just got excited when stuff when I got things to work but now I feel I am going down a rabbit hole with another potential condition..
Thanks in advance!
Share Improve this question asked May 1, 2016 at 23:43 Antonio Pavicevac-OrtizAntonio Pavicevac-Ortiz 7,79720 gold badges76 silver badges158 bronze badges5 Answers
Reset to default 4Here's a bit faster version that takes advantage of the fact that you don't have to actually add every single sequential number in a sequence, but you can calculate that sum based on the start and end point:
function sumAll(args) {
var min = Math.min.apply(Math, args),
max = Math.max.apply(Math, args);
return min + ((max - min) * ((max + min + 1) / 2));
}
And, here's a test bed: https://jsfiddle/jfriend00/rh75gesc/ which pares it to the old fashioned way for accuracy.
For pure performance (not code brevity), it's probably better to just pare the two values rather than make two function calls:
function sumAllFaster(args) {
var min, max;
if (args[0] < args[1]) {
min = args[0];
max = args[1];
} else {
min = args[1];
max = args[0];
}
return min + ((max - min) * ((max + min + 1) / 2));
}
If you test this against the @NenadVracar answer and include some large ranges, this last version is up to 100 times faster. The longer the range, the more of a speed difference. Even with short ranges, it is 3-4x faster. Timed tests here: https://jsfiddle/jfriend00/5daztnky/.
Here's a slightly faster version:
function sumAllFastest(args) {
var diff = args[0] < args[1] ? args[1] - args[0] : args[0] - args[1];
return (1 + diff) * ((args[0] + args[1]) / 2)
}
You could use min
, max
and one loop
var sumAll = function(arr) {
var sum = 0,
min = Math.min.apply(null, arr),
max = Math.max.apply(null, arr);
for (var i = min; i <= max; i++) {
sum += i;
}
return sum;
}
console.log(sumAll([10, 5]))
Here's a bit slower version, but it's in ES6, which is cool
function sumAll(arr, n=1){
const [min, max] = arr.sort();
return Array(max+n).fill(0,min-n,max+n).reduce((a,b,i) => a+i);
}
I'm pretty sure that, when saying: "an array of numbers", he/she didn't mean an Array Object containing those two numbers. So I offer you this Spartan JS:
function sum_range(x,y){ return( 1 + ( x < y ? y - x : x - y ) ) * (x + y) / 2; }
p.s.: It can be found on my FB timeline.
But even than, you are reassured that the supposed array will contain only two peripheral numbers of the range;
So it's all the same. The change is in the way of passing arguments to the function, e.g.:
console.log( sum_range( arr[0], arr[1] ) );
v.s.:
console.log( sum_range( 10, 5 ) );
An intuitive way to solve this would be to:
- Find min and max of the input array.
- From min to max sum all the numbers.
Something like this:
sumAll = function(arr) {
var low_bound = Math.min.apply(Math, arr);
var up_bound = Math.max.apply(Math, arr);
result = 0;
for (i=low_bound;i<=up_bound;i++){
result += i;
}
return result
}