3

i'm doing some coding exercises and i'm not being able to solve this one.

Find the sum of all divisors of a given integer. For n = 12, the input should be sumOfDivisors(n) = 28.

example: 1 + 2 + 3 + 4 + 6 + 12 = 28.

Constraints: 1 ≤ n ≤ 15.

how can i solve this exercise? i'm not being able to.

function(n){
    var arr = [],
        finalSum;

    if(n <= 1 || n => 16){
       return false ;   
   }
   for(var i = 0; i < n; i++){
       var tmp= n/2;
       arr.push(tmp)    
       // i need to keep on dividing n but i can't get the way of how to
   }
  return finalSum;
}

5 Answers 5

19

This is another way to do it:

var divisors = n=>[...Array(n+1).keys()].slice(1)
   .reduce((s, a)=>s+(!(n % a) && a), 0);

console.log(divisors(12));

JSFiddle: https://jsfiddle.net/32n5jdnb/141/

Explaining:

  • n=> this is an arrow function, the equivalent to function(n) {. You don't need the () if there's only one parameter.
  • Array(n+1) creates an empty array of n+1 elements
  • .keys() gets the keys of the empty array (the indexes i.e. 0, 1, 2) so this is a way to create a numeric sequence
  • [...Array(n+1)].keys()] uses the spread (...) operator to transform the iterator in another array so creating an array with the numeric sequence
  • .slice(1) removes the first element thus creating a sequence starting with 1. Remember the n+1 ?
  • .reduce() is a method that iterates though each element and calculates a value in order to reduce the array to one value. It receives as parameter a callback function to calculate the value and the initial value of the calculation
  • (s, a)=> is the callback function for reduce. It's an arrow function equivalent to function(s, a) {
  • s+(!(n % a) && a) is the calculation of the value.
  • s+ s (for sum) or the last value calculated +
  • !(n % a) this returns true only for the elements that have a 0 as modular value.
  • (!(n % a) && a) is a js 'trick'. The case is that boolean expressions in javascript don't return true or false. They return a 'truthy' or 'falsy' value which is then converted to boolean. So the actual returned value is the right value for && (considering both have to be truthy) and the first thuthy value found for || (considering only one need to be truthy). So this basically means: if a is a modular value (i.e. != 0) return a to add to the sum, else return 0.
  • , 0 is the initial value for the reduce calculation.

Reduce documentation: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Edit

Answering to Tristan Forward:

var divisorsList = [];
var divisors = (n)=>[...Array(n+1).keys()].slice(1)
       .reduce((s, a)=>{
          var divisor = !(n % a) && a;
          if (divisor) divisorsList.push(divisor);
          return s+divisor;
       }, 0);
    

console.log('Result:', divisors(12));
console.log('Divisors:', divisorsList);

Sign up to request clarification or add additional context in comments.

3 Comments

Any idea how to return a list of divisors from this function versus adding them?
@TristanForward included an example to answer you.
just another example to find divisors with no use of reduce: const divisors = (n) => [...Array(n + 1).keys()].slice(1).filter((i) => n % i === 0);
5

You have to check if specified number is or not a divisor of given integer. You can use modulo % - if there's no rest, specified number is the divisor of the given integer - add it to the sum.

function sumDivisors(num){
  var sum = 0;
  for (var i = 1; i <= num; i++){
    if (!(num % i)) {
      sum += i;
    }
  }
  console.log(sum);
}

sumDivisors(6);
sumDivisors(10);

Comments

1

Here is a solution with better algorithm performance (O(sqrt(largest prime factor of n)))

divisors = n => {
  sum = 1
  for (i = 2; n > 1; i++) {
    i * i > n ? i = n : 0
    b = 0
    while (n % i < 1) {
      c = sum * i
      sum += c - b
      b = c
      n /= i
    }
  }
  return sum
}

1 Comment

Can you describe the logic here?
0

since n / i is also a devisor this can be done more efficiently.

function sumDivisors(num) {
    let sum = 1;
    
    for (let i = 2; i < num / i; i++) {
        if (num % i === 0) {
            sum += i + num / i;
        }
    }

    const sqrt = Math.sqrt(num);
    return num + (num % sqrt === 0 ? sum + sqrt : sum);
}

Comments

0
function countDivisors(n){
 let counter = 1;
 for(let i=1; i <= n/2; i++){
  n % i === 0 ? counter++ : null;
 }
 return counter
}  

in this case, we consider our counter as starting with 1 since by default all numbers are divisible by 1. Then we half the number since numbers that can be able to divide n are less or equal to half its value

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.