Skip to content

Commit 2f350d9

Browse files
authoredDec 9, 2024
feat: add go solution to lc problem: No.3348 (#3848)
1 parent e5e5f55 commit 2f350d9

File tree

3 files changed

+396
-2
lines changed

3 files changed

+396
-2
lines changed
 

‎solution/3300-3399/3348.Smallest Divisible Digit Product II/README.md

+132-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,138 @@ tags:
107107
#### Go
108108

109109
```go
110-
110+
func smallestNumber(num string, t int64) string {
111+
primeCount, isDivisible := getPrimeCount(t)
112+
if !isDivisible {
113+
return "-1"
114+
}
115+
116+
factorCount := getFactorCount(primeCount)
117+
if sumValues(factorCount) > len(num) {
118+
return construct(factorCount)
119+
}
120+
121+
primeCountPrefix := getPrimeCountFromString(num)
122+
firstZeroIndex := strings.Index(num, "0")
123+
if firstZeroIndex == -1 {
124+
firstZeroIndex = len(num)
125+
if isSubset(primeCount, primeCountPrefix) {
126+
return num
127+
}
128+
}
129+
130+
for i := len(num) - 1; i >= 0; i-- {
131+
d := int(num[i] - '0')
132+
primeCountPrefix = subtract(primeCountPrefix, kFactorCounts[d])
133+
spaceAfterThisDigit := len(num) - 1 - i
134+
if i > firstZeroIndex {
135+
continue
136+
}
137+
for biggerDigit := d + 1; biggerDigit < 10; biggerDigit++ {
138+
factorsAfterReplacement := getFactorCount(
139+
subtract(subtract(primeCount, primeCountPrefix), kFactorCounts[biggerDigit]),
140+
)
141+
if sumValues(factorsAfterReplacement) <= spaceAfterThisDigit {
142+
fillOnes := spaceAfterThisDigit - sumValues(factorsAfterReplacement)
143+
return num[:i] + strconv.Itoa(biggerDigit) + strings.Repeat("1", fillOnes) + construct(factorsAfterReplacement)
144+
}
145+
}
146+
}
147+
148+
factorsAfterExtension := getFactorCount(primeCount)
149+
return strings.Repeat("1", len(num)+1-sumValues(factorsAfterExtension)) + construct(factorsAfterExtension)
150+
}
151+
152+
var kFactorCounts = map[int]map[int]int{
153+
0: {}, 1: {}, 2: {2: 1}, 3: {3: 1}, 4: {2: 2},
154+
5: {5: 1}, 6: {2: 1, 3: 1}, 7: {7: 1}, 8: {2: 3}, 9: {3: 2},
155+
}
156+
157+
func getPrimeCount(t int64) (map[int]int, bool) {
158+
count := map[int]int{2: 0, 3: 0, 5: 0, 7: 0}
159+
for _, prime := range []int{2, 3, 5, 7} {
160+
for t%int64(prime) == 0 {
161+
t /= int64(prime)
162+
count[prime]++
163+
}
164+
}
165+
return count, t == 1
166+
}
167+
168+
func getPrimeCountFromString(num string) map[int]int {
169+
count := map[int]int{2: 0, 3: 0, 5: 0, 7: 0}
170+
for _, d := range num {
171+
for prime, freq := range kFactorCounts[int(d-'0')] {
172+
count[prime] += freq
173+
}
174+
}
175+
return count
176+
}
177+
178+
func getFactorCount(count map[int]int) map[int]int {
179+
res := map[int]int{}
180+
count8 := count[2] / 3
181+
remaining2 := count[2] % 3
182+
count9 := count[3] / 2
183+
count3 := count[3] % 2
184+
count4 := remaining2 / 2
185+
count2 := remaining2 % 2
186+
count6 := 0
187+
if count2 == 1 && count3 == 1 {
188+
count2, count3 = 0, 0
189+
count6 = 1
190+
}
191+
if count3 == 1 && count4 == 1 {
192+
count2 = 1
193+
count6 = 1
194+
count3, count4 = 0, 0
195+
}
196+
res[2] = count2
197+
res[3] = count3
198+
res[4] = count4
199+
res[5] = count[5]
200+
res[6] = count6
201+
res[7] = count[7]
202+
res[8] = count8
203+
res[9] = count9
204+
return res
205+
}
206+
207+
func construct(factors map[int]int) string {
208+
var res strings.Builder
209+
for digit := 2; digit < 10; digit++ {
210+
res.WriteString(strings.Repeat(strconv.Itoa(digit), factors[digit]))
211+
}
212+
return res.String()
213+
}
214+
215+
func isSubset(a, b map[int]int) bool {
216+
for key, value := range a {
217+
if b[key] < value {
218+
return false
219+
}
220+
}
221+
return true
222+
}
223+
224+
func subtract(a, b map[int]int) map[int]int {
225+
res := make(map[int]int, len(a))
226+
for k, v := range a {
227+
res[k] = v
228+
}
229+
for k, v := range b {
230+
res[k] = max(0, res[k]-v)
231+
}
232+
return res
233+
}
234+
235+
func sumValues(count map[int]int) int {
236+
sum := 0
237+
for _, v := range count {
238+
sum += v
239+
}
240+
return sum
241+
}
111242
```
112243

113244
<!-- tabs:end -->

‎solution/3300-3399/3348.Smallest Divisible Digit Product II/README_EN.md

+132-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,138 @@ tags:
104104
#### Go
105105

106106
```go
107-
107+
func smallestNumber(num string, t int64) string {
108+
primeCount, isDivisible := getPrimeCount(t)
109+
if !isDivisible {
110+
return "-1"
111+
}
112+
113+
factorCount := getFactorCount(primeCount)
114+
if sumValues(factorCount) > len(num) {
115+
return construct(factorCount)
116+
}
117+
118+
primeCountPrefix := getPrimeCountFromString(num)
119+
firstZeroIndex := strings.Index(num, "0")
120+
if firstZeroIndex == -1 {
121+
firstZeroIndex = len(num)
122+
if isSubset(primeCount, primeCountPrefix) {
123+
return num
124+
}
125+
}
126+
127+
for i := len(num) - 1; i >= 0; i-- {
128+
d := int(num[i] - '0')
129+
primeCountPrefix = subtract(primeCountPrefix, kFactorCounts[d])
130+
spaceAfterThisDigit := len(num) - 1 - i
131+
if i > firstZeroIndex {
132+
continue
133+
}
134+
for biggerDigit := d + 1; biggerDigit < 10; biggerDigit++ {
135+
factorsAfterReplacement := getFactorCount(
136+
subtract(subtract(primeCount, primeCountPrefix), kFactorCounts[biggerDigit]),
137+
)
138+
if sumValues(factorsAfterReplacement) <= spaceAfterThisDigit {
139+
fillOnes := spaceAfterThisDigit - sumValues(factorsAfterReplacement)
140+
return num[:i] + strconv.Itoa(biggerDigit) + strings.Repeat("1", fillOnes) + construct(factorsAfterReplacement)
141+
}
142+
}
143+
}
144+
145+
factorsAfterExtension := getFactorCount(primeCount)
146+
return strings.Repeat("1", len(num)+1-sumValues(factorsAfterExtension)) + construct(factorsAfterExtension)
147+
}
148+
149+
var kFactorCounts = map[int]map[int]int{
150+
0: {}, 1: {}, 2: {2: 1}, 3: {3: 1}, 4: {2: 2},
151+
5: {5: 1}, 6: {2: 1, 3: 1}, 7: {7: 1}, 8: {2: 3}, 9: {3: 2},
152+
}
153+
154+
func getPrimeCount(t int64) (map[int]int, bool) {
155+
count := map[int]int{2: 0, 3: 0, 5: 0, 7: 0}
156+
for _, prime := range []int{2, 3, 5, 7} {
157+
for t%int64(prime) == 0 {
158+
t /= int64(prime)
159+
count[prime]++
160+
}
161+
}
162+
return count, t == 1
163+
}
164+
165+
func getPrimeCountFromString(num string) map[int]int {
166+
count := map[int]int{2: 0, 3: 0, 5: 0, 7: 0}
167+
for _, d := range num {
168+
for prime, freq := range kFactorCounts[int(d-'0')] {
169+
count[prime] += freq
170+
}
171+
}
172+
return count
173+
}
174+
175+
func getFactorCount(count map[int]int) map[int]int {
176+
res := map[int]int{}
177+
count8 := count[2] / 3
178+
remaining2 := count[2] % 3
179+
count9 := count[3] / 2
180+
count3 := count[3] % 2
181+
count4 := remaining2 / 2
182+
count2 := remaining2 % 2
183+
count6 := 0
184+
if count2 == 1 && count3 == 1 {
185+
count2, count3 = 0, 0
186+
count6 = 1
187+
}
188+
if count3 == 1 && count4 == 1 {
189+
count2 = 1
190+
count6 = 1
191+
count3, count4 = 0, 0
192+
}
193+
res[2] = count2
194+
res[3] = count3
195+
res[4] = count4
196+
res[5] = count[5]
197+
res[6] = count6
198+
res[7] = count[7]
199+
res[8] = count8
200+
res[9] = count9
201+
return res
202+
}
203+
204+
func construct(factors map[int]int) string {
205+
var res strings.Builder
206+
for digit := 2; digit < 10; digit++ {
207+
res.WriteString(strings.Repeat(strconv.Itoa(digit), factors[digit]))
208+
}
209+
return res.String()
210+
}
211+
212+
func isSubset(a, b map[int]int) bool {
213+
for key, value := range a {
214+
if b[key] < value {
215+
return false
216+
}
217+
}
218+
return true
219+
}
220+
221+
func subtract(a, b map[int]int) map[int]int {
222+
res := make(map[int]int, len(a))
223+
for k, v := range a {
224+
res[k] = v
225+
}
226+
for k, v := range b {
227+
res[k] = max(0, res[k]-v)
228+
}
229+
return res
230+
}
231+
232+
func sumValues(count map[int]int) int {
233+
sum := 0
234+
for _, v := range count {
235+
sum += v
236+
}
237+
return sum
238+
}
108239
```
109240

110241
<!-- tabs:end -->

0 commit comments

Comments
 (0)