Open In App

Powers of 2 to required sum

Given an integer N, task is to find the numbers which when raised to the power of 2 and added finally, gives the integer N.

Example : 



Input : 71307
Output : 0, 1, 3, 7, 9, 10, 12, 16
Explanation :
71307 = 2^0 + 2^1 + 2^3 + 2^7 +
        2^9 + 2^10 + 2^12 + 2^16

Input : 1213
Output : 0, 2, 3, 4, 5, 7, 10
Explanation : 
1213 = 2^0 + 2^2 + 2^3 + 2^4 + 
       2^5 + 2^7 + 2^10

Approach : 
Every number can be described in powers of 2. 
Example : 29 = 2^0 + 2^2 + 2^3 + 2^4.
2^0 ( exponent of 2 is ‘0’) 0 
2^2 ( exponent of 2 is ‘2’) 1 
2^3 ( exponent of 2 is ‘3’) 3 
2^4 ( exponent of 2 is ‘4’) 4
Convert each number into its binary equivalent by pushing remainder of given number, when divided by 2 till it is greater than 0, to vector. Now, Iterate through its binary equivalent and whenever there is set bit, just print the i-th value(iteration number). 

Application : 
Hamming Code : Hamming Code is an error correcting code which can detect and correct one bit error. This pattern is also used in Hamming code error detection where parity bits store the XOR of numbers on the basis of LSB(Least Significant bit), where numbers are assigned in blocks and you need to find the blocks where the sum of power of 2 resulting to given number exists.



Below is the image to show the blocks with given numbers.  

Below is the implementation of above approach : 




// CPP program to find the
// blocks for given number.
#include <bits/stdc++.h>
using namespace std;
 
void block(long int x)
{
    vector<long int> v;
     
    // Converting the decimal number
    // into its binary equivalent.
    cout << "Blocks for " << x << " : ";
    while (x > 0)
    {
        v.push_back(x % 2);
        x = x / 2;
    }
 
    // Displaying the output when
    // the bit is '1' in binary
    // equivalent of number.
    for (int i = 0; i < v.size(); i++)
    {
        if (v[i] == 1)
        {
            cout << i;
            if (i != v.size() - 1)
                cout << ", ";
        }
    }
    cout << endl;
}
 
// Driver Function
int main()
{
    block(71307);
    block(1213);
    block(29);
    block(100);
    return 0;
}




// Java program to find the
// blocks for given number.
import java.util.*;
 
class GFG {
 
static void block(long x)
{
    ArrayList<Integer> v = new ArrayList<Integer>();
     
    // Convert decimal number to
    // its binary equivalent
    System.out.print("Blocks for "+x+" : ");
    while (x > 0)
    {
        v.add((int)x % 2);
        x = x / 2;
    }
 
    // Displaying the output when
    // the bit is '1' in binary
    // equivalent of number.
    for (int i = 0; i < v.size(); i++)
    {
        if (v.get(i) == 1)
        {
        System.out.print(i);
            if (i != v.size() - 1)
            System.out.print( ", ");
        }
    }
System.out.println();
}
 
// Driver Code
public static void main(String args[])
{
    block(71307);
    block(1213);
    block(29);
    block(100);
}
}
 
// This code is contributed by Arnab Kundu.




# Python3 program to find the
# blocks for given number.
def block(x):
     
    v = []
     
    # Converting the decimal number
    # into its binary equivalent.
    print ("Blocks for %d : " %x, end="")
    while (x > 0):
        v.append(int(x % 2))
        x = int(x / 2)
 
    # Displaying the output when
    # the bit is '1' in binary
    # equivalent of number.
    for i in range(0, len(v)):
        if (v[i] == 1):
            print (i, end = "")
            if (i != len(v) - 1):
                print (", ", end = "")
    print ("\n")
 
block(71307)
block(1213)
block(29)
block(100)
 
# This code is contributed by Manish
# Shaw (manishshaw1)




// C# program to find the
// blocks for given number.
using System;
using System.Collections.Generic;
 
class GFG {
 
    static void block(long x)
    {
        List<int> v = new List<int>();
     
        // Convert decimal number to
        // its binary equivalent
        Console.Write("Blocks for " + x + " : ");
         
        while (x > 0)
        {
            v.Add((int)x % 2);
            x = x / 2;
        }
     
        // Displaying the output when
        // the bit is '1' in binary
        // equivalent of number.
        for (int i = 0; i < v.Count; i++)
        {
            if (v[i] == 1)
            {
                Console.Write(i);
                 
                if (i != v.Count - 1)
                    Console.Write(", ");
            }
        }
     
        Console.WriteLine();
    }
     
    // Driver Code here
    public static void Main()
    {
        block(71307);
        block(1213);
        block(29);
        block(100);
    }
}
 
// This code is contributed by Ajit.




<?php
// PHP program to find the
// blocks for given number.
 
function block($x)
{
    $v = array();
 
    // Convert decimal number to
    // its binary equivalent
    echo 'Blocks for ' .$x.' : ';
     
    while ($x > 0)
    {
        array_push($v,intval($x % 2));
        $x = intval($x / 2);
    }
 
    // Displaying the output when
    // the bit is '1' in binary
    // equivalent of number.
    for ($i = 0; $i < sizeof($v); $i++)
    {
        if ($v[$i] == 1)
        {
            print $i;
             
            if ($i != sizeof($v) - 1)
                echo ', ';
        }
    }
 
    echo "\n";
}
 
// Driver Code
block(71307);
block(1213);
block(29);
block(100);
 
// This code is contributed
// by Manish Shaw (manishshaw1)
?>




<script>
 
// Javascript program to find the
// blocks for given number.
function block(x)
{
    let v = [];
   
    // Convert decimal number to
    // its binary equivalent
    document.write("Blocks for " + x + " : ");
       
    while (x > 0)
    {
        v.push(x % 2);
        x = parseInt(x / 2, 10);
    }
   
    // Displaying the output when
    // the bit is '1' in binary
    // equivalent of number.
    for(let i = 0; i < v.length; i++)
    {
        if (v[i] == 1)
        {
            document.write(i);
               
            if (i != v.length - 1)
                document.write(", ");
        }
    }
    document.write("</br>");
}
 
// Driver code
block(71307);
block(1213);
block(29);
block(100);
 
// This code is contributed by mukesh07
 
</script>

Output: 
Blocks for 71307 : 0, 1, 3, 7, 9, 10, 12, 16
Blocks for 1213 : 0, 2, 3, 4, 5, 7, 10
Blocks for 29 : 0, 2, 3, 4
Blocks for 100 : 2, 5, 6

 

Time Complexity: O(log2n)   

Auxiliary Space: O(log2n)

Another Approach( Using Binary search )  :                                                                                                                      

1. We will generate array a[] of all value from pow(2,0) to pow(2,k) , where k is the largest power of 2 such that pow(2,k) <= num .                               2. Then use binary search upper_bound function to find largest value in array a[] such that value <= num .                    
3. Then reduce num to num-val                                                                                                                                            
4. We will do this operation till num become 0.                                                                                                                      
5. Finally , print all power of 2 required to make num

Below is the implementation of the above approach :




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
//Function to find minimum power of 2 required
// to make x
void block(long int x)
{
   int k; int i=0; long int val=pow(2,i);
   vector<long int> v;
  //for storing all power of 2 such pow(2,i) <= x
   
   while(val<=x)
   
      v.push_back(val);
      k=i; i++;
      val=pow(2,i);
      //Generating all values such that
      //pow(2,i) <= x
    }
     
    // Performing operation till num become 0
    set<int> ans;
    while(x!=0)
    {
      int index = upper_bound(v.begin(),v.end(),x)-v.begin();
       index--;// Now v[index] <= x and v[index+1] > x
      ans.insert(index); // Adding power in ans
      x = x - v[index];//reducing x to x-v[index]
    }
    
    for(auto val:ans)
    {
     cout<<val<<", ";}//printing  power of 2 required
                      // to make x
     cout<<endl;
}
 
// Driver Code
int main()
{  
    //Function call
    cout<<"Blocks for 71307: ";block(71307);
    cout<<"Blocks for 1213: ";block(1213);
    cout<<"Blocks for 29: ";block(29);
    cout<<"Blocks for 100: ";block(100);
    return 0;
}
 
// This code is contributed by nikhilsainiofficial546




// Java Code
 
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG
{
    //Function to find minimum power of 2 required
    // to make x
    static void block(long x)
    {
        int k; int i=0; long val=(long) Math.pow(2,i);
        Vector<Long> v = new Vector<Long>();
        //for storing all power of 2 such pow(2,i) <= x
 
        while(val<=x)
        
            v.add(val);
            k=i; i++;
            val=(long) Math.pow(2,i);
            //Generating all values such that
            //pow(2,i) <= x
        }
         
        // Performing operation till num become 0
        Set<Integer> ans = new HashSet<Integer>();
        while(x!=0)
        {
            int index = Collections.binarySearch(v,x);
            if(index<0)
            {
                index = -index - 1;
                index--; // Now v[index] <= x and v[index+1] > x
            }
            ans.add(index);// Adding power in ans
            x = x - v.get(index);//reducing x to x-v[index]
        }
        
        for(int va:ans)
        {
            System.out.print(va+", ");//printing  power of 2 required
                                // to make x
        }
        System.out.println();
    }
 
    // Driver Code
    public static void main (String[] args)
    {  
        //Function call
        System.out.print("Blocks for 71307: "); block(71307);
        System.out.print("Blocks for 1213: "); block(1213);
        System.out.print("Blocks for 29: "); block(29);
        System.out.print("Blocks for 100: "); block(100);
    }
}




import math
import bisect
# Function to find minimum power of 2 required to make x
def block(x):
    i = 0
    val = math.pow(2, i)
    v = []
    # for storing all power of 2 such pow(2,i) <= x
    while val <= x:
        v.append(val)
        i += 1
        val = math.pow(2, i)
        # Generating all values such that pow(2,i) <= x
     
    # Performing operation till num become 0
    ans = set()
    while x != 0:
        index = bisect.bisect_right(v, x) - 1
        # Now v[index] <= x and v[index+1] > x
        ans.add(index)
        # Adding power in ans
        x = x - v[index]
        # reducing x to x-v[index]
    
    # printing power of 2 required to make x
    print("Blocks for {}: ".format(x), end="")
    for val in ans:
        print(val, end=", ")
    print()
 
# Driver Code
if __name__ == "__main__":
    # Function call
    block(71307)
    block(1213)
    block(29)
    block(100)




using System;
using System.Collections.Generic;
 
class GFG
{
    //Function to find minimum power of 2 required
    // to make x
    static void Block(long x)
    {
        int k; int i = 0; long val = (long) Math.Pow(2, i);
        List<long> v = new List<long>();
        //for storing all power of 2 such pow(2,i) <= x
 
        while (val <= x)
        
            v.Add(val);
            k = i; i++;
            val = (long) Math.Pow(2, i);
            //Generating all values such that
            //pow(2,i) <= x
        }
         
        // Performing operation till num become 0
        HashSet<int> ans = new HashSet<int>();
        while (x != 0)
        {
            int index = v.BinarySearch(x);
            if (index < 0)
            {
                index = ~index - 1;
                // Now v[index] <= x and v[index+1] > x
            }
            ans.Add(index);// Adding power in ans
            x = x - v[index];//reducing x to x-v[index]
        }
        
        Console.Write("Blocks for {0}: ", x);
        //printing  power of 2 required to make x
        foreach (int va in ans)
        {
            Console.Write("{0}, ", va);
        }
        Console.WriteLine();
    }
 
    // Driver Code
    static void Main(string[] args)
    {  
        //Function call
        Console.Write("Blocks for 71307: "); Block(71307);
        Console.Write("Blocks for 1213: "); Block(1213);
        Console.Write("Blocks for 29: "); Block(29);
        Console.Write("Blocks for 100: "); Block(100);
    }
}




//Function to find minimum power of 2 required to make x
function block(x) {
  let i = 0;
  let val = Math.pow(2, i);
  let v = [];
  //for storing all power of 2 such pow(2,i) <= x
  while (val <= x) {
    v.push(val);
    i++;
    val = Math.pow(2, i);
    //Generating all values such that pow(2,i) <= x
  }
 
  // Performing operation till num become 0
  let ans = new Set();
  while (x != 0) {
    let index = v.findIndex((element) => element > x);
    if (index === -1) {
      index = v.length - 1;
    } else {
      index--;
    }
    // Now v[index] <= x and v[index+1] > x
    ans.add(index); // Adding power in ans
    x = x - v[index]; //reducing x to x-v[index]
  }
 
  console.log('Blocks for ' + x + ': ' + [...ans].join(', ')); //printing power of 2 required to make x
}
 
// Driver Code
block(71307);
block(1213);
block(29);
block(100);

Output
Blocks for 71307: 0, 1, 3, 7, 9, 10, 12, 16, 
Blocks for 1213: 0, 2, 3, 4, 5, 7, 10, 
Blocks for 29: 0, 2, 3, 4, 
Blocks for 100: 2, 5, 6, 

Time Complexity: O(logn) 
Auxiliary Space: O(logn)


Article Tags :