# Count digit groupings of a number with given constraints

• Difficulty Level : Hard
• Last Updated : 06 May, 2021

We are given a string consisting of digits, we may group these digits into sub-groups (but maintaining their original order). The task is to count the number of groupings such that for every sub-group except the last one, the sum of digits in a sub-group is less than or equal to the sum of the digits in the sub-group immediately on its right.
For example, a valid grouping of digits of number 1119 is (1-11-9). Sum of digits in first subgroup is 1, next subgroup is 2, and last subgroup is 9. Sum of every subgroup is less than or equal to its immediate right.
Examples :

```Input : "1119"
Output: 7
Sub-groups: [1-119], [1-1-19], [1-11-9], [1-1-1-9],
[11-19] and [111-9].
Note : Here we have included  in the group and
the sum of digits is 12 and this group has no
immediate right.

Input : "1234"
Output: 6
Sub-groups : , [1-234], [12-34], [1-2-3-4],
[12-3-4] and [1-2-34]```

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Let “length” be the length of the input number. A recursive solution is to consider every position from 0 length-1. For every position, recursively count all possible subgroups after it. Below is C++ implementation of the naive recursive solution.

## C++

 `// C++ program to count number of``// ways to group digits of a number``// such that sum of digits in every``// subgroup is less than or equal to``// its immediate right subgroup.``#include``using` `namespace` `std;` `// Function to find the subgroups``int` `countGroups(``int` `position,``                ``int` `previous_sum,``                ``int` `length, ``char` `*num)``{``    ``// Terminating Condition``    ``if` `(position == length)``        ``return` `1;` `    ``int` `res = 0;``    ` `    ``// sum of digits``    ``int` `sum = 0;` `    ``// Traverse all digits from``    ``// current position to rest``    ``// of the length of string``    ``for` `(``int` `i = position; i < length; i++)``    ``{``        ``sum += (num[i] - ``'0'``);` `        ``// If forward_sum is greater``        ``// than the previous sum,``        ``// then call the method again``        ``if` `(sum >= previous_sum)` `        ``// Note : We pass current``        ``// sum as previous sum``        ``res += countGroups(i + 1, sum,``                           ``length, num);``    ``}` `    ``// Total number of subgroups``    ``// till current position``    ``return` `res;``}` `// Driver Code``int` `main()``{``    ``char` `num[] = ``"1119"``;``    ``int` `len = ``strlen``(num);``    ``cout << countGroups(0, 0, len, num);``    ``return` `0;``}`

## Java

 `// Java program to count number``// of ways to group digits of ``// a number such that sum of ``// digits in every subgroup is``// less than or equal to its``// immediate right subgroup.``import` `java.io.*;` `class` `GFG``{` `// Function to find``// the subgroups``static` `int` `countGroups(``int` `position,``                       ``int` `previous_sum,``                       ``int` `length,``                       ``String num)``{``    ``// Terminating Condition``    ``if` `(position == length)``        ``return` `1``;` `    ``int` `res = ``0``;``    ` `    ``// sum of digits``    ``int` `sum = ``0``;` `    ``// Traverse all digits from``    ``// current position to rest``    ``// of the length of string``    ``for` `(``int` `i = position; i < length; i++)``    ``{``        ``sum += (num.charAt(i) - ``'0'``);` `        ``// If forward_sum is greater``        ``// than the previous sum,``        ``// then call the method again``        ``if` `(sum >= previous_sum)` `        ``// Note : We pass current``        ``// sum as previous sum``        ``res += countGroups(i + ``1``, sum,``                         ``length, num);``    ``}` `    ``// Total number of subgroups``    ``// till current position``    ``return` `res;``}` `// Driver Code``public` `static` `void` `main (String[] args)``{``    ``String num = ``"1119"``;``    ``int` `len =num .length();``    ``System.out.println(countGroups(``0``, ``0``,``                                   ``len, num));``}``}` `// This code is contributed by anuj_67.`

## Python3

 `# Python3 program to count``# number of ways to group digits``# of a number such that sum of``# digits in every subgroup``# is less than or equal to its immediate``# right subgroup.` `# Function to find the subgroups``def` `countGroups(position, previous_sum,``               ``length, num):` `    ``# Terminating Condition``    ``if``(position ``=``=` `length):``        ``return` `1` `    ``res ``=` `0``    ``# sum of digits``    ``sum` `=` `0` `    ``# Traverse all digits from``    ``# current position to rest``    ``# of the length of string``    ``for` `i ``in` `range``(position, length):` `        ``sum` `=` `sum` `+` `int``(num[i])``        ``# If forward_sum is greater``        ``# than the previous sum,``        ``# then call the method again``        ``if` `(``sum` `>``=` `previous_sum):``            ``# Note : We pass current``            ``# sum as previous sum``            ``res ``=` `res ``+` `countGroups(i ``+` `1``, ``sum``, length, num)` `    ``# Total number of subgroups``    ``# till the current position``    ``return` `res` `# Driver Code``if` `__name__``=``=``'__main__'``:``    ``num ``=` `"1119"``    ``len` `=` `len``(num)``    ``print``(countGroups(``0``, ``0``, ``len``, num))` `# This code is contributed by``# Sanjit_Prasad`

## C#

 `// C# program to count number``// of ways to group digits of``// a number such that sum of``// digits in every subgroup is``// less than or equal to its``// immediate right subgroup.``using` `System;``                    ` `class` `GFG``{` `// Function to find``// the subgroups``static` `int` `countGroups(``int` `position,``                       ``int` `previous_sum,``                       ``int` `length,``                       ``String num)``{``    ``// Terminating Condition``    ``if` `(position == length)``        ``return` `1;` `    ``int` `res = 0;` `    ``// sum of digits``    ``int` `sum = 0;` `    ``// Traverse all digits from``    ``// current position to rest``    ``// of the length of string``    ``for` `(``int` `i = position; i < length; i++)``    ``{``        ``sum += (num[i] - ``'0'``);` `        ``// If forward_sum is greater``        ``// than the previous sum,``        ``// then call the method again``        ``if` `(sum >= previous_sum)` `        ``// Note : We pass current``        ``// sum as previous sum``        ``res += countGroups(i + 1, sum,``                           ``length, num);``    ``}` `    ``// Total number of subgroups``    ``// till current position``    ``return` `res;``}` `// Driver Code``public` `static` `void` `Main ()``{``    ``String num = ``"1119"``;``    ``int` `len = num.Length;``    ``Console.Write(countGroups(0, 0, len, num));``}``}` `// This code is contributed by 29AjayKumar`

## PHP

 `= ``\$previous_sum``)` `        ``// Note : We pass current``        ``// sum as previous sum``        ``\$res` `+= countGroups(``\$i` `+ 1, ``\$sum``,``                            ``\$length``, ``\$num``);``    ``}` `    ``// Total number of subgroups``    ``// till current position``    ``return` `\$res``;``}` `// Driver Code``\$num` `= ``"1119"``;``\$len` `= ``strlen``(``\$num``);``echo` `countGroups(0, 0, ``\$len``, ``\$num``);` `// This code is contributed by ajit``?>`

## Javascript

 ``

Output :

`7`

If we take a closer look at the above recursive solution, we notice that there may be overlapping subproblems. For example, if the input number is 12345, then for position = 3 and previous_sum = 3, we recur two times. Similarly, for position 4 and previous_sum = 7, we recur two times. Therefore the above solution can be optimized using Dynamic Programming. Below is a Dynamic Programming based solution for this problem.

1. The maximum sum of digits can be 9*length where ‘length’ is length of input num.
2. Create a 2D array int dp[MAX][9*MAX] where MAX is maximum possible length of input number. A value dp[position][previous] is going to store result for ‘position’ and ‘previous_sum’.

3. If current subproblem has been evaluated i.e; dp[position][previous_sum] != -1, then use this result, else recursively compute its value.

4. If by including the current position digit in sum i.e; sum = sum + num[position]-‘0’, sum becomes greater than equal to previous sum, then increment the result and call the problem for next position in the num.
5. If position == length, then we have been traversed current subgroup successfully and we return 1;

Below is the implementation of the above algorithm.

## C++

 `// C++ program to count number of``// ways to group digits of a number``// such that sum of digits in every``// subgroup is less than or equal``// to its immediate right subgroup.``#include``using` `namespace` `std;` `// Maximum length of``// input number string``const` `int` `MAX = 40;` `// A memoization table to store``// results of subproblems length``// of string is 40 and maximum``// sum will be 9 * 40 = 360.``int` `dp[MAX][9*MAX + 1];` `// Function to find the count``// of splits with given condition``int` `countGroups(``int` `position,``                ``int` `previous_sum,``                ``int` `length, ``char` `*num)``{``    ``// Terminating Condition``    ``if` `(position == length)``        ``return` `1;` `    ``// If already evaluated for``    ``// a given sub problem then``    ``// return the value``    ``if` `(dp[position][previous_sum] != -1)``        ``return` `dp[position][previous_sum];` `    ``// countGroups for current``    ``// sub-group is 0``    ``dp[position][previous_sum] = 0;` `    ``int` `res = 0;``    ` `    ``// sum of digits``    ``int` `sum = 0;` `    ``// Traverse all digits from``    ``// current position to rest``    ``// of the length of string``    ``for` `(``int` `i = position; i < length; i++)``    ``{``        ``sum += (num[i] - ``'0'``);` `        ``// If forward_sum is greater``        ``// than the previous sum,``        ``// then call the method again``        ``if` `(sum >= previous_sum)` `        ``// Note : We pass current``        ``// sum as previous sum``        ``res += countGroups(i + 1, sum,``                           ``length, num);``    ``}` `    ``dp[position][previous_sum] = res;` `    ``// total number of subgroups``    ``// till current position``    ``return` `res;``}` `// Driver Code``int` `main()``{``    ``char` `num[] = ``"1119"``;``    ``int` `len = ``strlen``(num);` `    ``// Initialize dp table``    ``memset``(dp, -1, ``sizeof``(dp));` `    ``cout << countGroups(0, 0, len, num);``    ``return` `0;``}`

## Java

 `    ` `// Java program to count the number of``// ways to group digits of a number``// such that sum of digits in every``// subgroup is less than or equal``// to its immediate right subgroup.``class` `GFG``{` `// Maximum length of``// input number string``static` `int` `MAX = ``40``;` `// A memoization table to store``// results of subproblems length``// of string is 40 and maximum``// sum will be 9 * 40 = 360.``static` `int` `dp[][] = ``new` `int``[MAX][``9` `* MAX + ``1``];` `// Function to find the count``// of splits with given condition``static` `int` `countGroups(``int` `position,``                ``int` `previous_sum,``                ``int` `length, ``char` `[]num)``{``    ``// Terminating Condition``    ``if` `(position == length)``        ``return` `1``;` `    ``// If already evaluated for``    ``// a given sub problem then``    ``// return the value``    ``if` `(dp[position][previous_sum] != -``1``)``        ``return` `dp[position][previous_sum];` `    ``// countGroups for current``    ``// sub-group is 0``    ``dp[position][previous_sum] = ``0``;` `    ``int` `res = ``0``;``    ` `    ``// sum of digits``    ``int` `sum = ``0``;` `    ``// Traverse all digits from``    ``// current position to rest``    ``// of the length of string``    ``for` `(``int` `i = position; i < length; i++)``    ``{``        ``sum += (num[i] - ``'0'``);` `        ``// If forward_sum is greater``        ``// than the previous sum,``        ``// then call the method again``        ``if` `(sum >= previous_sum)` `        ``// Note : We pass current``        ``// sum as previous sum``        ``res += countGroups(i + ``1``, sum,``                        ``length, num);``    ``}` `    ``dp[position][previous_sum] = res;` `    ``// total number of subgroups``    ``// till current position``    ``return` `res;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``char` `num[] = ``"1119"``.toCharArray();``    ``int` `len = num.length;` `    ``// Initialize dp table``    ``for``(``int` `i = ``0``; i < dp.length; i++)``    ``{``        ``for``(``int` `j = ``0``;j < ``9` `* MAX + ``1``; j++){``            ``dp[i][j] = -``1``;``        ``}``    ``}``    ``System.out.println(countGroups(``0``, ``0``, len, num));``    ``}``}` `// This code is contributed by PrinciRaj1992`

## Python3

 `# Python3 program to count the number of``# ways to group digits of a number``# such that sum of digits in every``# subgroup is less than or equal``# to its immediate right subgroup.` `# Maximum length of``# input number string``MAX` `=` `40` `# A memoization table to store``# results of subproblems length``# of string is 40 and maximum``# sum will be 9 * 40 = 360.``dp ``=` `[[ ``-``1` `for` `i ``in` `range``(``9` `*` `MAX` `+` `1``)]``           ``for` `i ``in` `range``(``MAX``)]` `# Function to find the count``# of splits with given condition``def` `countGroups(position, previous_sum,``                           ``length, num):``    ` `    ``# Terminating Condition``    ``if` `(position ``=``=` `length):``        ``return` `1` `    ``# If already evaluated for``    ``# a given sub problem then``    ``# return the value``    ``if` `(dp[position][previous_sum] !``=` `-``1``):``        ``return` `dp[position][previous_sum]` `    ``# countGroups for current``    ``# sub-group is 0``    ``dp[position][previous_sum] ``=` `0` `    ``res ``=` `0` `    ``# sum of digits``    ``sum` `=` `0` `    ``# Traverse all digits from``    ``# current position to rest``    ``# of the length of string``    ``for` `i ``in` `range``(position,length):``        ``sum` `+``=` `(``ord``(num[i]) ``-` `ord``(``'0'``))` `        ``# If forward_sum is greater``        ``# than the previous sum,``        ``# then call the method again``        ``if` `(``sum` `>``=` `previous_sum):` `            ``# Note : We pass current``            ``# sum as previous sum``            ``res ``+``=` `countGroups(i ``+` `1``, ``sum``,``                               ``length, num)` `    ``dp[position][previous_sum] ``=` `res` `    ``# total number of subgroups``    ``# till the current position``    ``return` `res` `# Driver Code``num ``=` `"1119"``len` `=` `len``(num)` `print``(countGroups(``0``, ``0``, ``len``, num))` `# This code is contributed by Mohit Kumar`

## C#

 `// C# program to count number of``// ways to group digits of a number``// such that sum of digits in every``// subgroup is less than or equal``// to its immediate right subgroup.``using` `System;` `class` `GFG``{``    ``// Maximum length of``    ``// input number string``    ``static` `int` `MAX = 40;``    ` `    ``// A memoization table to store``    ``// results of subproblems length``    ``// of string is 40 and maximum``    ``// sum will be 9 * 40 = 360.``    ``static` `int``[,] dp = ``new` `int``[MAX, 9 * MAX + 1];``    ` `    ``// Function to find the count``    ``// of splits with given condition``    ``static` `int` `countGroups(``int` `position,``                            ``int` `previous_sum,``                            ``int` `length, ``char``[] num)``    ``{``        ``// Terminating Condition``        ``if` `(position == length)``            ``return` `1;``    ` `        ``// If already evaluated for``        ``// a given sub problem then``        ``// return the value``        ``if` `(dp[position,previous_sum] != -1)``            ``return` `dp[position,previous_sum];``    ` `        ``// countGroups for current``        ``// sub-group is 0``        ``dp[position,previous_sum] = 0;``    ` `        ``int` `res = 0;``        ` `        ``// sum of digits``        ``int` `sum = 0;``    ` `        ``// Traverse all digits from``        ``// current position to rest``        ``// of the length of string``        ``for` `(``int` `i = position; i < length; i++)``        ``{``            ``sum += (num[i] - ``'0'``);``    ` `            ``// If forward_sum is greater``            ``// than the previous sum,``            ``// then call the method again``            ``if` `(sum >= previous_sum)``    ` `            ``// Note : We pass current``            ``// sum as previous sum``            ``res += countGroups(i + 1, sum,``                            ``length, num);``        ``}``    ` `        ``dp[position,previous_sum] = res;``    ` `        ``// total number of subgroups``        ``// till current position``        ``return` `res;``    ``}``    ` `    ``// Driver Code``    ``static` `void` `Main()``    ``{``        ``char``[] num = {``'1'``, ``'1'``, ``'1'``, ``'9'``};``        ``int` `len = num.Length;``    ` `        ``// Initialize dp table``        ``for``(``int` `i = 0; i < MAX; i++)``            ``for``(``int` `j = 0; j < 9 * MAX + 1; j++)``                ``dp[i, j] = -1;``    ` `        ``Console.Write(countGroups(0, 0, len, num));``    ``}``}` `// This code is contributed by DrRoot_`

## Javascript

 ``

Output :

` 7`