Use this to learn the idea, then write your own version.
1FACTOR_COUNTS = {2 0: collections.Counter(),3 1: collections.Counter(),4 2: collections.Counter([2]),5 3: collections.Counter([3]),6 4: collections.Counter([2, 2]),7 5: collections.Counter([5]),8 6: collections.Counter([2, 3]),9 7: collections.Counter([7]),10 8: collections.Counter([2, 2, 2]),11 9: collections.Counter([3, 3]),12}13 14 15class Solution:16 def smallestNumber(self, num: str, t: int) -> str:17 primeCount, isDivisible = self._getPrimeCount(t)18 if not isDivisible:19 return '-1'20 21 factorCount = self._getFactorCount(primeCount)22 if sum(factorCount.values()) > len(num):23 return ''.join(factor * freq for factor, freq in factorCount.items())24 25 primeCountPrefix = sum((FACTOR_COUNTS[int(c)]26 for c in num), start=collections.Counter())27 firstZeroIndex = next((i for i, d in enumerate(num) if d == '0'), len(num))28 if firstZeroIndex == len(num) and primeCount <= primeCountPrefix:29 return num30 31 for i, c in reversed(list(enumerate(num))):32 d = int(c)33 34 primeCountPrefix -= FACTOR_COUNTS[d]35 spaceAfterThisDigit = len(num) - 1 - i36 if i <= firstZeroIndex:37 for biggerDigit in range(d + 1, 10):38 39 factorsAfterReplacement = self._getFactorCount(40 primeCount - primeCountPrefix - FACTOR_COUNTS[biggerDigit]41 )42 43 if sum(factorsAfterReplacement.values()) <= spaceAfterThisDigit:44 45 fillOnes = spaceAfterThisDigit - sum(46 factorsAfterReplacement.values())47 return (48 num[:i] 49 + str(biggerDigit) 50 + '1' * fillOnes 51 + ''.join(factor * freq for factor,52 freq in factorsAfterReplacement.items())53 )54 55 56 57 factorCount = self._getFactorCount(primeCount)58 return (59 '1' * (len(num) + 1 - sum(factorCount.values()))60 + ''.join(factor * freq for factor, freq in factorCount.items())61 )62 63 def _getPrimeCount(self, t: int) -> tuple[dict[int, int], bool]:64 """65 Returns the count of prime factors of t and if t is divisible by 2, 3, 5, 7.66 """67 count = collections.Counter()68 for prime in [2, 3, 5, 7]:69 while t % prime == 0:70 t = prime71 count[prime] += 172 return count, t == 173 74 def _getFactorCount(self, count: dict[int, int]) -> dict[str, int]:75 """Returns the required factors to form the smallest number."""76 count8, remaining2 = divmod(count[2], 3) 77 count9, count3 = divmod(count[3], 2) 78 count4, count2 = divmod(remaining2, 2) 79 80 count2, count3, count6 = ((0, 0, 1) if count2 == 1 and count3 == 181 else (count2, count3, 0))82 83 count2, count6, count3, count4 = ((1, 1, 0, 0)84 if count3 == 1 and count4 == 185 else (count2, count6, count3, count4))86 return {'2': count2, '3': count3, '4': count4, '5': count[5],87 '6': count6, '7': count[7], '8': count8, '9': count9}88