Open In App

Count of N digit numbers which contains all single digit primes

Given a positive integer N, the task is to count the number of N-digit numbers which contain all single digit primes.

Examples:



Input: N = 4
Output: 24
Explanation: The number of single digit primes is 4 i.e.{2, 3, 5, 7}. Hence number of ways to arrange 4 numbers in 4 places is 4! = 24.

Input: N = 5
Output: 936



Naive Approach: The simplest approach to solve the given problem is to generate all possible N-digit numbers and count those numbers which contain all single digit prime numbers. After checking for all the numbers, print the value of the count as the resultant total count of numbers.

Time Complexity: O(N *10N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized by using Dynamic Programming because it has overlapping subproblems and optimal substructure. The subproblems can be stored in dp[][] table using memoization where dp[index][mask] stores the answer from the indexthposition till the end, where mask is used to store the count of distinct primes included till now. Follow the steps below to solve the problem:

Below is the implementation of the above approach:




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Stores the dp-states
int dp[100][1 << 4];
 
// Stores the index of prime numbers
map<int, int> primeIndex;
 
int countOfNumbers(int index, int mask, int N)
{
    // If index = N+1
    if (index == N + 1) {
 
        // Find count of distinct
        // prime numbers by counting
        // number of set bits.
        int countOfPrimes = __builtin_popcount(mask);
 
        // If count of distinct
        // prime numbers is equal to 4
        // return 1.
        if (countOfPrimes == 4) {
            return 1;
        }
        return 0;
    }
 
    int& val = dp[index][mask];
 
    // If the state has
    // already been computed
    if (val != -1) {
        return val;
    }
 
    val = 0;
 
    // If current position is 1,
    // then any digit from [1-9] can be placed.
    // If N = 1, 0 can be also placed.
    if (index == 1) {
        for (int digit = (N == 1 ? 0 : 1); digit <= 9;
             ++digit) {
 
            // If the digit is a prime number,
            // set the index of the
            // digit to 1 in the bitmask.
            if (primeIndex.find(digit)
                != primeIndex.end()) {
                val += countOfNumbers(
                    index + 1,
                    mask | (1 << primeIndex[digit]), N);
            }
 
            else {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // For remaining positions,
    // any digit from [0-9] can be placed
    else {
        for (int digit = 0; digit <= 9; ++digit) {
 
            // If the digit is a prime number,
            // set the index of the
            // digit to 1 in the bitmask.
            if (primeIndex.find(digit)
                != primeIndex.end()) {
                val += countOfNumbers(
                    index + 1,
                    mask | (1 << primeIndex[digit]), N);
            }
 
            else {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // Return the answer.
    return val;
}
 
// Driver Code
int main()
{
    // Initializing dp array with -1.
    memset(dp, -1, sizeof dp);
 
    // Indexing prime numbers in
    // ascending order
    primeIndex[2] = 0;
    primeIndex[3] = 1;
    primeIndex[5] = 2;
    primeIndex[7] = 3;
 
    // Given Input
    int N = 4;
 
    // Function call.
    cout << countOfNumbers(1, 0, N);
 
    return 0;
}




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
public static int[][] dp = new int[100][(1 << 4)];
 
// Stores the index of prime numbers
public static HashMap<Integer,
                      Integer> primeIndex = new HashMap<>();
 
public static int countSetBits(int n)
{
    int count = 0;
     
    while (n > 0)
    {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
 
public static int countOfNumbers(int index, int mask,
                                 int N)
{
     
    // If index = N+1
    if (index == N + 1)
    {
         
        // Find count of distinct
        // prime numbers by counting
        // number of set bits.
        int countOfPrimes = countSetBits(mask);
 
        // If count of distinct
        // prime numbers is equal to 4
        // return 1.
        if (countOfPrimes == 4)
        {
            return 1;
        }
        return 0;
    }
 
    int val = dp[index][mask];
 
    // If the state has
    // already been computed
    if (val != -1)
    {
        return val;
    }
 
    val = 0;
 
    // If current position is 1, then any
    // digit from [1-9] can be placed.
    // If N = 1, 0 can be also placed.
    if (index == 1)
    {
        for(int digit = (N == 1 ? 0 : 1);
                digit <= 9; ++digit)
        {
             
            // If the digit is a prime number,
            // set the index of the digit to 1
            // in the bitmask.
            if (primeIndex.containsKey(digit))
            {
                int newMask = mask | (1 << primeIndex.get(digit));
                val += countOfNumbers(index + 1,
                                      newMask, N);
            }
 
            else
            {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // For remaining positions,
    // any digit from [0-9] can be placed
    else
    {
        for(int digit = 0; digit <= 9; ++digit)
        {
             
            // If the digit is a prime number,
            // set the index of the digit to 1
            // in the bitmask.
            if (primeIndex.containsKey(digit))
            {
                int newMask = mask | (1 << primeIndex.get(digit));
                val += countOfNumbers(index + 1, newMask, N);
            }
            else
            {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // Return the answer.
    return val;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Initializing dp array with -1.
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < (1 << 4); j++)
        {
            dp[i][j] = -1;
        }
    }
 
    // Indexing prime numbers in
    // ascending order
    primeIndex.put(2, 0);
    primeIndex.put(3, 1);
    primeIndex.put(5, 2);
    primeIndex.put(7, 3);
 
    // Given Input
    int N = 4;
 
    // Function call
    System.out.println(countOfNumbers(1, 0, N));
}
}
 
// This code is contributed by maddler




# Python3 program for the above approach
 
# Stores the dp-states
dp = [[-1 for i in range(1<<4)] for j in range(100)]
 
# Stores the index of prime numbers
primeIndex = {}
 
def  countSetBits(n):
    count = 0
    while (n):
        count += n & 1
        n >>= 1
    return count
 
def countOfNumbers(index, mask, N):
    # If index = N+1
    if (index == N + 1):
 
        # Find count of distinct
        # prime numbers by counting
        # number of set bits.
        countOfPrimes = countSetBits(mask);
 
        # If count of distinct
        # prime numbers is equal to 4
        # return 1.
        if (countOfPrimes == 4):
            return 1
        return 0
 
    val = dp[index][mask]
 
    # If the state has
    # already been computed
    if (val != -1):
        return val
 
    val = 0
 
    # If current position is 1,
    # then any digit from [1-9] can be placed.
    # If N = 1, 0 can be also placed.
    if (index == 1):
        digit = 0 if N == 1 else 1
        while(digit <= 9):
            # If the digit is a prime number,
            # set the index of the
            # digit to 1 in the bitmask.
            if (digit in primeIndex):
                val += countOfNumbers(index + 1,mask | (1 << primeIndex[digit]), N)
 
            else:
                val += countOfNumbers(index + 1, mask, N)
 
            digit += 1
 
    # For remaining positions,
    # any digit from [0-9] can be placed
    else:
        for digit in range(10):
            # If the digit is a prime number,
            # set the index of the
            # digit to 1 in the bitmask.
            if (digit in primeIndex):
                val += countOfNumbers(index + 1,mask | (1 << primeIndex[digit]), N)
 
            else:
                val += countOfNumbers(index + 1, mask, N)
 
    # Return the answer.
    return val
 
# Driver Code
if __name__ == '__main__':
    # Initializing dp array with -1.
    # Indexing prime numbers in
    # ascending order
    primeIndex[2] = 0
    primeIndex[3] = 1
    primeIndex[5] = 2
    primeIndex[7] = 3
 
    # Given Input
    N = 4
 
    # Function call.
    print(countOfNumbers(1, 0, N))
     
    # This code is contributed by ipg2016107.




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
public static int[,] dp = new int[100,(1 << 4)];
 
// Stores the index of prime numbers
public static Dictionary<int,int> primeIndex = new Dictionary<int,int>();
 
public static int countSetBits(int n)
{
    int count = 0;
     
    while (n > 0)
    {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
 
public static int countOfNumbers(int index, int mask,
                                 int N)
{
     
    // If index = N+1
    if (index == N + 1)
    {
         
        // Find count of distinct
        // prime numbers by counting
        // number of set bits.
        int countOfPrimes = countSetBits(mask);
 
        // If count of distinct
        // prime numbers is equal to 4
        // return 1.
        if (countOfPrimes == 4)
        {
            return 1;
        }
        return 0;
    }
 
    int val = dp[index,mask];
 
    // If the state has
    // already been computed
    if (val != -1)
    {
        return val;
    }
 
    val = 0;
 
    // If current position is 1, then any
    // digit from [1-9] can be placed.
    // If N = 1, 0 can be also placed.
    if (index == 1)
    {
        for(int digit = (N == 1 ? 0 : 1);
                digit <= 9; ++digit)
        {
             
            // If the digit is a prime number,
            // set the index of the digit to 1
            // in the bitmask.
            if (primeIndex.ContainsKey(digit))
            {
                int newMask = mask | (1 << primeIndex[digit]);
                val += countOfNumbers(index + 1,
                                      newMask, N);
            }
 
            else
            {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // For remaining positions,
    // any digit from [0-9] can be placed
    else
    {
        for(int digit = 0; digit <= 9; ++digit)
        {
             
            // If the digit is a prime number,
            // set the index of the digit to 1
            // in the bitmask.
            if (primeIndex.ContainsKey(digit))
            {
                int newMask = mask | (1 << primeIndex[digit]);
                val += countOfNumbers(index + 1, newMask, N);
            }
            else
            {
                val += countOfNumbers(index + 1, mask, N);
            }
        }
    }
 
    // Return the answer.
    return val;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Initializing dp array with -1.
    for(int i = 0; i < 100; i++)
    {
        for(int j = 0; j < (1 << 4); j++)
        {
            dp[i,j] = -1;
        }
    }
 
    // Indexing prime numbers in
    // ascending order
    primeIndex.Add(2, 0);
    primeIndex.Add(3, 1);
    primeIndex.Add(5, 2);
    primeIndex.Add(7, 3);
 
    // Given Input
    int N = 4;
 
    // Function call
    Console.WriteLine(countOfNumbers(1, 0, N));
}
}
 
// This code is contributed by shikhasingrajput




<script>
// Javascript program for the above approach
 
let dp = new Array(100).fill(0).map(() => new Array(1 << 4));
 
// Stores the index of prime numbers
let primeIndex = new Map();
 
function countSetBits(n) {
  let count = 0;
 
  while (n > 0) {
    count += n & 1;
    n >>= 1;
  }
  return count;
}
 
function countOfNumbers(index, mask, N) {
  // If index = N+1
  if (index == N + 1) {
    // Find count of distinct
    // prime numbers by counting
    // number of set bits.
    let countOfPrimes = countSetBits(mask);
 
    // If count of distinct
    // prime numbers is equal to 4
    // return 1.
    if (countOfPrimes == 4) {
      return 1;
    }
    return 0;
  }
 
  let val = dp[index][mask];
 
  // If the state has
  // already been computed
  if (val != -1) {
    return val;
  }
 
  val = 0;
 
  // If current position is 1, then any
  // digit from [1-9] can be placed.
  // If N = 1, 0 can be also placed.
  if (index == 1) {
    for (let digit = N == 1 ? 0 : 1; digit <= 9; ++digit) {
      // If the digit is a prime number,
      // set the index of the digit to 1
      // in the bitmask.
      if (primeIndex.has(digit)) {
        let newMask = mask | (1 << primeIndex.get(digit));
        val += countOfNumbers(index + 1, newMask, N);
      } else {
        val += countOfNumbers(index + 1, mask, N);
      }
    }
  }
 
  // For remaining positions,
  // any digit from [0-9] can be placed
  else {
    for (let digit = 0; digit <= 9; ++digit) {
      // If the digit is a prime number,
      // set the index of the digit to 1
      // in the bitmask.
      if (primeIndex.has(digit)) {
        let newMask = mask | (1 << primeIndex.get(digit));
        val += countOfNumbers(index + 1, newMask, N);
      } else {
        val += countOfNumbers(index + 1, mask, N);
      }
    }
  }
 
  // Return the answer.
  return val;
}
 
// Driver Code
 
// Initializing dp array with -1.
for (let i = 0; i < 100; i++) {
  for (let j = 0; j < 1 << 4; j++) {
    dp[i][j] = -1;
  }
}
 
// Indexing prime numbers in
// ascending order
primeIndex.set(2, 0);
primeIndex.set(3, 1);
primeIndex.set(5, 2);
primeIndex.set(7, 3);
 
// Given Input
let N = 4;
 
// Function call
document.write(countOfNumbers(1, 0, N));
 
// This code is contributed by gfgking
 
</script>

Output
24

Time Complexity: O(N *10 * 24)
Auxiliary Space: O(N * 24


Article Tags :