feat: progress
This commit is contained in:
115
pkg/questions/multiply_strings/main.go
Normal file
115
pkg/questions/multiply_strings/main.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package multiplystrings
|
||||
|
||||
func addDigits(a, b byte) (byte, byte) {
|
||||
abInt := int(a-'0') + int(b-'0')
|
||||
return byte(abInt/10) + '0', byte(abInt%10) + '0'
|
||||
}
|
||||
|
||||
func addByDigit(dst *[]byte, src byte) {
|
||||
for i, b := range *dst {
|
||||
if src == '0' {
|
||||
return
|
||||
}
|
||||
|
||||
src, (*dst)[i] = addDigits(b, src)
|
||||
}
|
||||
|
||||
if src != '0' {
|
||||
*dst = append(*dst, src)
|
||||
}
|
||||
}
|
||||
|
||||
func add(dst *[]byte, src []byte) {
|
||||
carry := byte('0')
|
||||
|
||||
for i := range max(len(*dst), len(src)) {
|
||||
d, s := byte('0'), byte('0')
|
||||
if len(*dst) > i {
|
||||
d = (*dst)[i]
|
||||
}
|
||||
if len(src) > i {
|
||||
s = src[i]
|
||||
}
|
||||
|
||||
hi, lo := addDigits(d, s)
|
||||
total := []byte{lo, hi}
|
||||
addByDigit(&total, carry)
|
||||
(*dst)[i], carry = total[0], total[1]
|
||||
}
|
||||
|
||||
if carry != '0' {
|
||||
*dst = append(*dst, carry)
|
||||
}
|
||||
}
|
||||
|
||||
func multiplyDigits(a, b byte) (byte, byte) {
|
||||
abInt := int(a-'0') * int(b-'0')
|
||||
return byte(abInt/10) + '0', byte(abInt%10) + '0'
|
||||
}
|
||||
|
||||
func multiplyByDigit(and []byte, ier byte) []byte {
|
||||
result, carry := []byte{}, byte('0')
|
||||
for _, b := range and {
|
||||
hi, lo := multiplyDigits(b, ier)
|
||||
|
||||
// Fold the incoming carry into the low digit; any overflow rolls
|
||||
// into hi, which is small enough that it never overflows again.
|
||||
c, lo := addDigits(lo, carry)
|
||||
_, carry = addDigits(hi, c)
|
||||
|
||||
result = append(result, lo)
|
||||
}
|
||||
|
||||
if carry != '0' {
|
||||
result = append(result, carry)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func reverse(s string) []byte {
|
||||
digits := make([]byte, len(s))
|
||||
for i := range s {
|
||||
digits[len(s)-1-i] = s[i]
|
||||
}
|
||||
|
||||
return digits
|
||||
}
|
||||
|
||||
func multiply(a, b string) string {
|
||||
if a == "0" || b == "0" {
|
||||
return "0"
|
||||
}
|
||||
|
||||
and := reverse(a)
|
||||
result := make([]byte, len(a)+len(b))
|
||||
for i := range result {
|
||||
result[i] = '0'
|
||||
}
|
||||
|
||||
for i := range len(b) {
|
||||
ier := b[len(b)-1-i]
|
||||
partial := multiplyByDigit(and, ier)
|
||||
|
||||
// Shift left by i places (little-endian: i leading zeros).
|
||||
shifted := make([]byte, i+len(partial))
|
||||
for j := range i {
|
||||
shifted[j] = '0'
|
||||
}
|
||||
copy(shifted[i:], partial)
|
||||
|
||||
add(&result, shifted)
|
||||
}
|
||||
|
||||
end := len(result)
|
||||
for end > 1 && result[end-1] == '0' {
|
||||
end--
|
||||
}
|
||||
|
||||
out := make([]byte, end)
|
||||
for i := range end {
|
||||
out[i] = result[end-1-i]
|
||||
}
|
||||
|
||||
return string(out)
|
||||
}
|
||||
Reference in New Issue
Block a user