Count of ways to split a given number into prime segments - GeeksforGeeks

12 Oct, 2021
Given numeric string str, the task is to count the number of ways the given string can be split, such that each segment is a prime number. Since the answer can be large, return the answer modulo 109 + 7. Note: A split that contains numbers with leading zeroes will be invalid and the initial string does not contain leading zeroes.Examples: 
Input: str = “3175” Output: 3 Explanation: There are 3 ways to split this string into prime numbers which are (31, 7, 5), (3, 17, 5), (317, 5).Input: str = “11373” Output: 6 Explanation: There are 6 ways to split this string into prime numbers which are (11, 3, 7, 3), (113, 7, 3), (11, 37, 3), (11, 3, 73), (113, 73) and (11, 373). 
Naive Approach: To solve the problem mentioned above, the naive method is to use Recursion.  
Start recursing from the ending index of the given string and consider every suffix up to 6 digits (given that the prime number must be in the range of [1, 106)] and check if it is a prime number or not.
If the suffix doesn’t contain a leading zero and it is a prime number, then recursively call the function to count the ways for the remaining string and add to the total count.
When the index reaches 0, we reach the base case and return 1 to consider current splits as a valid count.
Take mod of the count at each iteration and return the count at the end.
Below is the implementation above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation to count total// number of ways to split a// string to get prime numbers #include <bits/stdc++.h>using namespace std;#define MOD 1000000007 // Function to check whether a number// is a prime number or notbool isPrime(string number){    int num = stoi(number);    for (int i = 2; i * i <= num; i++)        if ((num % i) == 0)            return false;    return num > 1 ? true : false;} // Function to find the count// of ways to split string// into prime numbersint countPrimeStrings(    string& number, int i){     // 1 based indexing    if (i == 0)        return 1;    int cnt = 0;     // Consider every suffix up to 6 digits    for (int j = 1; j <= 6; j++) {         // Number should not have        // a leading zero and        // it should be a prime number        if (i - j >= 0            && number[i - j] != '0'            && isPrime(                   number.substr(i - j, j))) {            cnt                += countPrimeStrings(                    number,                    i - j);             cnt %= MOD;        }    }     // Return the final result    return cnt;} // Driver codeint main(){    string s1 = "3175";     int l = s1.length();    cout << countPrimeStrings(s1, l);     return 0;}
// Java implementation to count total// number of ways to split a string// to get prime numbersimport java.util.*; class GFG{     static final int MOD =1000000007; // Function to check whether a number// is a prime number or notstatic boolean isPrime(String number){    int num = Integer.valueOf(number);         for(int i = 2; i * i <= num; i++)    {       if ((num % i) == 0)           return false;    }    return num > 1 ? true : false;} // Function to find the count// of ways to split String// into prime numbersstatic int countPrimeStrings(String number,                                     int i){     // 1 based indexing    if (i == 0)        return 1;             int cnt = 0;     // Consider every suffix up to 6 digits    for(int j = 1; j <= 6; j++)    {               // Number should not have       // a leading zero and it       // should be a prime number       if (i - j >= 0 &&           number.charAt(i - j) != '0' &&           isPrime(number.substring(i - j, i)))       {           cnt += countPrimeStrings(number,                                    i - j);           cnt %= MOD;       }    }         // Return the final result    return cnt;} // Driver codepublic static void main(String[] args){    String s1 = "3175";    int l = s1.length();         System.out.print(countPrimeStrings(s1, l));}} // This code is contributed by sapnasingh4991
# Python3 implementation to# count total number of ways# to split a string to get# prime numbersMOD = 1000000007 # Function to check whether# a number is a prime number# or notdef isPrime(number):     num = int(number)    i = 2         while i * i <= num:        if ((num % i) == 0):            return False        i += 1             if num > 1:      return True    else:      return False # Function to find the count# of ways to split string# into prime numbersdef countPrimeStrings(number, i):     # 1 based indexing    if (i == 0):        return 1    cnt = 0     # Consider every suffix    # up to 6 digits    for j in range(1, 7):         # Number should not have        # a leading zero and        # it should be a prime number        if (i - j >= 0 and            number[i - j] != '0' and            isPrime(number[i - j : i])):            cnt += countPrimeStrings(number,                                     i - j)            cnt %= MOD             # Return the final result    return cnt # Driver codeif __name__ == "__main__":       s1 = "3175"    l = len(s1)    print (countPrimeStrings(s1, l)) # This code is contributed by Chitranayal
// C# implementation to count total// number of ways to split a string// to get prime numbersusing System;class GFG{     static readonly int MOD =1000000007; // Function to check whether a number// is a prime number or notstatic bool isPrime(String number){    int num = Int32.Parse(number);         for(int i = 2; i * i <= num; i++)    {        if ((num % i) == 0)            return false;    }    return num > 1 ? true : false;} // Function to find the count// of ways to split String// into prime numbersstatic int countPrimeStrings(String number,                                     int i){     // 1 based indexing    if (i == 0)        return 1;             int cnt = 0;     // Consider every suffix up to 6 digits    for(int j = 1; j <= 6; j++)    {                 // Number should not have        // a leading zero and it        // should be a prime number        if (i - j >= 0 &&            number[i - j] != '0' &&            isPrime(number.Substring(i - j, j)))        {            cnt += countPrimeStrings(number,                                     i - j);            cnt %= MOD;        }    }         // Return the readonly result    return cnt;} // Driver codepublic static void Main(String[] args){    String s1 = "3175";    int l = s1.Length;         Console.Write(countPrimeStrings(s1, l));}} // This code is contributed by sapnasingh4991
<script>// Javascript implementation to count total// number of ways to split a string// to get prime numbers let MOD =1000000007;// Function to check whether a number// is a prime number or notfunction isPrime(number){    let num = parseInt(number);          for(let i = 2; i * i <= num; i++)    {       if ((num % i) == 0)           return false;    }    return num > 1 ? true : false;} // Function to find the count// of ways to split String// into prime numbersfunction countPrimeStrings(number,i){    // 1 based indexing    if (i == 0)        return 1;              let cnt = 0;      // Consider every suffix up to 6 digits    for(let j = 1; j <= 6; j++)    {                // Number should not have       // a leading zero and it       // should be a prime number       if (i - j >= 0 &&           number[i - j] != '0' &&           isPrime(number.substring(i - j, i)))       {           cnt += countPrimeStrings(number,                                    i - j);           cnt %= MOD;       }    }          // Return the final result    return cnt;} // Driver codelet s1 = "3175";let l = s1.length;document.write(countPrimeStrings(s1, l));   // This code is contributed by avanitrachhadiya2155</script>
3
 
Time Complexity: O(N2) Auxiliary Space: O(N)Efficient Approach: The optimize the above method the main idea is to use memoization technique to reduce the time complexity of the recursion solution discussed above. Let us consider a dp[] table which stores at every index dp[i], the ways to split the first i digits of the string str. The complexity to check if a number is prime or not can be further reduced by using Sieve of Eratosthenes.Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation to count total// number of ways to split a// string to get prime numbers #include <bits/stdc++.h>using namespace std;const int MOD = 1000000007;bool sieve[1000000]; // Function to build sievevoid buildSieve(){    for (auto& i : sieve)        i = true;     sieve[0] = false;    sieve[1] = false;     for (int p = 2; p * p <= 1000000;         p++) {         // If p is a prime        if (sieve[p] == true) {             // Update all multiples            // of p as non prime             for (int i = p * p; i <= 1000000;                 i += p)                sieve[i] = false;        }    }} // Function to check whether a number// is a prime number or notbool isPrime(string number){    int num = stoi(number);    return sieve[num];} // Function to find the count// of ways to split string// into prime numbersint rec(string& number, int i,        vector<int>& dp){    if (dp[i] != -1)        return dp[i];     int cnt = 0;     for (int j = 1; j <= 6; j++) {         // Number should not have a        // leading zero and it        // should be a prime number        if (i - j >= 0            && number[i - j] != '0'            && isPrime(                   number.substr(i - j, j))) {             cnt += rec(                number, i - j, dp);            cnt %= MOD;        }    }    return dp[i] = cnt;} // Function to count the// number of prime stringsint countPrimeStrings(string& number){    int n = number.length();    vector<int> dp(n + 1, -1);    dp[0] = 1;    return rec(number, n, dp);} // Driver codeint main(){    buildSieve();     string s1 = "3175";     cout << countPrimeStrings(s1) << "\n";     return 0;}
// Java implementation to count total// number of ways to split a String// to get prime numbersimport java.util.*; class GFG{     static int MOD = 1000000007;static boolean []sieve = new boolean[1000000]; // Function to build sievestatic void buildSieve(){    Arrays.fill(sieve, true);     sieve[0] = false;    sieve[1] = false;     for(int p = 2; p * p <= 1000000; p++)    {        // If p is a prime       if (sieve[p] == true)       {            // Update all multiples           // of p as non prime           for(int i = p * p; i < 1000000;                   i += p)              sieve[i] = false;       }    }} // Function to check whether a number// is a prime number or notstatic boolean isPrime(String number){    int num = Integer.valueOf(number);    return sieve[num];} // Function to find the count// of ways to split String// into prime numbersstatic int rec(String number, int i,                              int []dp){    if (dp[i] != -1)        return dp[i];    int cnt = 0;     for(int j = 1; j <= 6; j++)    {               // Number should not have a       // leading zero and it       // should be a prime number       if (i - j >= 0 &&           number.charAt(i - j) != '0' &&           isPrime(number.substring(i - j, i)))       {           cnt += rec(number, i - j, dp);           cnt %= MOD;       }    }    return dp[i] = cnt;} // Function to count the// number of prime Stringsstatic int countPrimeStrings(String number){    int n = number.length();    int []dp = new int[n + 1];         Arrays.fill(dp, -1);    dp[0] = 1;     return rec(number, n, dp);} // Driver codepublic static void main(String[] args){    buildSieve();     String s1 = "3175";     System.out.print(countPrimeStrings(s1) + "\n");}} // This code is contributed by 29AjayKumar
# Python3 implementation to count total# number of ways to split a String# to get prime numbersMOD = 1000000007sieve = [0]*(1000000)  # Function to build sievedef buildSieve():    for i in range(len(sieve)):        sieve[i] = True          sieve[0] = False    sieve[1] = False         p = 2    while p*p <= 1000000:        # If p is a prime        if sieve[p] == True:            # Update all multiples            # of p as non prime            for i in range(p*p, 1000000, p):                sieve[i] = False        p+=1         # Function to check whether a number# is a prime number or notdef isPrime(number):    num = int(number)    return sieve[num]  # Function to find the count# of ways to split String# into prime numbersdef rec(number,i,dp):    if dp[i] != -1:        return dp[i]    cnt = 0       for j in range(1, 7):       # Number should not have a       # leading zero and it       # should be a prime number       if (i - j) >= 0 and number[i - j] != '0' and isPrime(number[i - j: i]):           cnt += rec(number, i - j, dp)           cnt %= MOD    dp[i] = cnt    return dp[i]  # Function to count the# number of prime Stringsdef countPrimeStrings(number):    n = len(number)    dp = [0]*(n + 1)          for i in range(n + 1):        dp[i] = -1          dp[0] = 1       return rec(number, n, dp) # Driver codebuildSieve()s1 = "3175"print(countPrimeStrings(s1)) # This code is contributed by suresh07.
// C# implementation to count total// number of ways to split a String// to get prime numbersusing System; class GFG{     static int MOD = 1000000007;static bool []sieve = new bool[1000000]; // Function to build sievestatic void buildSieve(){    for(int j = 0; j < sieve.Length; j++)       sieve[j] = true;     sieve[0] = false;    sieve[1] = false;     for(int p = 2; p * p <= 1000000; p++)    {               // If p is a prime       if (sieve[p] == true)       {                       // Update all multiples           // of p as non prime           for(int i = p * p; i < 1000000;                   i += p)              sieve[i] = false;       }    }} // Function to check whether a number// is a prime number or notstatic bool isPrime(String number){    int num = Int32.Parse(number);    return sieve[num];} // Function to find the count// of ways to split String// into prime numbersstatic int rec(String number, int i,                              int []dp){    if (dp[i] != -1)        return dp[i];    int cnt = 0;     for(int j = 1; j <= 6; j++)    {               // Number should not have a       // leading zero and it       // should be a prime number       if (i - j >= 0 &&           number[i - j] != '0' &&           isPrime(number.Substring(i - j, j)))       {           cnt += rec(number, i - j, dp);           cnt %= MOD;       }    }    return dp[i] = cnt;} // Function to count the// number of prime Stringsstatic int countPrimeStrings(String number){    int n = number.Length;    int []dp = new int[n + 1];         for(int j = 0; j < dp.Length; j++)       dp[j] = -1;    dp[0] = 1;     return rec(number, n, dp);} // Driver codepublic static void Main(String[] args){    buildSieve();     String s1 = "3175";     Console.Write(countPrimeStrings(s1) + "\n");}} // This code is contributed by 29AjayKumar
<script>// Javascript implementation to count total// number of ways to split a String// to get prime numberslet MOD = 1000000007;let sieve = new Array(1000000); // Function to build sievefunction buildSieve(){    for(let i = 0; i < sieve.length; i++)    {        sieve[i] = true;    }         sieve[0] = false;    sieve[1] = false;      for(let p = 2; p * p <= 1000000; p++)    {         // If p is a prime       if (sieve[p] == true)       {             // Update all multiples           // of p as non prime           for(let i = p * p; i < 1000000;                   i += p)              sieve[i] = false;       }    }} // Function to check whether a number// is a prime number or notfunction isPrime(number){    let num = parseInt(number);    return sieve[num];} // Function to find the count// of ways to split String// into prime numbersfunction rec(number,i,dp){    if (dp[i] != -1)        return dp[i];    let cnt = 0;      for(let j = 1; j <= 6; j++)    {                // Number should not have a       // leading zero and it       // should be a prime number       if (i - j >= 0 &&           number[i - j] != '0' &&           isPrime(number.substring(i - j, i)))       {           cnt += rec(number, i - j, dp);           cnt %= MOD;       }    }    return dp[i] = cnt;} // Function to count the// number of prime Stringsfunction countPrimeStrings(number){    let n = number.length;    let dp = new Array(n + 1);         for(let i = 0; i < (n + 1); i++)    {        dp[i] = -1;    }         dp[0] = 1;      return rec(number, n, dp);} // Driver codebuildSieve();let s1 = "3175";document.write(countPrimeStrings(s1) + "<br>"); // This code is contributed by rag2127</script>
3
 
Time Complexity: O(N + N*log(log(N))) Auxiliary Space: O(N)
sapnasingh4991
29AjayKumar
ukasp
avanitrachhadiya2155
rag2127
suresh07
Atlassian
Memoization
Dynamic Programming
Mathematical
Recursion
Atlassian
Dynamic Programming
Mathematical
Recursion
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Matrix Chain Multiplication | DP-8
Longest Palindromic Substring | Set 1
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Write a program to print all permutations of a given string
C++ Data Types
Set in C++ Standard Template Library (STL)
Merge two sorted arrays
Modulo Operator (%) in C/C++ with Examples