Skip to content

Commit b901699

Browse files
authored
Create Solution.go
1 parent f96887d commit b901699

File tree

1 file changed

+132
-0
lines changed
  • solution/3300-3399/3348.Smallest Divisible Digit Product II

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
func smallestNumber(num string, t int64) string {
2+
primeCount, isDivisible := getPrimeCount(t)
3+
if !isDivisible {
4+
return "-1"
5+
}
6+
7+
factorCount := getFactorCount(primeCount)
8+
if sumValues(factorCount) > len(num) {
9+
return construct(factorCount)
10+
}
11+
12+
primeCountPrefix := getPrimeCountFromString(num)
13+
firstZeroIndex := strings.Index(num, "0")
14+
if firstZeroIndex == -1 {
15+
firstZeroIndex = len(num)
16+
if isSubset(primeCount, primeCountPrefix) {
17+
return num
18+
}
19+
}
20+
21+
for i := len(num) - 1; i >= 0; i-- {
22+
d := int(num[i] - '0')
23+
primeCountPrefix = subtract(primeCountPrefix, kFactorCounts[d])
24+
spaceAfterThisDigit := len(num) - 1 - i
25+
if i > firstZeroIndex {
26+
continue
27+
}
28+
for biggerDigit := d + 1; biggerDigit < 10; biggerDigit++ {
29+
factorsAfterReplacement := getFactorCount(
30+
subtract(subtract(primeCount, primeCountPrefix), kFactorCounts[biggerDigit]),
31+
)
32+
if sumValues(factorsAfterReplacement) <= spaceAfterThisDigit {
33+
fillOnes := spaceAfterThisDigit - sumValues(factorsAfterReplacement)
34+
return num[:i] + strconv.Itoa(biggerDigit) + strings.Repeat("1", fillOnes) + construct(factorsAfterReplacement)
35+
}
36+
}
37+
}
38+
39+
factorsAfterExtension := getFactorCount(primeCount)
40+
return strings.Repeat("1", len(num)+1-sumValues(factorsAfterExtension)) + construct(factorsAfterExtension)
41+
}
42+
43+
var kFactorCounts = map[int]map[int]int{
44+
0: {}, 1: {}, 2: {2: 1}, 3: {3: 1}, 4: {2: 2},
45+
5: {5: 1}, 6: {2: 1, 3: 1}, 7: {7: 1}, 8: {2: 3}, 9: {3: 2},
46+
}
47+
48+
func getPrimeCount(t int64) (map[int]int, bool) {
49+
count := map[int]int{2: 0, 3: 0, 5: 0, 7: 0}
50+
for _, prime := range []int{2, 3, 5, 7} {
51+
for t%int64(prime) == 0 {
52+
t /= int64(prime)
53+
count[prime]++
54+
}
55+
}
56+
return count, t == 1
57+
}
58+
59+
func getPrimeCountFromString(num string) map[int]int {
60+
count := map[int]int{2: 0, 3: 0, 5: 0, 7: 0}
61+
for _, d := range num {
62+
for prime, freq := range kFactorCounts[int(d-'0')] {
63+
count[prime] += freq
64+
}
65+
}
66+
return count
67+
}
68+
69+
func getFactorCount(count map[int]int) map[int]int {
70+
res := map[int]int{}
71+
count8 := count[2] / 3
72+
remaining2 := count[2] % 3
73+
count9 := count[3] / 2
74+
count3 := count[3] % 2
75+
count4 := remaining2 / 2
76+
count2 := remaining2 % 2
77+
count6 := 0
78+
if count2 == 1 && count3 == 1 {
79+
count2, count3 = 0, 0
80+
count6 = 1
81+
}
82+
if count3 == 1 && count4 == 1 {
83+
count2 = 1
84+
count6 = 1
85+
count3, count4 = 0, 0
86+
}
87+
res[2] = count2
88+
res[3] = count3
89+
res[4] = count4
90+
res[5] = count[5]
91+
res[6] = count6
92+
res[7] = count[7]
93+
res[8] = count8
94+
res[9] = count9
95+
return res
96+
}
97+
98+
func construct(factors map[int]int) string {
99+
var res strings.Builder
100+
for digit := 2; digit < 10; digit++ {
101+
res.WriteString(strings.Repeat(strconv.Itoa(digit), factors[digit]))
102+
}
103+
return res.String()
104+
}
105+
106+
func isSubset(a, b map[int]int) bool {
107+
for key, value := range a {
108+
if b[key] < value {
109+
return false
110+
}
111+
}
112+
return true
113+
}
114+
115+
func subtract(a, b map[int]int) map[int]int {
116+
res := make(map[int]int, len(a))
117+
for k, v := range a {
118+
res[k] = v
119+
}
120+
for k, v := range b {
121+
res[k] = max(0, res[k]-v)
122+
}
123+
return res
124+
}
125+
126+
func sumValues(count map[int]int) int {
127+
sum := 0
128+
for _, v := range count {
129+
sum += v
130+
}
131+
return sum
132+
}

0 commit comments

Comments
 (0)