Count of ways to split a given number into prime segments

Given a 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 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 not
bool 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 numbers
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.substr(i - j, j))) {
            cnt
                += countPrimeStrings(
                    number,
                    i - j);
  
            cnt %= MOD;
        }
    }
  
    // Return the final result
    return cnt;
}
  
// Driver code
int main()
{
    string s1 = "3175";
  
    int l = s1.length();
    cout << countPrimeStrings(s1, l);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to count total
// number of ways to split a string 
// to get prime numbers
import java.util.*;
  
class GFG{
      
static final int MOD =1000000007;
  
// Function to check whether a number
// is a prime number or not
static 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 numbers
static 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 code
public static void main(String[] args)
{
    String s1 = "3175";
    int l = s1.length();
      
    System.out.print(countPrimeStrings(s1, l));
}
}
  
// This code is contributed by sapnasingh4991

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to count total
// number of ways to split a string 
// to get prime numbers
using System;
class GFG{
      
static readonly int MOD =1000000007;
  
// Function to check whether a number
// is a prime number or not
static 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 numbers
static 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 code
public static void Main(String[] args)
{
    String s1 = "3175";
    int l = s1.Length;
      
    Console.Write(countPrimeStrings(s1, l));
}
}
  
// This code is contributed by sapnasingh4991

chevron_right


Output:

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 sieve
void 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 not
bool isPrime(string number)
{
    int num = stoi(number);
    return sieve[num];
}
  
// Function to find the count
// of ways to split string
// into prime numbers
int 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 strings
int countPrimeStrings(string& number)
{
    int n = number.length();
    vector<int> dp(n + 1, -1);
    dp[0] = 1;
    return rec(number, n, dp);
}
  
// Driver code
int main()
{
    buildSieve();
  
    string s1 = "3175";
  
    cout << countPrimeStrings(s1) << "\n";
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to count total
// number of ways to split a String
// to get prime numbers
import java.util.*;
  
class GFG{
      
static int MOD = 1000000007;
static boolean []sieve = new boolean[1000000];
  
// Function to build sieve
static 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 not
static boolean isPrime(String number)
{
    int num = Integer.valueOf(number);
    return sieve[num];
}
  
// Function to find the count
// of ways to split String
// into prime numbers
static 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 Strings
static 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 code
public static void main(String[] args)
{
    buildSieve();
  
    String s1 = "3175";
  
    System.out.print(countPrimeStrings(s1) + "\n");
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to count total
// number of ways to split a String
// to get prime numbers
using System;
  
class GFG{
      
static int MOD = 1000000007;
static bool []sieve = new bool[1000000];
  
// Function to build sieve
static 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 not
static bool isPrime(String number)
{
    int num = Int32.Parse(number);
    return sieve[num];
}
  
// Function to find the count
// of ways to split String
// into prime numbers
static 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 Strings
static 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 code
public static void Main(String[] args)
{
    buildSieve();
  
    String s1 = "3175";
  
    Console.Write(countPrimeStrings(s1) + "\n");
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


Output:

3

Time Complexity: O(N + N*log(log(N)))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.