Given a positive integer n, the task is to count the number of n digits 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
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.
Using recursion
To solve this, we generate all possible n-digit numbers recursively while keeping track of which single-digit primes have been encountered so far using a bitmask. Since there are only 4 single-digit primes, we can represent their presence using 4 bits:
Mapping primes to bits:
- 2 is mapped to bit 0
- 3 is mapped to bit 1
- 5 is mapped to bit 2
- 7 is mapped to bit 3
The bitmask allows us to efficiently track these primes. For example, if the current digit is 7, we update the bitmask as mask | (1<<3) where (1<<3) set 3rd bit to 1. since 7 is mapped to 3, we set 3rd bit to 1.
Recursive Relation:
For a given index i, we iterate over all digits from 0 to 9, take the summation of it.
countOfNumbers(i, mask, n) = countOfNumbers(i+1, newMask, n) for all value of d from 0 to 9.
- If d is a prime number (d â {2, 3, 5, 7}), update the bitmask to include d:
newMask = (mask | (1<<primeIndex[d]))
where, primeIndex[d] is the mapped number given to d (primeIndex[2] = 0, primeIndex[3] = 1, primeIndex[5] = 2, primeIndex[7]=3)- otherwise, the bitmak remains unchanged:
newMask = maskBase Case:
if i = n+1 where n is the total number of digits.
countOfNumbers(i, mask, n) = 1 , if count of set bits in mask is 4(all the single digit prime number is present) otherwise 0.
// C++ program to count the valid number
// using recusion
#include <bits/stdc++.h>
using namespace std;
int countOfNumbers(int index, int mask, int n,
map<int, int> &primeIndex) {
// If index == n+1
if (index == n + 1) {
// Count the number of set bits in the mask
int countOfPrimes = __builtin_popcount(mask);
// If all 4 single-digit primes are present, return 1
return (countOfPrimes == 4) ? 1 : 0;
}
int val = 0;
// If current position is 1, digits [1-9] are allowed
// If n == 1, 0 can also be placed
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.find(digit) != primeIndex.end()) {
val += countOfNumbers(index + 1, mask |
(1 << primeIndex.at(digit)), n, primeIndex);
}
else {
val += countOfNumbers(index + 1, mask, n, primeIndex);
}
}
}
// For all other positions, digits [0-9] are allowed
else {
for (int digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.find(digit) != primeIndex.end()) {
val += countOfNumbers(index + 1, mask |
(1 << primeIndex.at(digit)), n, primeIndex);
}
else {
val += countOfNumbers(index + 1,
mask, n, primeIndex);
}
}
}
// Return the result
return val;
}
int main() {
map<int, int> primeIndex;
primeIndex[2] = 0;
primeIndex[3] = 1;
primeIndex[5] = 2;
primeIndex[7] = 3;
int n = 4;
cout << countOfNumbers(1, 0, n, primeIndex);
return 0;
}
// Java program to count the valid number
// using recusion
import java.util.HashMap;
import java.util.Map;
class GfG {
static int
countOfNumbers(int index, int mask, int n,
Map<Integer, Integer> primeIndex) {
// If index == n+1
if (index == n + 1) {
// Count the number of set bits in the mask
int countOfPrimes = Integer.bitCount(mask);
// If all 4 single-digit primes are present,
// return 1
return (countOfPrimes == 4) ? 1 : 0;
}
int val = 0;
// If current position is 1, digits [1-9] are
// allowed If n == 1, 0 can also be placed
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9;
++digit) {
// Update mask if the digit is a prime
if (primeIndex.containsKey(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)),
n, primeIndex);
}
else {
val += countOfNumbers(index + 1, mask,
n, primeIndex);
}
}
}
// For all other positions, digits [0-9] are allowed
else {
for (int digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.containsKey(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)),
n, primeIndex);
}
else {
val += countOfNumbers(index + 1, mask,
n, primeIndex);
}
}
}
// Return the result
return val;
}
public static void main(String[] args) {
Map<Integer, Integer> primeIndex = new HashMap<>();
primeIndex.put(2, 0);
primeIndex.put(3, 1);
primeIndex.put(5, 2);
primeIndex.put(7, 3);
int n = 4;
System.out.println(
countOfNumbers(1, 0, n, primeIndex));
}
}
# Python program to count the valid number
# using recusion
def countOfNumbers(index, mask, n, primeIndex):
# If index == n+1
if index == n + 1:
# Count the number of set bits in the mask
countOfPrimes = bin(mask).count('1')
# If all 4 single-digit primes are
# present, return 1
return 1 if countOfPrimes == 4 else 0
val = 0
# If current position is 1, digits [1-9] are allowed
# If n == 1, 0 can also be placed
start = 0 if n == 1 else 1 if index == 1 else 0
for digit in range(start, 10):
# Update mask if the digit is a prime
if digit in primeIndex:
val += countOfNumbers(index + 1, mask
| (1 << primeIndex[digit]), n, primeIndex)
else:
val += countOfNumbers(index + 1, mask, n, primeIndex)
# Return the result
return val
if __name__ == "__main__":
primeIndex = {2: 0, 3: 1, 5: 2, 7: 3}
n = 4
print(countOfNumbers(1, 0, n, primeIndex))
// C# program to count the valid number
// using recusion
using System;
using System.Collections.Generic;
class GfG {
// Function to count the valid numbers
// using recursion
static int
CountOfNumbers(int index, int mask, int n,
Dictionary<int, int> primeIndex) {
// If index == n + 1
if (index == n + 1) {
// Count the number of set bits in the mask
int countOfPrimes = CountSetBits(mask);
// If all 4 single-digit primes are present,
// return 1
return (countOfPrimes == 4) ? 1 : 0;
}
int val = 0;
// If current position is 1, digits [1-9] are
// allowed If n == 1, 0 can also be placed
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9;
++digit) {
// Update mask if the digit is a prime
if (primeIndex.ContainsKey(digit)) {
val += CountOfNumbers(
index + 1,
mask | (1 << primeIndex[digit]), n,
primeIndex);
}
else {
val += CountOfNumbers(index + 1, mask,
n, primeIndex);
}
}
}
// For all other positions, digits [0-9] are allowed
else {
for (int digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.ContainsKey(digit)) {
val += CountOfNumbers(
index + 1,
mask | (1 << primeIndex[digit]), n,
primeIndex);
}
else {
val += CountOfNumbers(index + 1, mask,
n, primeIndex);
}
}
}
// Return the result
return val;
}
static int CountSetBits(int mask) {
int count = 0;
while (mask > 0) {
count += mask & 1;
mask >>= 1;
}
return count;
}
static void Main() {
Dictionary<int, int> primeIndex
= new Dictionary<int, int>{
{ 2, 0 }, { 3, 1 }, { 5, 2 }, { 7, 3 }
};
int n = 4;
Console.WriteLine(
CountOfNumbers(1, 0, n, primeIndex));
}
}
// JavaScript program to count the valid number using
// recusion
function countSetBits(mask) {
let count = 0;
while (mask > 0) {
count += mask & 1;
mask >>= 1;
}
return count;
}
function countOfNumbers(index, mask, n, primeIndex) {
// If index == n+1
if (index === n + 1) {
// Count the number of set bits in the mask
const countOfPrimes = countSetBits(mask);
// If all 4 single-digit primes are present, return
// 1
return countOfPrimes === 4 ? 1 : 0;
}
let val = 0;
// If current position is 1, digits [1-9] are allowed
// If n == 1, 0 can also be placed
const start = (n === 1) ? 0 : (index === 1) ? 1 : 0;
for (let digit = start; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.has(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)), n,
primeIndex);
}
else {
val += countOfNumbers(index + 1, mask, n,
primeIndex);
}
}
// Return the result
return val;
}
const primeIndex = new Map();
primeIndex.set(2, 0);
primeIndex.set(3, 1);
primeIndex.set(5, 2);
primeIndex.set(7, 3);
const n = 4;
console.log(countOfNumbers(1, 0, n, primeIndex));
Output
24
Time Complexity: O(n *10^n)
Auxiliary Space: O(n)
Using Top-Down DP (Memoization)
If notice carefully, we can see that the above recursive function countOfNumbers() also follows the overlapping subproblems property i.e., same substructure solved again and again in different recursion call paths. We can avoid this using the memoization approach. Since there is two parameter that changes in recursive calls so we use a 2D array and initialize it as -1 to indicate that the values are not computed.
// C++ program to count the valid number
// using memoization
#include <bits/stdc++.h>
using namespace std;
int countOfNumbers(int index, int mask, int n,
map<int, int> &primeIndex, vector<vector<int>> &memo) {
// If index == n+1
if (index == n + 1) {
// Count the number of set bits in the mask
int countOfPrimes = __builtin_popcount(mask);
// If all 4 single-digit primes are present, return 1
return (countOfPrimes == 4) ? 1 : 0;
}
if(memo[index][mask]!=-1)
return memo[index][mask];
int val = 0;
// If current position is 1, digits [1-9] are allowed
// If n == 1, 0 can also be placed
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.find(digit) != primeIndex.end()) {
val += countOfNumbers(index + 1, mask |
(1 << primeIndex.at(digit)), n, primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask, n, primeIndex, memo);
}
}
}
// For all other positions, digits
// [0-9] are allowed
else {
for (int digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.find(digit) != primeIndex.end()) {
val += countOfNumbers(index + 1, mask
| (1 << primeIndex.at(digit)), n, primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask, n, primeIndex, memo);
}
}
}
// Return the result
return val;
}
int main() {
map<int, int> primeIndex;
primeIndex[2] = 0;
primeIndex[3] = 1;
primeIndex[5] = 2;
primeIndex[7] = 3;
int n = 4;
vector<vector<int>> memo =
vector<vector<int>>(n + 1, vector<int>(16, -1));
cout << countOfNumbers(1, 0, n, primeIndex, memo);
return 0;
}
// Java program to count the valid number
// using memoization
import java.util.HashMap;
import java.util.Map;
class GfG {
static int
countOfNumbers(int index, int mask, int n,
Map<Integer, Integer> primeIndex,
int[][] memo) {
// If index == n+1
if (index == n + 1) {
// Count the number of set bits in the mask
int countOfPrimes = Integer.bitCount(mask);
// If all 4 single-digit primes are present,
// return 1
return (countOfPrimes == 4) ? 1 : 0;
}
// Check if the result is already computed
// (memoization)
if (memo[index][mask] != -1) {
return memo[index][mask];
}
int val = 0;
// If current position is 1, digits [1-9] are
// allowed If n == 1, 0 can also be placed
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9;
++digit) {
// Update mask if the digit is a prime
if (primeIndex.containsKey(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)),
n, primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask,
n, primeIndex,
memo);
}
}
}
else {
// For all other positions, digits [0-9] are
// allowed
for (int digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.containsKey(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)),
n, primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask,
n, primeIndex,
memo);
}
}
}
// Memoize and return the result
memo[index][mask] = val;
return val;
}
public static void main(String[] args) {
Map<Integer, Integer> primeIndex = new HashMap<>();
primeIndex.put(2, 0);
primeIndex.put(3, 1);
primeIndex.put(5, 2);
primeIndex.put(7, 3);
int n = 4;
int[][] memo = new int[n + 1][1 << 4];
for (int i = 0; i <= n; i++) {
for (int j = 0; j < (1 << 4); j++) {
memo[i][j]
= -1;
}
}
System.out.println(
countOfNumbers(1, 0, n, primeIndex, memo));
}
}
# Python program to count the valid number
# using memoization
def countOfNumbers(index, mask, n, primeIndex, memo):
# If index == n+1
if index == n + 1:
# Count the number of set bits in the mask
countOfPrimes = bin(mask).count('1')
# If all 4 single-digit primes are present,
# return 1
return 1 if countOfPrimes == 4 else 0
# Check if the result is already computed
# (memoization)
if memo[index][mask] != -1:
return memo[index][mask]
val = 0
# If current position is 1, digits [1-9] are allowed
# If n == 1, 0 can also be placed
if index == 1:
for digit in range(0 if n == 1 else 1, 10):
# Update mask if the digit is a prime
if digit in primeIndex:
val += countOfNumbers(index + 1, mask
| (1 << primeIndex[digit]), n, primeIndex, memo)
else:
val += countOfNumbers(index + 1, mask, n, primeIndex, memo)
else:
# For all other positions, digits [0-9] are allowed
for digit in range(10):
# Update mask if the digit is a prime
if digit in primeIndex:
val += countOfNumbers(index + 1, mask
| (1 << primeIndex[digit]), n, primeIndex, memo)
else:
val += countOfNumbers(index + 1, mask, n, primeIndex, memo)
# Memoize and return the result
memo[index][mask] = val
return val
if __name__ == "__main__":
primeIndex = {2: 0, 3: 1, 5: 2, 7: 3}
n = 4
memo = [[-1 for _ in range(1 << 4)] for _ in range(n + 1)]
print(countOfNumbers(1, 0, n, primeIndex, memo))
// C# program to count the valid number using memoization
using System;
using System.Collections.Generic;
class GfG {
static int countSetBits(int number) {
int count = 0;
while (number > 0) {
count += (number & 1);
number >>= 1;
}
return count;
}
static int
countOfNumbers(int index, int mask, int n,
Dictionary<int, int> primeIndex,
int[, ] memo) {
// If index == n+1
if (index == n + 1) {
// Count the number of set bits in the mask
int countOfPrimes = countSetBits(mask);
// If all 4 single-digit primes are present,
// return 1
return countOfPrimes == 4 ? 1 : 0;
}
// Check if the result is already computed
// (memoization)
if (memo[index, mask] != -1) {
return memo[index, mask];
}
int val = 0;
// If current position is 1, digits [1-9] are
// allowed If n == 1, 0 can also be placed
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9;
++digit) {
// Update mask if the digit is a prime
if (primeIndex.ContainsKey(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex[digit]), n,
primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask,
n, primeIndex,
memo);
}
}
}
else {
// For all other positions, digits [0-9] are
// allowed
for (int digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.ContainsKey(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex[digit]), n,
primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask,
n, primeIndex,
memo);
}
}
}
// Memoize and return the result
memo[index, mask] = val;
return val;
}
static void Main() {
Dictionary<int, int> primeIndex
= new Dictionary<int, int>{
{ 2, 0 }, { 3, 1 }, { 5, 2 }, { 7, 3 }
};
int n = 4;
int[, ] memo = new int[n + 1, 1 << 4];
for (int i = 0; i <= n; i++) {
for (int j = 0; j < (1 << 4); j++) {
memo[i, j] = -1;
}
}
Console.WriteLine(
countOfNumbers(1, 0, n, primeIndex, memo));
}
}
// JavaScript program to count the valid number
// using memoization
function countSetBits(number) {
let count = 0;
while (number > 0) {
count += (number & 1);
number >>= 1;
}
return count;
}
function countOfNumbers(index, mask, n, primeIndex, memo) {
// If index == n+1
if (index === n + 1) {
// Count the number of set bits in the mask
const countOfPrimes = countSetBits(mask);
// If all 4 single-digit primes are present, return
// 1
return countOfPrimes === 4 ? 1 : 0;
}
// Check if the result is already computed (memoization)
if (memo[index][mask] !== -1) {
return memo[index][mask];
}
let val = 0;
// If current position is 1, digits [1-9] are allowed
// If n == 1, 0 can also be placed
if (index === 1) {
for (let digit = (n === 1 ? 0 : 1); digit <= 9;
++digit) {
// Update mask if the digit is a prime
if (primeIndex.has(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)), n,
primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask, n,
primeIndex, memo);
}
}
}
else {
// For all other positions, digits [0-9] are allowed
for (let digit = 0; digit <= 9; ++digit) {
// Update mask if the digit is a prime
if (primeIndex.has(digit)) {
val += countOfNumbers(
index + 1,
mask | (1 << primeIndex.get(digit)), n,
primeIndex, memo);
}
else {
val += countOfNumbers(index + 1, mask, n,
primeIndex, memo);
}
}
}
// Memoize and return the result
memo[index][mask] = val;
return val;
}
const primeIndex
= new Map([ [ 2, 0 ], [ 3, 1 ], [ 5, 2 ], [ 7, 3 ] ]);
const n = 4;
const memo = Array.from({length : n + 1},
() => Array(16).fill(-1));
console.log(countOfNumbers(1, 0, n, primeIndex, memo));
Output
24
Time Complexity: O(10*n*2^4)
Auxiliary Space: O(n*2^4)
Using Bottom-Up DP (Tabulation)
The approach is similar to the previous one. just instead of breaking down the problem recursively, we iteratively build up the solution by calculating in bottom-up manner.
// C++ program to count the valid number
// using tabulation
#include <bits/stdc++.h>
using namespace std;
int countSetBits(int number) {
int count = 0;
while (number > 0) {
// Add 1 if the least significant bit is set
// Right shift to check the next bit
count += (number & 1);
number >>= 1;
}
return count;
}
int countOfNumbers(int n, map<int, int> &primeIndex) {
// Memoization table: memo[index][mask] stores results
// for a given index and prime bitmask
vector<vector<int>> dp(n + 2, vector<int>(16, 0));
// Base case: when index == n + 1, check if all 4 primes
// are included (4 set bits in the mask)
for (int mask = 0; mask < 16; mask++) {
if (countSetBits(mask) == 4) {
// Mark as valid if all 4 primes are present
dp[n + 1][mask] = 1;
}
}
// Fill the memo table iteratively for all
// indices from n to 1
for (int index = n; index >= 1; --index) {
for (int mask = 0; mask < 16; ++mask) {
// Loop through all possible prime bitmasks
int val = 0;
// Handle the first position: digits 1-9 (0 if n == 1)
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9; ++digit) {
// Update the bitmask if the digit
// is prime
if (primeIndex.find(digit) != primeIndex.end()) {
val += dp[index + 1][(mask | (1 << primeIndex[digit]))];
}
else {
val += dp[index + 1][mask];
}
}
}
// For other positions, digits 0-9
// are allowed
else {
for (int digit = 0; digit <= 9; ++digit) {
// Update the bitmask if the digit is prime
if (primeIndex.find(digit) != primeIndex.end()) {
val += dp[index + 1][(mask | (1 << primeIndex[digit]))];
}
else {
val += dp[index + 1][mask];
}
}
}
// Store the result in the memo table for the
// current index and bitmask
dp[index][mask] = val;
}
}
// Return the result for starting at index 1 with no
// primes used (mask == 0)
return dp[1][0];
}
int main() {
map<int, int> primeIndex;
primeIndex[2] = 0;
primeIndex[3] = 1;
primeIndex[5] = 2;
primeIndex[7] = 3;
int n = 4;
cout << countOfNumbers(n, primeIndex) << endl;
return 0;
}
// Java program to count the valid
// number using tabulation.
import java.util.*;
class GfG {
// Count the number of set bits in a number
static int countSetBits(int number) {
int count = 0;
while (number > 0) {
// Add 1 if the least significant bit is set
// Right shift to check the next bit
count += (number & 1);
number >>= 1;
}
return count;
}
// Main function to count valid numbers with all four primes
static int countOfNumbers(int n, Map<Integer, Integer> primeIndex) {
// Memoization table: memo[index][mask] stores results for
// a given index and prime bitmask
int[][] dp = new int[n + 2][16];
// Base case: when index == n + 1, check if all 4 primes
// are included (4 set bits in the mask)
for (int mask = 0; mask < 16; mask++) {
if (countSetBits(mask) == 4) {
// Mark as valid if all 4 primes
// are present
dp[n + 1][mask] = 1;
}
}
// Fill the memo table iteratively for all
// indices from n to 1
for (int index = n; index >= 1; --index) {
for (int mask = 0; mask < 16; ++mask) {
int val = 0;
// Handle the first position: digits
// 1-9 (0 if n == 1)
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1); digit <= 9; ++digit) {
// Update the bitmask if the digit is prime
if (primeIndex.containsKey(digit)) {
val += dp[index + 1][(mask | (1 << primeIndex.get(digit)))];
} else {
val += dp[index + 1][mask];
}
}
} else {
// For other positions, digits 0-9 are allowed
for (int digit = 0; digit <= 9; ++digit) {
// Update the bitmask if the digit
// is prime
if (primeIndex.containsKey(digit)) {
val += dp[index + 1][(mask |
(1 << primeIndex.get(digit)))];
} else {
val += dp[index + 1][mask];
}
}
}
// Store the result in the memo table for the current
// index and bitmask
dp[index][mask] = val;
}
}
// Return the result for starting at index 1 with no primes
// used (mask == 0)
return dp[1][0];
}
public static void main(String[] args) {
Map<Integer, Integer> primeIndex = new HashMap<>();
primeIndex.put(2, 0);
primeIndex.put(3, 1);
primeIndex.put(5, 2);
primeIndex.put(7, 3);
int n = 4;
System.out.println(countOfNumbers(n, primeIndex));
}
}
# Python program to count the valid number
# using tabulation
def countSetBits(number):
count = 0
while number > 0:
# Add 1 if the least significant bit is set
# Right shift to check the next bit
count += (number & 1)
number >>= 1
return count
def countOfNumbers(n, primeIndex):
# Memoization table: memo[index][mask] stores results
# for a given index and prime bitmask
dp = [[0] * 16 for _ in range(n + 2)]
# Base case: when index == n + 1, check if all 4 primes
# are included (4 set bits in the mask)
for mask in range(16):
if countSetBits(mask) == 4:
# Mark as valid if all 4 primes are present
dp[n + 1][mask] = 1
# Fill the memo table iteratively for all
# indices from n to 1
for index in range(n, 0, -1):
for mask in range(16):
val = 0
# Handle the first position: digits
# 1-9 (0 if n == 1)
if index == 1:
for digit in range(0 if n == 1 else 1, 10):
# Update the bitmask if the digit is prime
if digit in primeIndex:
val += dp[index + 1][mask
| (1 << primeIndex[digit])]
else:
val += dp[index + 1][mask]
else:
# For other positions, digits 0-9 are allowed
for digit in range(10):
# Update the bitmask if the digit
# is prime
if digit in primeIndex:
val += dp[index + 1][mask
| (1 << primeIndex[digit])]
else:
val += dp[index + 1][mask]
# Store the result in the memo table for the current
# index and bitmask
dp[index][mask] = val
# Return the result for starting at index 1 with no primes
# used (mask == 0)
return dp[1][0]
if __name__ == "__main__":
primeIndex = {2: 0, 3: 1, 5: 2, 7: 3}
n = 4
print(countOfNumbers(n, primeIndex))
// C# program to count the valid number
// using tabulation
using System;
using System.Collections.Generic;
class GfG {
// Function to count the number of
// set bits in a number
static int countSetBits(int number) {
int count = 0;
while (number > 0) {
// Add 1 if the least significant bit is set
// Right shift to check the next bit
count += (number & 1);
number >>= 1;
}
return count;
}
static int
countOfNumbers(int n, Dictionary<int, int> primeIndex) {
// Memoization table: memo[index][mask] stores
// results for a given index and prime bitmask
int[, ] dp = new int[n + 2, 16];
// Base case: when index == n + 1, check if all 4
// primes are included (4 set bits in the mask)
for (int mask = 0; mask < 16; mask++) {
if (countSetBits(mask) == 4) {
// Mark as valid if all 4 primes
// are present
dp[n + 1, mask] = 1;
}
}
// Fill the memo table iteratively for all indices
// from n to 1
for (int index = n; index >= 1; --index) {
for (int mask = 0; mask < 16; ++mask) {
int val = 0;
// Handle the first position: digits 1-9 (0
// if n == 1)
if (index == 1) {
for (int digit = (n == 1 ? 0 : 1);
digit <= 9; ++digit) {
// Update the bitmask if the digit
// is prime
if (primeIndex.ContainsKey(digit)) {
val += dp
[index + 1,
mask
| (1 << primeIndex
[digit])];
}
else {
val += dp[index + 1, mask];
}
}
}
else {
// For other positions, digits 0-9 are
// allowed
for (int digit = 0; digit <= 9;
++digit) {
// Update the bitmask if the digit
// is prime
if (primeIndex.ContainsKey(digit)) {
val += dp
[index + 1,
mask
| (1 << primeIndex
[digit])];
}
else {
val += dp[index + 1, mask];
}
}
}
// Store the result in the memo table for
// the current index and bitmask
dp[index, mask] = val;
}
}
// Return the result for starting at index 1 with no
// primes used (mask == 0)
return dp[1, 0];
}
static void Main() {
Dictionary<int, int> primeIndex
= new Dictionary<int, int>{
{ 2, 0 }, { 3, 1 }, { 5, 2 }, { 7, 3 }
};
int n
= 4;
Console.WriteLine(countOfNumbers(n, primeIndex));
}
}
// JavaScript program to count the valid number
// using tabulation
function countSetBits(number) {
let count = 0;
while (number > 0) {
// Add 1 if the least significant bit is set
count += (number & 1);
// Right shift to check the next bit
number >>= 1;
}
return count;
}
function countOfNumbers(n, primeIndex) {
// Memoization table: memo[index][mask] stores results
// for a given index and prime bitmask
const dp = Array.from({length : n + 2},
() => Array(16).fill(0));
// Base case: when index == n + 1, check if all 4 primes
// are included (4 set bits in the mask)
for (let mask = 0; mask < 16; mask++) {
if (countSetBits(mask) === 4) {
// Mark as valid if all 4 primes are present
dp[n + 1][mask] = 1;
}
}
// Fill the memo table iteratively for all indices from
// n to 1
for (let index = n; index >= 1; --index) {
for (let mask = 0; mask < 16; ++mask) {
let val = 0;
// Handle the first position: digits 1-9 (0 if n
// == 1)
if (index === 1) {
for (let digit = (n === 1 ? 0 : 1);
digit <= 9; ++digit) {
// Update the bitmask if the digit is
// prime
if (primeIndex.has(digit)) {
val += dp[index + 1][(
mask
| (1
<< primeIndex.get(digit)))];
}
else {
val += dp[index + 1][mask];
}
}
}
else {
// For other positions, digits 0-9 are
// allowed
for (let digit = 0; digit <= 9; ++digit) {
// Update the bitmask if the digit is
// prime
if (primeIndex.has(digit)) {
val += dp[index + 1][(
mask
| (1
<< primeIndex.get(digit)))];
}
else {
val += dp[index + 1][mask];
}
}
}
// Store the result in the memo table for the
// current index and bitmask
dp[index][mask] = val;
}
}
// Return the result for starting at index 1 with no
// primes used (mask == 0)
return dp[1][0];
}
const primeIndex = new Map();
primeIndex.set(2, 0);
primeIndex.set(3, 1);
primeIndex.set(5, 2);
primeIndex.set(7, 3);
const n = 4;
console.log(countOfNumbers(n, primeIndex));
Output
24
Time Complexity: O(10*n*2^4)
Auxiliary Space: O(n*2^4)