Partition N where the count of parts and each part are a power of 2, and part size and count are restricted in JavaScript


We are required to write a JavaScript function that takes in a number. The function should divide the number into chunks according to the following rules −

  • The number of chunks should be a power−of−two,

  • Each chunk should also have a power-of-two number of items (where size goes up to a max power of two, so 1, 2, 4, 8, 16, 32, 32 being the max)

Therefore, for example, 8 could be divided into 1 bucket −

[8]

9 could be −

[8, 1]

That works because both numbers are powers of two, and the size of the array is 2 (also a power of two).

Let's try 11 −

[8, 2, 1]

Nope that doesn't work.

Because the size of the array is 3 which is not a power of two, even though it adds to 11.

[4, 4, 2, 1]

That works! It's 4 elements which is a power of two.

Example

The code for this will be −

function permuteCombinations(n, maximum){
   const maxPowerOf2 = 1 << maximum;
   const m = ~~(n / maxPowerOf2);
   const A = new Array(maximum + 1).fill(0);
   A[maximum] = m;
   let num = n − m * maxPowerOf2;
   let p = 0;
   let bitCount = 0;
   while (num){
      if (num & 1){
         bitCount += 1;
         A[p] = 1;
      }
      num >>= 1;
      p += 1;
   }
   const min = m + bitCount;
   let target = 1;
   while (target < min)
   target *= 2;
   if (target > n)
   return −1;
   if (target == min)
   return A.map((c, p) => [1 << Number(p), c]);
   if (target == n)
   return [n];
   target = target − min;
   let i = m ? maximum : p;
   while (target && i > 0){
      if (!A[i]){
         i −= 1;
         continue;
      }
      const max = Math.min(target, A[i]);
      A[i] −= max;
      A[i−1] += 2*max;
      target −= max;
      i −= 1;
   }
   return target ? −1 : A.map((c, p) => [1 << Number(p), c]);
};
console.log(permuteCombinations(11, 5));

Output

And the output in the console will be −

[ [ 1, 1 ], [ 2, 1 ], [ 4, 2 ], [ 8, 0 ], [ 16, 0 ], [ 32, 0 ] ]

Updated on: 21-Nov-2020

73 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements