Trying to find factors of a number in JS

前端 未结 13 2857
陌清茗
陌清茗 2021-02-19 04:52

I am just starting JS, and understand the concept of finding a factor. However, this snippet of code is what I have so far. I have the str variable that outputs nothing but the

相关标签:
13条回答
  • 2021-02-19 05:20

    here is a performance friendly version with complexity O(sqrt(N)). Output is a sorted array without using sort.

    var factors = (num) => {
    let fac = [], i = 1, ind = 0;
    
    while (i <= Math.floor(Math.sqrt(num))) {
      //inserting new elements in the middle using splice
      if (num%i === 0) {
        fac.splice(ind,0,i);
        if (i != num/i) {
          fac.splice(-ind,0,num/i);
        }
        ind++;
      }
      i++;
    }
    
    //swapping first and last elements
    let temp = fac[fac.length - 1];
    fac[fac.length - 1] = fac[0];
    fac[0] = temp;
    
    // nice sorted array of factors
    return fac;
    };
    console.log(factors(100));
    

    Output: [ 1, 2, 4, 5, 10, 20, 25, 50, 100 ]

    0 讨论(0)
  • 2021-02-19 05:22

    function primeFactors(n) {
      let arrPrime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79];
      let divisor = 2,
        divided = n,
        arr = [],
        count = 0, out = "";
      while (divisor < n) {
        if (divided % divisor == 0) {
          arr.push(divisor)
          divided /= divisor;
          console.log(divisor);
        }
        else {
          divisor++;
        }
      }
      console.log(count);
      // let news = arr.filter(num => num != ",")
      // console.log(news);
      // arr.slice(indexOf(map(",")), 1)
      return arr;
    }
    
    let out = primeFactors(86240);
    console.log(out);

    0 讨论(0)
  • 2021-02-19 05:23

    As an even more performant complement to @the-quodesmith's answer, once you have a factor, you know immediately what its pairing product is:

    function getFactors(num) {
      const isEven = num % 2 === 0;
      let inc = isEven ? 1 : 2;
      let factors = [1, num];
    
      for (let curFactor = isEven ? 2 : 3; Math.pow(curFactor, 2) <= num; curFactor += inc) {
        if (num % curFactor !== 0) continue;
        factors.push(curFactor);
        let compliment = num / curFactor;
        if (compliment !== curFactor) factors.push(compliment);
      }
    
      return factors;
    }
    

    for getFactors(300) this will run the loop only 15 times, as opposed to +-150 for the original.

    0 讨论(0)
  • 2021-02-19 05:29

    Below is an implementation with the time complexity O(sqrt(N)):

    function(A) {
      var output = [];
    
      for (var i=1; i <= Math.sqrt(A); i++) {
        if (A % i === 0) {
          output.push(i);
    
          if (i !== Math.sqrt(A)) output.push(A/i);
        }
      }
    
      if (output.indexOf(A) === -1) output.push(A);
    
      return output;
    }
    
    0 讨论(0)
  • 2021-02-19 05:34

    This got me an 85% on Codility (Fails on the upperlimit, over a billion).

    Reducing the input by half doesn't work well on large numbers as half is still a very large loop. So I used an object to keep track of the number and it's half value, meaning that we can reduce the loop to one quarter as we work from both ends simultaneously. N=24 becomes: (1&24),(2&12),(3&8),(4&6)

    function solution(N) {
    
        const factors = {};
    
         let num = 1;  
         let finished = false;
         while(!finished)
         {
             if(factors[num] !== undefined)
             {
                 finished = true;
             }
             else if(Number.isInteger(N/num))
             {
    
              factors[num] = 0;
              factors[N/num]= 0;
             }
            num++
         }
    
        return Object.keys(factors).length;
    }
    
    0 讨论(0)
  • 2021-02-19 05:37

    @Moob's answer is correct. You must use a loop. However, you can speed up the process by determining if each number is even or odd. Odd numbers don't need to be checked against every number like evens do. Odd numbers can be checked against every-other number. Also, we don't need to check past half the given number as nothing above half will work. Excluding 0 and starting with 1:

    function calculate(num) {
        
        var half = Math.floor(num / 2), // Ensures a whole number <= num.
            str = '1', // 1 will be a part of every solution.
            i, j;
        
        // Determine our increment value for the loop and starting point.
        num % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);
        
        for (i; i <= half; i += j) {
            num % i === 0 ? str += ',' + i : false;
        }
    
        str += ',' + num; // Always include the original number.
        console.log(str);
    }
    
    calculate(232);

    http://jsfiddle.net/r8wh715t/

    While I understand in your particular case (calculating 232) computation speed isn't a factor (<-- no pun intended), it could be an issue for larger numbers or multiple calculations. I was working on Project Euler problem #12 where I needed this type of function and computation speed was crucial.

    0 讨论(0)
提交回复
热议问题