# Count possible N-digit numbers such that each digit does not appear more than given number of times consecutively

• Difficulty Level : Easy
• Last Updated : 05 Oct, 2021

Given an integer N and an array maxDigit[], the task is to count all the distinct N-digit numbers such that digit i does not appear more than maxDigit[i] times. Since the count can be very large, print it modulo 109 + 7.

Examples:

Input: N = 2, maxDigit[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
Output: 90
Explanation:
Any digit can’t appear more than once consecutively. Therefore, numbers [00, 11, 22, 33, 44, 55, 66, 77, 88, 99] are invalid.
Hence, the total numbers without any restrictions are 10×10 = 100.
Therefore, the count is 100 – 10 = 90.

Input: N = 3, maxDigit[] = {2, 1, 1, 1, 1, 2, 1, 1, 1, 2}
Output: 864

Naive Approach: The simplest approach is to iterate over all the N-digit numbers and count those numbers that satisfy the given conditions. After checking all the numbers, print the total count modulo 109 + 7

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

Efficient Approach: To optimize the above approach, the idea is to use the concept of Digit Dynamic Programming. The DP states for this problem are explained as follows:

• In Digit-DP, the idea is to build a number from left to right by placing a digit [0, 9] at every position. So, to keep track of the current position, it is required to have a position state. This state will have possible values from 0 to (N – 1).
• According to the question, a digit i can’t appear more than maxDigit[i] consecutive times, therefore keep track of the previously filled digit. So, a state previous is required. This state will have possible values from 0 to 9.
• A state count is required which will provide the number of times a digit can appear consecutively. This state will have possible values from 1 to maxDigit[i].

Follow the steps below to solve this problem:

• The first position can have any digit without any restrictions.
• From the second position and onwards, keep a track of the previously filled digit and its given count up to which it can appear consecutively.
• If the same digit appears on the next position, then decrement its count and if this count becomes zero, simply ignore this digit in the next recursive call.
• If a different digit appears on the next position, then update its count according to the given value in maxDigit[].
• At each of the above recursive calls when the resultant number is generated then increment the count for that number.
• After the above steps, print the value of the total count as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Macros for modulus``#define MOD 1000000007` `// DP array for memoization``int` `dp;` `// Utility function to count N digit``// numbers with digit i not appearing``// more than max_digit[i] consecutively``int` `findCountUtil(``int` `N, ``int` `maxDigit[],``                  ``int` `position = 0,``                  ``int` `previous = 0,``                  ``int` `count = 1)``{``  ` `    ``// If number with N digits``    ``// is generated``    ``if` `(position == N) {``        ``return` `1;``    ``}` `    ``// Create a reference variable``    ``int``& ans = dp[position][previous][count];` `    ``// Check if the current state is``    ``// already computed before``    ``if` `(ans != -1) {``        ``return` `ans;``    ``}` `    ``// Initialize ans as zero``    ``ans = 0;` `    ``for` `(``int` `i = 0; i <= 9; ++i) {` `        ``// Check if count of previous``        ``// digit has reached zero or not``        ``if` `(count == 0 && previous != i) {` `            ``// Fill current position``            ``// only with digits that``            ``// are unequal to previous digit``            ``ans = (ans``                   ``+ (findCountUtil(N, maxDigit,``                                    ``position + 1, i,``                                    ``maxDigit[i] - 1))``                         ``% MOD)``                  ``% MOD;``        ``}` `        ``else` `if` `(count != 0) {` `            ``// If by placing the same digit``            ``// as previous on the current``            ``// position, decrement count by 1` `            ``// Else set the value of count``            ``// for this new digit``            ``// accordingly from max_digit[]``            ``ans = (ans``                   ``+ (findCountUtil(``                         ``N, maxDigit, position + 1, i,``                         ``(previous == i && position != 0)``                             ``? count - 1``                             ``: maxDigit[i] - 1))``                         ``% MOD)``                  ``% MOD;``        ``}``    ``}``    ``return` `ans;``}` `// Function to count N digit numbers``// with digit i not appearing more``// than max_digit[i] consecutive times``void` `findCount(``int` `N, ``int` `maxDigit[])``{``  ` `    ``// Stores the final count``    ``int` `ans = findCountUtil(N, maxDigit);` `    ``// Print the total count``    ``cout << ans;``}` `// Driver Code``int` `main()``{``    ``int` `N = 2;``    ``int` `maxDigit = { 1, 1, 1, 1, 1,``                         ``1, 1, 1, 1, 1 };` `    ``// Initialize the dp array with -1``    ``memset``(dp, -1, ``sizeof``(dp));` `    ``// Function Call``    ``findCount(N, maxDigit);``    ``return` `0;``}`

## Java

 `// Java program for the above approach ``import` `java.util.*;` `class` `GFG{``        ` `// Macros for modulus``static` `int` `MOD = ``1000000007``;` `// DP array for memoization``static` `int` `dp[][][] = ``new` `int``[``5005``][``12``][``12``];` `// Utility function to count N digit``// numbers with digit i not appearing``// more than max_digit[i] consecutively``static` `int` `findCountUtil(``int` `N, ``int` `maxDigit[],``                         ``int` `position,``                         ``int` `previous,``                         ``int` `count)``{``    ` `    ``// If number with N digits``    ``// is generated``    ``if` `(position == N)``    ``{``        ``return` `1``;``    ``}` `    ``// Create a reference variable``    ``int` `ans = dp[position][previous][count];` `    ``// Check if the current state is``    ``// already computed before``    ``if` `(ans != -``1``)``    ``{``        ``return` `ans;``    ``}` `    ``// Initialize ans as zero``    ``ans = ``0``;` `    ``for``(``int` `i = ``0``; i <= ``9``; ++i)``    ``{``        ` `        ``// Check if count of previous``        ``// digit has reached zero or not``        ``if` `(count == ``0` `&& previous != i)``        ``{``            ` `            ``// Fill current position``            ``// only with digits that``            ``// are unequal to previous digit``            ``ans = (ans + (findCountUtil(``                  ``N, maxDigit, position + ``1``, i,``                  ``maxDigit[i] - ``1``)) % MOD) % MOD;``        ``}` `        ``else` `if` `(count != ``0``)``        ``{``            ` `            ``// If by placing the same digit``            ``// as previous on the current``            ``// position, decrement count by 1` `            ``// Else set the value of count``            ``// for this new digit``            ``// accordingly from max_digit[]``            ``ans = (ans + (findCountUtil(``                  ``N, maxDigit, position + ``1``, i,``                  ``(previous == i && position != ``0``) ?``                  ``count - ``1` `: maxDigit[i] - ``1``)) % MOD) % MOD;``        ``}``    ``}``    ` `    ``return` `ans;``}` `// Function to count N digit numbers``// with digit i not appearing more``// than max_digit[i] consecutive times``static` `void` `findCount(``int` `N, ``int` `maxDigit[])``{``    ``int` `position = ``0``;``    ``int` `previous = ``0``;``    ``int` `count = ``1``;``    ` `    ``// Stores the final count``    ``int` `ans = findCountUtil(N, maxDigit, position,``                            ``previous, count);` `    ``// Print the total count``    ``System.out.println(ans);``}` `// Driver Code   ``public` `static` `void` `main (String[] args)   ``{   ``    ``int` `N = ``2``;``    ``int``[] maxDigit = { ``1``, ``1``, ``1``, ``1``, ``1``,``                       ``1``, ``1``, ``1``, ``1``, ``1` `};` `    ``// Initialize the dp array with -1``    ``// Fill each row with -1. ``    ``for``(``int``[][] row : dp)``    ``{``        ``for``(``int``[] rowColumn : row)``        ``{``            ``Arrays.fill(rowColumn, -``1``);``        ``}``    ``}``    ` `    ``// Function Call``    ``findCount(N, maxDigit);``}``}` `// This code is contributed by susmitakundugoaldanga`

## Python3

 `# Python3 program for the above approach``# Macros for modulus` `# DP array for memoization``dp ``=` `[[[ ``-``1` `for` `i ``in` `range``(``5005``)] ``for` `i ``in` `range``(``12``) ] ``for` `i ``in` `range``(``12``)]` `# Utility function to count N digit``# numbers with digit i not appearing``# more than max_digit[i] consecutively``def` `findCountUtil(N, maxDigit, position ,previous ,count):``    ``global` `dp``    ` `    ``# If number with N digits``    ``# is generated``    ``if` `(position ``=``=` `N):``        ``return` `1` `    ``# Create a reference variable``    ``ans ``=` `dp[position][previous][count]` `    ``# Check if the current state is``    ``# already computed before``    ``if` `(ans !``=` `-``1``):``        ``return` `ans` `    ``# Initialize ans as zero``    ``ans ``=` `0``    ``for` `i ``in` `range``(``10``):` `        ``# Check if count of previous``        ``# digit has reached zero or not``        ``if` `(count ``=``=` `0` `and` `previous !``=` `i):` `            ``# Fill current position``            ``# only with digits that``            ``# are unequal to previous digit``            ``ans ``=` `(ans ``+` `(findCountUtil(N, maxDigit, position ``+` `1``, i, maxDigit[i] ``-` `1``)) ``%` `1000000007``)``%` `1000000007``        ``elif` `(count !``=` `0``):` `            ``# If by placing the same digit``            ``# as previous on the current``            ``# position, decrement count by 1` `            ``# Else set the value of count``            ``# for this new digit``            ``# accordingly from max_digit[]``            ``ans ``=` `(ans ``+` `(findCountUtil(N, maxDigit, position ``+` `1``, i, count ``-` `1` `if` `(previous ``=``=` `i ``and` `position !``=` `0``) ``else` `maxDigit[i] ``-` `1``)) ``%` `1000000007``)``%` `1000000007` `    ``dp[position][previous][count] ``=` `ans``    ``return` `ans` `# Function to count N digit numbers``# with digit i not appearing more``# than max_digit[i] consecutive times``def` `findCount(N, maxDigit):``    ` `    ``# Stores the final count``    ``ans ``=` `findCountUtil(N, maxDigit, ``0``, ``0``, ``1``)` `    ``# Print the total count``    ``print` `(ans)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``N ``=` `2``    ``maxDigit ``=` `[``1``, ``1``, ``1``, ``1``, ``1``,``1``, ``1``, ``1``, ``1``, ``1``]` `    ``# Function Call``    ``findCount(N, maxDigit)` `    ``# This code is contributed by mohit kumar 29`

## C#

 `// C# program for the above approach ``using` `System;``using` `System.Collections.Generic;`  `using` `System;``using` `System.Collections.Generic;``public` `class` `GFG{``        ` `// Macros for modulus``static` `int` `MOD = 1000000007;` `// DP array for memoization``static` `int` `[,,]dp = ``new` `int``[5005, 12, 12];` `// Utility function to count N digit``// numbers with digit i not appearing``// more than max_digit[i] consecutively``static` `int` `findCountUtil(``int` `N, ``int` `[]maxDigit,``                         ``int` `position,``                         ``int` `previous,``                         ``int` `count)``{``    ` `    ``// If number with N digits``    ``// is generated``    ``if` `(position == N)``    ``{``        ``return` `1;``    ``}` `    ``// Create a reference variable``    ``int` `ans = dp[position, previous, count];` `    ``// Check if the current state is``    ``// already computed before``    ``if` `(ans != -1)``    ``{``        ``return` `ans;``    ``}` `    ``// Initialize ans as zero``    ``ans = 0;` `    ``for``(``int` `i = 0; i <= 9; ++i)``    ``{``        ` `        ``// Check if count of previous``        ``// digit has reached zero or not``        ``if` `(count == 0 && previous != i)``        ``{``            ` `            ``// Fill current position``            ``// only with digits that``            ``// are unequal to previous digit``            ``ans = (ans + (findCountUtil(``                  ``N, maxDigit, position + 1, i,``                  ``maxDigit[i] - 1)) % MOD) % MOD;``        ``}` `        ``else` `if` `(count != 0)``        ``{``            ` `            ``// If by placing the same digit``            ``// as previous on the current``            ``// position, decrement count by 1` `            ``// Else set the value of count``            ``// for this new digit``            ``// accordingly from max_digit[]``            ``ans = (ans + (findCountUtil(``                  ``N, maxDigit, position + 1, i,``                  ``(previous == i && position != 0) ?``                  ``count - 1 : maxDigit[i] - 1)) % MOD) % MOD;``        ``}``    ``}   ``    ``return` `ans;``}` `// Function to count N digit numbers``// with digit i not appearing more``// than max_digit[i] consecutive times``static` `void` `findCount(``int` `N, ``int` `[]maxDigit)``{``    ``int` `position = 0;``    ``int` `previous = 0;``    ``int` `count = 1;``    ` `    ``// Stores the readonly count``    ``int` `ans = findCountUtil(N, maxDigit, position,``                            ``previous, count);` `    ``// Print the total count``    ``Console.WriteLine(ans);``}` `// Driver Code   ``public` `static` `void` `Main(String[] args)   ``{   ``    ``int` `N = 2;``    ``int``[] maxDigit = { 1, 1, 1, 1, 1,``                       ``1, 1, 1, 1, 1 };` `    ``// Initialize the dp array with -1``    ``// Fill each row with -1. ``    ``for``(``int` `i = 0; i < dp.GetLength(0); i++)``    ``{``        ``for` `(``int` `j = 0; j < dp.GetLength(1); j++)``        ``{``            ``for` `(``int` `k = 0; k < dp.GetLength(2); k++)``                ``dp[i, j, k] = -1;``        ``}``    ``}``    ` `    ``// Function Call``    ``findCount(N, maxDigit);``}``}` `// This code is contributed by 29AjayKumar`

## Javascript

 ``

Output:

`90`

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

My Personal Notes arrow_drop_up