Pernicious Number


A number is considered to be pernicious if the number is a positive integer and the number of set bits in its binary expansion are prime. The first pernicious number is 3, as 3 = (11)2. It can be seen that the number of set bits in the binary representation of 3 are 2, which is a prime number.

The first 10 pernicious numbers are 3, 5, 6, 7, 9, 10, 11, 12, 13, 14. Interestingly, powers of 2 can never be pernicious since they always have only 1 set bit. 1 is not a prime number. On the other hand, all the numbers that can be represented by 2n + 1, where n is any natural number, will always be pernicious because they will have 2 set bits and as we know 2 is a prime number.

Keeping these properties of a pernicious number in mind, the following article discusses an approach to check whether a number is pernicious or not.

Problem Statement

This problem aims to check whether the given number, n, is a pernicious number i.e. it is a positive number with a prime number of set bits in its binary expansion.

Examples

Input: 37
Output: Pernicious

Explanation

The binary representation of 37 = 100101.

Number of set bits = 3

Since 3 is a prime number, 37 is a pernicious number.

Input: 22
Output: Pernicious

Explanation

The binary representation of 22 = 10110.

Number of set bits = 3.

Since 3 is a prime number, 22 is a pernicious number.

Input: 71
Output: Not Pernicious

Explanation

The binary representation of 71 = 1000111.

Number of set bits = 4.

Since 4 is not a prime number, 71 is not a pernicious number.

Input: 64
Output: Not Pernicious

Explanation

The binary representation of 64 = 1000000.

Number of set bits = 1.

Since 64 = 26, i.e. it is a power of 2, it has 1 set bit. As 1 is not a prime number, 64 is not a pernicious number.

Solution Approach

We must know whether the number of set bits is prime in order to decide whether a number is pernicious or not. The major task at hand is counting the number of set bits in the number's binary expansion. The following method can be used to count the set bits and then determine whether the outcome is prime.

The approach consists of the following steps −

  • Iterate over all the bits of the number using a loop and a right shift operator.

  • If the bit value is 1, increment count of set bits by one.

  • Check if the final value of count is a prime number or not.

  • Display the answer.

Algorithm

Function is_prime()

  • if (n < 2)

    • return false

  • for (i from 2 to √a)

    • if (a % i == 0)

        return false

  • return true

Function count_set_bits()

  • Initialise counter = 0

  • while (n > 0)

  • if ((n & 1) > 0)

  • counter = counter + 1

  • n = n >> 1

  • return counter

Function is_pernicious()

  • Initialise counter

  • counter = count_set_bits(n)

  • if (is_prime(counter) == true)

    • return true

  • else

    • return false

Function main()

  • Initialise n

  • if (is_pernicious())

    • cout << “Pernicious Number”

  • else

    • cout << “Non-Pernicious Number”

  • Print output

Example: C++ Program

The programme determines whether or not a number is pernicious using the function

is_pernicious()

. It analyzes the least significant bit in every iteration of the loop by right shifting the value of n at the end of each iteration in the function

count_set_bits()

. It then calls the function

is_prime()

to gather if the count of set bits is prime or not.

#include <iostream>
using namespace std;
// this function counts the number of set bits by analyzing the rightmost bit using a while loop till n > 0.
// it performs logical & operation between 1 and n to determine if the rightmost bit is set or not.
// if it is set, count is incremented by 1
// right shift the value of n to make the bit left of the rightmost bit, the new rightmost bit.
int count_set_bits(int n){
   int count = 0;
   while (n > 0){
   
      // if the rightmost bit is 1: increment count
      if ((n & 1) > 0){
         count++;
      }
      
      // right shift the value of n to examine the next least significant bit
      n = n >> 1;
   }
   return count;
}

// this function determines if count of set bits in the given number is prime
bool is_prime(int count){
   if (count < 2)
   return false;
   for (int i = 2; i * i < count; i++){
      if (count % i == 0)
      return false;
   }
   return true;
}

// this functions states if count of set bits is prime -> pernicious
bool is_pernicious(int n){
   int count;
   count = count_set_bits(n);
   
   // if count is prime return true
   if (is_prime(count)){
      return true;
   }
   return false;
}

// main function
int main(){
   int n = 11;
   if (is_pernicious(n)){
      cout << n <<" is Pernicious Number";
   }
   else{
      cout << n << " is Non-Pernicious Number";
   }
   return 0;
}

Output

11 is Pernicious Number

Time and Space Analysis

Time Complexity: O(log(n) + sqrt(count)). In the function count_set_bits() the loop is executed log(n) times as we analyze the number bit by bit. The function is_prime() takes O(sqrt(count)) time to check whether count is prime or not. Both these functions are called once during the execution.

Space Complexity: O(1), since no auxiliary space is used in the implementation. The algorithm always uses constant space irrespective of the input number.

Conclusion

Pernicious numbers are an interesting mathematical concept and they can be easily and efficiently identified using the approach discussed above. The article also presents the algorithm to be used, the c++ program solution along with time and space complexity analysis.

Updated on: 17-Aug-2023

76 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements