<p>An integer <code>x</code> is <strong>numerically balanced</strong> if for every digit <code>d</code> in the number <code>x</code>, there are <strong>exactly</strong> <code>d</code> occurrences of that digit in <code>x</code>.</p>

<p>Given an integer <code>n</code>, return <em>the <strong>smallest numerically balanced</strong> number <strong>strictly greater</strong> than </em><code>n</code><em>.</em></p>

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

<pre>
<strong>Input:</strong> n = 1
<strong>Output:</strong> 22
<strong>Explanation:</strong> 
22 is numerically balanced since:
- The digit 2 occurs 2 times. 
It is also the smallest numerically balanced number strictly greater than 1.
</pre>

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

<pre>
<strong>Input:</strong> n = 1000
<strong>Output:</strong> 1333
<strong>Explanation:</strong> 
1333 is numerically balanced since:
- The digit 1 occurs 1 time.
- The digit 3 occurs 3 times. 
It is also the smallest numerically balanced number strictly greater than 1000.
Note that 1022 cannot be the answer because 0 appeared more than 0 times.
</pre>

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

<pre>
<strong>Input:</strong> n = 3000
<strong>Output:</strong> 3133
<strong>Explanation:</strong> 
3133 is numerically balanced since:
- The digit 1 occurs 1 time.
- The digit 3 occurs 3 times.
It is also the smallest numerically balanced number strictly greater than 3000.
</pre>

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

<ul>
	<li><code>0 &lt;= n &lt;= 10<sup>6</sup></code></li>
</ul>

class Solution:
    def nextBeautifulNumber(self, n: int) -> int:

        def _get_digits(x):
            if x == 1:
                return ['1']
            arr = range(1, x + 1)
            tuples = {tuple(sorted(t)) for l in range(1, len(arr)) for t in itertools.combinations(arr, l) if sum(t) == x}
            out = []
            for t in tuples:
                s = ""
                for d in t:
                    s += str(d) * d
                out.append(s)
            return out

        def _get_possible_numbers(x):
            n_digits = len(str(x))
            possible_digits = _get_digits(n_digits) + _get_digits(n_digits + 1)
            possible_numbers = []
            for digit_perm in possible_digits:
                possible_numbers += [int("".join(s)) for s in permutations(digit_perm, len(digit_perm))]
            return sorted(list(set(possible_numbers)))

        possible_numbers = _get_possible_numbers(n)

        while possible_numbers[0] <= n:
            possible_numbers.pop(0)

        return possible_numbers[0]
            

371