Search code examples
algorithmloopswhile-looptaskloading

using while loop the page keep loading over and over (codewars problem)


heyy guys i m trying to solve Factorial decomposition (codewars task ) well some numbers work with me untill i reach number 23 the page keep looping over and over someone help me please

function decomp(n) {
  let c =[]
  let sum =1
 for(let i=n;i>=1;i--){
   sum*=i
 }
 let k= 2
 
 while(k<=sum){
  if(sum%k!==0){
  k++}
  while(sum%k==0){
    c.push(k)
sum = sum/k

} 
 }
  return c.join('*')
}

the function works good until i reach the number 23 the keep loading over and over , the tasks is about the function is decomp(n) and should return the decomposition of n! into its prime factors in increasing order of the primes, as a string.

factorial can be a very big number (4000! has 12674 digits, n can go from 300 to 4000).

In Fortran - as in any other language - the returned string is not permitted to contain any redundant trailing whitespace: you can use dynamically allocated character strings.

example

n = 12; decomp(12) -> "2^10 * 3^5 * 5^2 * 7 * 11"

since 12! is divisible by 2 ten times, by 3 five times, by 5 two times and by 7 and 11 only once.

n = 22; decomp(22) -> "2^19 * 3^9 * 5^4 * 7^3 * 11^2 * 13 * 17 * 19"

n = 25; decomp(25) -> 2^22 * 3^10 * 5^6 * 7^3 * 11^2 * 13 * 17 * 19 * 23


Solution

  • 23! cannot be exactly expressed in double-precision floating-point format, which JavaScript uses for its numbers.

    However, you don't need to compute n!. You just need to factorize each number and concat their factorization.

    Actually, you don't even need to factorize each number. Note that given n and p, there are (n/p) numbers no greater than n that are multiples of p, (n/(p*p)) that are multiples of p*p, etc.

    function *primes(n) {
      // Sieve of Eratosthenes 
      const isPrime = Array(n + 1).fill(true);
      isPrime[0] = isPrime[1] = false;
      for (let i = 2; i <= n; i++) {
        if (isPrime[i]) {
          yield i;
          for (let j = i * i; j <= n; j += i)
            isPrime[j] = false;
        }
      }
    }
    
    function decomp(n) {
      let s = n + '! =';
      for (const p of primes(n)) {
        let m = n, c = 0;
        // There are (n/p) numbers no greater than n that are multiples of p
        // There are (n/(p*p)) numbers no greater than n that are multiples of p*p
        // ...
        while (m = ((m / p) | 0)) {
          c += m;
        }
        s += (p == 2 ? ' ' : ' * ') + p + (c == 1 ? '' : '^' + c);
      }  
      return s;
    }
    
    console.log(decomp(12))
    console.log(decomp(22))
    console.log(decomp(23))
    console.log(decomp(24))
    console.log(decomp(25))