<p>You are given two numeric strings <code>num1</code> and <code>num2</code> and two integers <code>max_sum</code> and <code>min_sum</code>. We denote an integer <code>x</code> to be <em>good</em> if:</p>

<ul>
	<li><code>num1 &lt;= x &lt;= num2</code></li>
	<li><code>min_sum &lt;= digit_sum(x) &lt;= max_sum</code>.</li>
</ul>

<p>Return <em>the number of good integers</em>. Since the answer may be large, return it modulo <code>10<sup>9</sup> + 7</code>.</p>

<p>Note that <code>digit_sum(x)</code> denotes the sum of the digits of <code>x</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> num1 = &quot;1&quot;, num2 = &quot;12&quot;, <code>min_sum</code> = 1, max_sum = 8
<strong>Output:</strong> 11
<strong>Explanation:</strong> There are 11 integers whose sum of digits lies between 1 and 8 are 1,2,3,4,5,6,7,8,10,11, and 12. Thus, we return 11.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> num1 = &quot;1&quot;, num2 = &quot;5&quot;, <code>min_sum</code> = 1, max_sum = 5
<strong>Output:</strong> 5
<strong>Explanation:</strong> The 5 integers whose sum of digits lies between 1 and 5 are 1,2,3,4, and 5. Thus, we return 5.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= num1 &lt;= num2 &lt;= 10<sup>22</sup></code></li>
	<li><code>1 &lt;= min_sum &lt;= max_sum &lt;= 400</code></li>
</ul>

class Solution:
    def count(self, num1: str, num2: str, min_sum: int, max_sum: int) -> int:
        @cache
        def f(n, sm):
            if sm < 0: return 0
            if sm == 0: return 1
            sn = str(n)
            if len(sn) == 1: return int(n >= sm)
            res = f(int(sn[1:]), sm - int(sn[0]))
            for i in range(min(sm + 1, int(sn[0]))): 
                res += f(int('9' * (len(sn) - 1)), sm - i)
            # print(n, sm, res)
            return res
        
        return sum((f(int(num2), sm) - f(int(num1) - 1, sm) for sm in range(min_sum, max_sum + 1))) % int(1e9 + 7)

# With comments version 
class Solution:
    def count(self, num1: str, num2: str, min_sum: int, max_sum: int) -> int:
        @cache
        def f(n, sm):
            """Answers the question how many numbers less than 
            or equal to n have digits that add up to sm.
            """
            if sm < 0: return 0  # impossible so return 0
            if sm == 0: return 1 # only 0 will work
            sn = str(n)          # string version of n to make the rest easier
            
            # ie with n == 9 and sm == 6, only 6 will work
            if len(sn) == 1: return int(n >= sm) 
            
            # if the first digit is fixed then the rest of the digits
            # must not represent a greater number than they currently do
            res = f(int(sn[1:]), sm - int(sn[0])) 

            # If the first digit is less than it is, then the rest can be up to 9999...
            for i in range(min(sm + 1, int(sn[0]))): 
                res += f(int('9' * (len(sn) - 1)), sm - i)

            return res
            
        # With a max of 400 sm's, we will go through each one. 
        return sum((f(int(num2), sm) - f(int(num1) - 1, sm) for sm in range(min_sum, max_sum + 1))) % int(1e9 + 7)
1088