Given an integer n, check whether it is Bleak or not. A number 'n' is called Bleak if it cannot be represented as sum of a positive number x and count of set bits in x, i.e., x + countSetBits(x) is not equal to n for any non-negative number x.
Examples:
Input: n = 3
Output: false
Explanation: For x = 2, countSetBits(2) = 1
2 + 1 = 3
So, 3 is not Bleak.
Input: n = 4
Output: true
Explanation:
There is no value of x such that x + countSetBits(x) = 4
So, 4 is Bleak.
Table of Content
Naive Approach - O(n log n) Time and O(1) Space
Checks all values of x from 1 to n−1. If any x satisfies x + countSetBits(x) = n, then n is not Bleak. If no such x exists, then n is Bleak.
Dry run for n = 4
- Check all values of x from 1 to 3
- x = 1, countSetBits(1) = 1 then 1 + 1 = 2 != 4
- x = 2, countSetBits(2) = 1 then 2 + 1 != 4
- x = 3, countSetBits(3) = 2 then 3 + 2 != 4
- No value satisfies the condition, so return true
Final answer is true (4 is Bleak).
#include <iostream>
using namespace std;
// Counts set bits in the binary
// representation of a number
int countSetBits(int x)
{
int count = 0;
while (x) {
// remove lowest set bit
x &= (x - 1);
count++;
}
return count;
}
bool isBleak(int n)
{
// Check for all numbers x < n
for (int x = 1; x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
int main()
{
isBleak(3) ? cout << "true\n" : cout << "false\n";
isBleak(4) ? cout << "true\n" : cout << "false\n";
return 0;
}
import java.io.*;
class GFG {
// Counts set bits in the binary
// representation of a number
static int countSetBits(int x)
{
int count = 0;
while (x != 0) {
// remove lowest set bit
x &= (x - 1);
count++;
}
return count;
}
static boolean isBleak(int n)
{
// Check for all numbers x < n
for (int x = 1; x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
public static void main(String args[])
{
System.out.println(isBleak(3));
System.out.println(isBleak(4));
}
}
# Counts set bits in the binary
# representation of a number
def countSetBits(x):
count = 0
while (x) :
# remove lowest set bit
x = x & (x-1)
count = count + 1
return count
def isBleak(n):
# Check for all numbers x < n
for x in range(1, n) :
if (x + countSetBits(x) == n) :
return False
return True
if __name__ == "__main__":
print(isBleak(3))
print(isBleak(4))
using System;
class GFG {
// Counts set bits in the binary
// representation of a number
static int countSetBits(int x)
{
int count = 0;
while (x != 0) {
// remove lowest set bit
x &= (x - 1);
count++;
}
return count;
}
static bool isBleak(int n)
{
// Check for all numbers x < n
for (int x = 1; x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
public static void Main()
{
Console.WriteLine(isBleak(3));
Console.WriteLine(isBleak(4));
}
}
// Counts set bits in the binary
// representation of a number
function countSetBits(x)
{
let count = 0;
while (x != 0) {
// remove lowest set bit
x &= (x - 1);
count++;
}
return count;
}
function isBleak(n)
{
// Check for all numbers x < n
for (let x = 1; x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
// Driver Code
console.log(isBleak(3));
console.log(isBleak(4));
Output
false true
Expected Approach - O(log n * log n) Time and O(1) Space
The maximum number of set bits in any number less than n is at most ceil(log2(n)). So, instead of checking all values, we only need to check numbers in the range n - ceil(log2(n)) to n - 1.
How does this work?
We need to satisfy:
x + countSetBits(x) = nRearranging:
countSetBits(x) = n − xNow, observe that the maximum number of set bits in any number
x < nis limited by the number of bits inx, which is at most:
ceil(log2(n))So:
countSetBits(x) ≤ ceil(log2(n))This gives:
n − x ≤ ceil(log2(n))Rearranging:
x ≥ n − ceil(log2(n))
Dry run for n = 8
- Firstly, find ceil(log2(8)) = 3
- Since countSetBits(x) ≤ 3, we have n − x ≤ 3
So, x ≥ 8 − 3 = 5 - Range reduces to: x from 5 to 7
- x = 5, countSetBits(5) = 2 then 5 + 2 = 7 != 8
- x = 6, countSetBits(6) = 2 then 6 + 2 = 8
- Condition satisfied. So, return false
Final answer is false (8 is not Bleak).
#include <iostream>
using namespace std;
// Counts set bits in the binary
// representation of a number
int countSetBits(int x)
{
unsigned int count = 0;
while (x) {
// remove last set bit
x &= (x - 1);
count++;
}
return count;
}
// Return ceiling of log x in base 2
int ceilLog2(int x)
{
int count = 0;
x--;
while (x > 0) {
// divide by 2
x = x >> 1;
count++;
}
return count;
}
bool isBleak(int n)
{
// Check only last log2(n) numbers before n
for (int x = n - ceilLog2(n); x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
int main()
{
isBleak(3) ? cout << "true\n" : cout << "false\n";
isBleak(4) ? cout << "true\n" : cout << "false\n";
return 0;
}
import java.io.*;
class GFG {
// Counts set bits in the binary
// representation of a number
static int countSetBits(int x)
{
int count = 0;
while (x != 0) {
// remove last set bit
x &= (x - 1);
count++;
}
return count;
}
// Return ceiling of log x in base 2
static int ceilLog2(int x)
{
int count = 0;
x--;
while (x > 0) {
// divide by 2
x = x >> 1;
count++;
}
return count;
}
static boolean isBleak(int n)
{
// Check only last log2(n) numbers before n
for (int x = n - ceilLog2(n); x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
public static void main(String[] args)
{
System.out.println(isBleak(3));
System.out.println(isBleak(4));
}
}
import math
# Counts set bits in the binary
# representation of a number
def countSetBits(x) :
count = 0
while (x) :
# remove last set bit
x = x & (x - 1)
count = count + 1
return count
# Return ceiling of log x in base 2
def ceilLog2(x) :
count = 0
x = x - 1
while (x > 0) :
# divide by 2
x = x >> 1
count = count + 1
return count
def isBleak(n) :
# Check only last log2(n) numbers before n
for x in range((n - ceilLog2(n)), n) :
if (x + countSetBits(x) == n) :
return False
return True
if __name__ == "__main__":
print(isBleak(3))
print(isBleak(4))
using System;
class GFG {
// Counts set bits in the binary
// representation of a number
static int countSetBits(int x)
{
int count = 0;
while (x != 0) {
// remove last set bit
x &= (x - 1);
count++;
}
return count;
}
// Return ceiling of log x in base 2
static int ceilLog2(int x)
{
int count = 0;
x--;
while (x > 0) {
// divide by 2
x = x >> 1;
count++;
}
return count;
}
static bool isBleak(int n)
{
// Check only last log2(n) numbers before n
for (int x = n - ceilLog2(n); x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
public static void Main()
{
Console.WriteLine(isBleak(3));
Console.WriteLine(isBleak(4));
}
}
// Counts set bits in the binary
// representation of a number
function countSetBits(x)
{
let count = 0;
while (x != 0) {
// remove last set bit
x &= (x - 1);
count++;
}
return count;
}
// Return ceiling of log x in base 2
function ceilLog2(x)
{
let count = 0;
x--;
while (x > 0) {
// divide by 2
x = x >> 1;
count++;
}
return count;
}
function isBleak(n)
{
// Check only last log2(n) numbers before n
for (let x = n - ceilLog2(n); x < n; x++)
if (x + countSetBits(x) == n)
return false;
return true;
}
// Driver Code
console.log(isBleak(3));
console.log(isBleak(4));
Output
false true
Note: Most languages provide built-in functions to count set bits, which can simplify the implementation and improve readability.
// C++ program to demonstrate __builtin_popcount()
#include <iostream>
using namespace std;
int main()
{
cout << __builtin_popcount(4) << endl;
cout << __builtin_popcount(15);
return 0;
}
// Java program to demonstrate Integer.bitCount()
import java.util.*;
class GFG{
public static void main(String[] args)
{
System.out.print(Integer.bitCount(4) +"\n");
System.out.print(Integer.bitCount(15));
}
}
# Python program to demonstrate x.bitCount()
if __name__ == '__main__':
x = 4;
y = 15;
print((4).bit_count())
print((15).bit_count())
// C# program to demonstrate BitOperations.PopCount((uint)x)
using System;
using System.Numerics;
public class GFG{
public static void Main(String[] args)
{
Console.WriteLine(BitOperations.PopCount((uint)4));
Console.WriteLine(BitOperations.PopCount((uint)15));
}
}
Output
1 4
Time Complexity: O(log n)
Auxiliary Space: O(1)