# Count of numbers between range having only non-zero digits whose sum of digits is N and number is divisible by M

Given a range **[L, R]** and two positive integers **N** and **M**. The task is to count the numbers in the range containing only non-zero digits whose **sum of digits is equal to N** and the **number is divisible by M**.**Examples:**

Input:L = 1, R = 100, N = 8, M = 2Output:4

Only 8, 26, 44 and 62 are valid numbersInput:L = 1, R = 200, N = 4, M = 11Output:2

Only 22 and 121 are valid numbers

**Prerequisites : **Digit DP

**Approach:** Firstly, if we are able to count the required numbers up to R i.e. in the range [0, R], we can easily reach our answer in the range [L, R] by solving for from zero to R and then subtracting the answer we get after solving for from zero to L â€“ 1. Now, we need to define the DP states. **DP States**:

- Since we can consider our number as a sequence of digits, one state is the
**position**at which we are currently in. This position can have values from 0 to 18 if we are dealing with numbers up to 10^{18}. In each recursive call, we try to build the sequence from left to right by placing a digit from 0 to 9. - Second state is the
**sum**of the digits we have placed so far. - Third state is the
**remainder**which defines the modulus of the number we have made so far modulo M. - Another state is the boolean variable
**tight**which tells the number we are trying to build has already become smaller than R so that in the upcoming recursive calls we can place any digit from 0 to 9. If the number has not become smaller, the maximum limit of digit we can place is digit at the current position in R.

For the number to have only non-zero digits, we maintain a variable **nonz** whose value if 1 tells the first digit in the number we have placed is a non-zero digit and thus, now we can’t place any zero digit in upcoming calls. Otherwise, we can place a zero digit as a leading zero so as to make number of digits in current number smaller than number of digits in upper limit.

Below is the implementation of the above approach:

## C++

`// C++ implementation of the approach` `#include <bits/stdc++.h>` `using` `namespace` `std;` `const` `int` `M = 20;` `// states - position, sum, rem, tight` `// sum can have values upto 162, if we` `// are dealing with numbers upto 10^18` `// when all 18 digits are 9, then sum` `// is 18 * 9 = 162` `int` `dp[M][165][M][2];` `// n is the sum of digits and number should` `// be divisible by m` `int` `n, m;` `// Function to return the count of` `// required numbers from 0 to num` `int` `count(` `int` `pos, ` `int` `sum, ` `int` `rem, ` `int` `tight,` ` ` `int` `nonz, vector<` `int` `> num)` `{` ` ` `// Last position` ` ` `if` `(pos == num.size()) {` ` ` `if` `(rem == 0 && sum == n)` ` ` `return` `1;` ` ` `return` `0;` ` ` `}` ` ` `// If this result is already computed` ` ` `// simply return it` ` ` `if` `(dp[pos][sum][rem][tight] != -1)` ` ` `return` `dp[pos][sum][rem][tight];` ` ` `int` `ans = 0;` ` ` `// Maximum limit upto which we can place` ` ` `// digit. If tight is 1, means number has` ` ` `// already become smaller so we can place` ` ` `// any digit, otherwise num[pos]` ` ` `int` `limit = (tight ? 9 : num[pos]);` ` ` `for` `(` `int` `d = 0; d <= limit; d++) {` ` ` `// If the current digit is zero` ` ` `// and nonz is 1, we can't place it` ` ` `if` `(d == 0 && nonz)` ` ` `continue` `;` ` ` `int` `currSum = sum + d;` ` ` `int` `currRem = (rem * 10 + d) % m;` ` ` `int` `currF = tight || (d < num[pos]);` ` ` `ans += count(pos + 1, currSum, currRem,` ` ` `currF, nonz || d, num);` ` ` `}` ` ` `return` `dp[pos][sum][rem][tight] = ans;` `}` `// Function to convert x into its digit vector` `// and uses count() function to return the` `// required count` `int` `solve(` `int` `x)` `{` ` ` `vector<` `int` `> num;` ` ` `while` `(x) {` ` ` `num.push_back(x % 10);` ` ` `x /= 10;` ` ` `}` ` ` `reverse(num.begin(), num.end());` ` ` `// Initialize dp` ` ` `memset` `(dp, -1, ` `sizeof` `(dp));` ` ` `return` `count(0, 0, 0, 0, 0, num);` `}` `// Driver code` `int` `main()` `{` ` ` `int` `L = 1, R = 100;` ` ` `n = 8, m = 2;` ` ` `cout << solve(R) - solve(L);` ` ` `return` `0;` `}` |

## Java

`// Java implementation of the approach` `import` `java.util.*;` `class` `GFG` `{` ` ` `static` `int` `M = ` `20` `;` `// states - position, sum, rem, tight` `// sum can have values upto 162, if we` `// are dealing with numbers upto 10^18` `// when all 18 digits are 9, then sum` `// is 18 * 9 = 162` `static` `int` `dp[][][][] = ` `new` `int` `[M][` `165` `][M][` `2` `];` `// n is the sum of digits and number should` `// be divisible by m` `static` `int` `n, m;` `// Function to return the count of` `// required numbers from 0 to num` `static` `int` `count(` `int` `pos, ` `int` `sum, ` `int` `rem, ` `int` `tight,` ` ` `int` `nonz, Vector<Integer> num)` `{` ` ` `// Last position` ` ` `if` `(pos == num.size())` ` ` `{` ` ` `if` `(rem == ` `0` `&& sum == n)` ` ` `return` `1` `;` ` ` `return` `0` `;` ` ` `}` ` ` `// If this result is already computed` ` ` `// simply return it` ` ` `if` `(dp[pos][sum][rem][tight] != -` `1` `)` ` ` `return` `dp[pos][sum][rem][tight];` ` ` `int` `ans = ` `0` `;` ` ` `// Maximum limit upto which we can place` ` ` `// digit. If tight is 1, means number has` ` ` `// already become smaller so we can place` ` ` `// any digit, otherwise num[pos]` ` ` `int` `limit = (tight != ` `0` `? ` `9` `: num.get(pos));` ` ` `for` `(` `int` `d = ` `0` `; d <= limit; d++)` ` ` `{` ` ` `// If the current digit is zero` ` ` `// and nonz is 1, we can't place it` ` ` `if` `(d == ` `0` `&& nonz != ` `0` `)` ` ` `continue` `;` ` ` `int` `currSum = sum + d;` ` ` `int` `currRem = (rem * ` `10` `+ d) % m;` ` ` `int` `currF = (tight != ` `0` `|| (d < num.get(pos))) ? ` `1` `: ` `0` `;` ` ` `ans += count(pos + ` `1` `, currSum, currRem,` ` ` `currF, (nonz != ` `0` `|| d != ` `0` `) ? ` `1` `: ` `0` `, num);` ` ` `}` ` ` `return` `dp[pos][sum][rem][tight] = ans;` `}` `// Function to convert x into its digit vector` `// and uses count() function to return the` `// required count` `static` `int` `solve(` `int` `x)` `{` ` ` `Vector<Integer> num = ` `new` `Vector<Integer>();` ` ` `while` `(x != ` `0` `)` ` ` `{` ` ` `num.add(x % ` `10` `);` ` ` `x /= ` `10` `;` ` ` `}` ` ` `Collections.reverse(num);` ` ` `// Initialize dp` ` ` `for` `(` `int` `i = ` `0` `; i < M; i++)` ` ` `for` `(` `int` `j = ` `0` `; j < ` `165` `; j++)` ` ` `for` `(` `int` `k = ` `0` `; k < M; k++)` ` ` `for` `(` `int` `l = ` `0` `; l < ` `2` `; l++)` ` ` `dp[i][j][k][l]=-` `1` `;` ` ` ` ` `return` `count(` `0` `, ` `0` `, ` `0` `, ` `0` `, ` `0` `, num);` `}` `// Driver code` `public` `static` `void` `main(String args[])` `{` ` ` `int` `L = ` `1` `, R = ` `100` `;` ` ` `n = ` `8` `; m = ` `2` `;` ` ` `System.out.print( solve(R) - solve(L));` `}` `}` `// This code is contributed by Arnab Kundu` |

## Python3

`# Python3 implementation of the approach` `# Function to return the count of` `# required numbers from 0 to num` `def` `count(pos, ` `Sum` `, rem, tight, nonz, num):` ` ` `# Last position` ` ` `if` `pos ` `=` `=` `len` `(num):` ` ` `if` `rem ` `=` `=` `0` `and` `Sum` `=` `=` `n:` ` ` `return` `1` ` ` `return` `0` ` ` `# If this result is already computed` ` ` `# simply return it` ` ` `if` `dp[pos][` `Sum` `][rem][tight] !` `=` `-` `1` `:` ` ` `return` `dp[pos][` `Sum` `][rem][tight]` ` ` ` ` `ans ` `=` `0` ` ` `# Maximum limit upto which we can place` ` ` `# digit. If tight is 1, means number has` ` ` `# already become smaller so we can place` ` ` `# any digit, otherwise num[pos]` ` ` `if` `tight:` ` ` `limit ` `=` `9` ` ` `else` `:` ` ` `limit ` `=` `num[pos]` ` ` ` ` `for` `d ` `in` `range` `(` `0` `, limit ` `+` `1` `):` ` ` `# If the current digit is zero` ` ` `# and nonz is 1, we can't place it` ` ` `if` `d ` `=` `=` `0` `and` `nonz:` ` ` `continue` ` ` ` ` `currSum ` `=` `Sum` `+` `d` ` ` `currRem ` `=` `(rem ` `*` `10` `+` `d) ` `%` `m` ` ` `currF ` `=` `int` `(tight ` `or` `(d < num[pos]))` ` ` `ans ` `+` `=` `count(pos ` `+` `1` `, currSum, currRem,` ` ` `currF, nonz ` `or` `d, num)` ` ` ` ` `dp[pos][` `Sum` `][rem][tight] ` `=` `ans` ` ` `return` `ans` `# Function to convert x into its digit` `# vector and uses count() function to` `# return the required count` `def` `solve(x):` ` ` `num ` `=` `[]` ` ` `global` `dp` ` ` ` ` `while` `x > ` `0` `:` ` ` `num.append(x ` `%` `10` `)` ` ` `x ` `/` `/` `=` `10` ` ` ` ` `num.reverse()` ` ` `# Initialize dp` ` ` `dp ` `=` `[[[[` `-` `1` `, ` `-` `1` `] ` `for` `i ` `in` `range` `(M)]` ` ` `for` `j ` `in` `range` `(` `165` `)]` ` ` `for` `k ` `in` `range` `(M)]` ` ` `return` `count(` `0` `, ` `0` `, ` `0` `, ` `0` `, ` `0` `, num)` `# Driver code` `if` `__name__ ` `=` `=` `"__main__"` `:` ` ` `L, R ` `=` `1` `, ` `100` ` ` ` ` `# n is the sum of digits and number` ` ` `# should be divisible by m` ` ` `n, m, M ` `=` `8` `, ` `2` `, ` `20` ` ` ` ` `# States - position, sum, rem, tight` ` ` `# sum can have values upto 162, if we` ` ` `# are dealing with numbers upto 10^18` ` ` `# when all 18 digits are 9, then sum` ` ` `# is 18 * 9 = 162` ` ` `dp ` `=` `[]` ` ` `print` `(solve(R) ` `-` `solve(L))` ` ` `# This code is contributed by Rituraj Jain` |

## C#

`// C# implementation of the approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG` `{` ` ` `static` `int` `M = 20;` `// states - position, sum, rem, tight` `// sum can have values upto 162, if we` `// are dealing with numbers upto 10^18` `// when all 18 digits are 9, then sum` `// is 18 * 9 = 162` `static` `int` `[,,,]dp = ` `new` `int` `[M, 165, M, 2];` `// n is the sum of digits and number should` `// be divisible by m` `static` `int` `n, m;` `// Function to return the count of` `// required numbers from 0 to num` `static` `int` `count(` `int` `pos, ` `int` `sum, ` `int` `rem, ` `int` `tight,` ` ` `int` `nonz, List<` `int` `> num)` `{` ` ` `// Last position` ` ` `if` `(pos == num.Count)` ` ` `{` ` ` `if` `(rem == 0 && sum == n)` ` ` `return` `1;` ` ` `return` `0;` ` ` `}` ` ` `// If this result is already computed` ` ` `// simply return it` ` ` `if` `(dp[pos,sum,rem,tight] != -1)` ` ` `return` `dp[pos,sum,rem,tight];` ` ` `int` `ans = 0;` ` ` `// Maximum limit upto which we can place` ` ` `// digit. If tight is 1, means number has` ` ` `// already become smaller so we can place` ` ` `// any digit, otherwise num[pos]` ` ` `int` `limit = (tight != 0 ? 9 : num[pos]);` ` ` `for` `(` `int` `d = 0; d <= limit; d++)` ` ` `{` ` ` `// If the current digit is zero` ` ` `// and nonz is 1, we can't place it` ` ` `if` `(d == 0 && nonz != 0)` ` ` `continue` `;` ` ` `int` `currSum = sum + d;` ` ` `int` `currRem = (rem * 10 + d) % m;` ` ` `int` `currF = (tight != 0 || (d < num[pos])) ? 1 : 0;` ` ` `ans += count(pos + 1, currSum, currRem,` ` ` `currF, (nonz != 0 || d != 0) ? 1 : 0, num);` ` ` `}` ` ` `return` `dp[pos, sum, rem, tight] = ans;` `}` `// Function to convert x into its digit vector` `// and uses count() function to return the` `// required count` `static` `int` `solve(` `int` `x)` `{` ` ` `List<` `int` `> num = ` `new` `List<` `int` `>();` ` ` `while` `(x != 0)` ` ` `{` ` ` `num.Add(x % 10);` ` ` `x /= 10;` ` ` `}` ` ` `num.Reverse();` ` ` `// Initialize dp` ` ` `for` `(` `int` `i = 0; i < M; i++)` ` ` `for` `(` `int` `j = 0; j < 165; j++)` ` ` `for` `(` `int` `k = 0; k < M; k++)` ` ` `for` `(` `int` `l = 0; l < 2; l++)` ` ` `dp[i, j, k, l] = -1;` ` ` ` ` `return` `count(0, 0, 0, 0, 0, num);` `}` `// Driver code` `public` `static` `void` `Main(String []args)` `{` ` ` `int` `L = 1, R = 100;` ` ` `n = 8; m = 2;` ` ` `Console.Write( solve(R) - solve(L));` `}` `}` `// This code has been contributed by 29AjayKumar` |

## Javascript

`<script>` `// JavaScript implementation of the approach` `var` `M = 20;` `// states - position, sum, rem, tight` `// sum can have values upto 162, if we` `// are dealing with numbers upto 10^18` `// when all 18 digits are 9, then sum` `// is 18 * 9 = 162` `var` `dp = Array.from(Array(M), ()=>Array(165));` `// n is the sum of digits and number should` `// be divisible by m` `var` `n, m;` `// Function to return the count of` `// required numbers from 0 to num` `function` `count( pos, sum, rem, tight, nonz, num)` `{` ` ` `// Last position` ` ` `if` `(pos == num.length) {` ` ` `if` `(rem == 0 && sum == n)` ` ` `return` `1;` ` ` `return` `0;` ` ` `}` ` ` `// If this result is already computed` ` ` `// simply return it` ` ` `if` `(dp[pos][sum][rem][tight] != -1)` ` ` `return` `dp[pos][sum][rem][tight];` ` ` `var` `ans = 0;` ` ` `// Maximum limit upto which we can place` ` ` `// digit. If tight is 1, means number has` ` ` `// already become smaller so we can place` ` ` `// any digit, otherwise num[pos]` ` ` `var` `limit = (tight ? 9 : num[pos]);` ` ` `for` `(` `var` `d = 0; d <= limit; d++) {` ` ` `// If the current digit is zero` ` ` `// and nonz is 1, we can't place it` ` ` `if` `(d == 0 && nonz)` ` ` `continue` `;` ` ` `var` `currSum = sum + d;` ` ` `var` `currRem = (rem * 10 + d) % m;` ` ` `var` `currF = (tight != 0 || (d < num[pos])) ? 1 : 0;` ` ` `ans += count(pos + 1, currSum, currRem,` ` ` `currF, (nonz != 0 || d != 0) ? 1 : 0, num);` ` ` `}` ` ` `dp[pos][sum][rem][tight] = ans;` ` ` `return` `ans;` `}` `// Function to convert x into its digit vector` `// and uses count() function to return the` `// required count` `function` `solve(x)` `{` ` ` `var` `num = [];` ` ` `while` `(x) {` ` ` `num.push(x % 10);` ` ` `x = parseInt(x/10);` ` ` `}` ` ` `num.reverse();` ` ` `// Initialize dp` ` ` `for` `(` `var` `i =0; i<M; i++)` ` ` `for` `(` `var` `j =0; j<165; j++)` ` ` `dp[i][j] = Array.from(Array(M), ()=>Array(2).fill(-1));` ` ` `return` `count(0, 0, 0, 0, 0, num);` `}` `// Driver code` `var` `L = 1, R = 100;` `n = 8, m = 2;` `document.write( solve(R) - solve(L));` `</script>` |

**Output:**

4

**Time Complexity:** O(M*M)**Auxiliary Space: **O(M*M)

**Short Python Implementation : **

## Python3

`# User Input` `l, r, n, m ` `=` `1` `, ` `100` `, ` `8` `, ` `2` `# Initialize Result` `output ` `=` `[]` `# Traverse through all numbers` `for` `x ` `in` `range` `(l, r` `+` `1` `):` ` ` `# Check for all conditions in every number` ` ` `if` `sum` `([` `int` `(k) ` `for` `k ` `in` `str` `(x)]) ` `=` `=` `n ` `and` `x ` `%` `m ` `=` `=` `0` `and` `'0'` `not` `in` `str` `(x): ` `# Check conditions` ` ` `output.append(x)` ` ` `print` `(` `len` `(output)) ` ` ` `# This code is contributed by mailprakashindia` |