Antonio Pavicevac-Ortiz
Antonio Pavicevac-Ortiz

Reputation: 7739

How do I sum all the numbers in a range using this function in JavaScript?

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 come 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 recommended? 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!

Upvotes: 1

Views: 1971

Answers (5)

jfriend00
jfriend00

Reputation: 707386

Here'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.net/jfriend00/rh75gesc/ which compares it to the old fashioned way for accuracy.


For pure performance (not code brevity), it's probably better to just compare 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.net/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)
}

Upvotes: 4

Bekim Bacaj
Bekim Bacaj

Reputation: 5955

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 ) );

Upvotes: 1

mkarts
mkarts

Reputation: 677

An intuitive way to solve this would be to:

  1. Find min and max of the input array.
  2. 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

}

Upvotes: 0

adeneo
adeneo

Reputation: 318212

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);
}

Upvotes: 2

Nenad Vracar
Nenad Vracar

Reputation: 122047

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]))

Upvotes: 2

Related Questions