mirror of
https://gitlab.com/mfocko/LeetCode.git
synced 2024-11-09 15:59:06 +01:00
go: add «726. Number of Atoms»
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
c69a2e96c7
commit
a718efd3d8
2 changed files with 120 additions and 0 deletions
92
go/number-of-atoms.go
Normal file
92
go/number-of-atoms.go
Normal file
|
@ -0,0 +1,92 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func countOfAtoms(formula string) string {
|
||||
var stack []map[string]int
|
||||
stack = append(stack, make(map[string]int))
|
||||
|
||||
i := 0
|
||||
for i < len(formula) {
|
||||
if formula[i] == '(' {
|
||||
stack = append(stack, make(map[string]int))
|
||||
i++
|
||||
} else if formula[i] == ')' {
|
||||
count := stack[len(stack)-1]
|
||||
stack = stack[:len(stack)-1]
|
||||
|
||||
i++
|
||||
j := i
|
||||
for j < len(formula) && unicode.IsDigit(rune(formula[j])) {
|
||||
j++
|
||||
}
|
||||
|
||||
multiplier := 1
|
||||
if i < j {
|
||||
parsedMultiplier, err := strconv.ParseInt(formula[i:j], 10, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
multiplier = int(parsedMultiplier)
|
||||
}
|
||||
i = j
|
||||
|
||||
parent := stack[len(stack)-1]
|
||||
for element, count := range count {
|
||||
parent[element] += count * multiplier
|
||||
}
|
||||
} else {
|
||||
j := i + 1
|
||||
for j < len(formula) && unicode.IsLower(rune(formula[j])) {
|
||||
j++
|
||||
}
|
||||
|
||||
element := formula[i:j]
|
||||
i = j
|
||||
|
||||
for j < len(formula) && unicode.IsDigit(rune(formula[j])) {
|
||||
j++
|
||||
}
|
||||
|
||||
count := 1
|
||||
if i < j {
|
||||
parsedCount, err := strconv.ParseInt(formula[i:j], 10, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
count = int(parsedCount)
|
||||
}
|
||||
i = j
|
||||
|
||||
parent := stack[len(stack)-1]
|
||||
parent[element] += count
|
||||
}
|
||||
}
|
||||
|
||||
finalCount := stack[0]
|
||||
|
||||
elements := make([]string, len(finalCount))
|
||||
for element := range finalCount {
|
||||
elements = append(elements, element)
|
||||
}
|
||||
slices.Sort(elements)
|
||||
|
||||
answer := ""
|
||||
for _, element := range elements {
|
||||
answer += element
|
||||
|
||||
count := finalCount[element]
|
||||
if count > 1 {
|
||||
answer += fmt.Sprintf("%d", count)
|
||||
}
|
||||
}
|
||||
|
||||
return answer
|
||||
}
|
28
go/number-of-atoms_test.go
Normal file
28
go/number-of-atoms_test.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func _test_NumberOfAtoms(t *testing.T, input, expected string) {
|
||||
result := countOfAtoms(input)
|
||||
if result != expected {
|
||||
t.Errorf("Expected ‹%s› for ‹%s›, but got: ‹%s›!", expected, input, result)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_NumberOfAtoms_Easy(t *testing.T) {
|
||||
_test_NumberOfAtoms(t, "H2", "H2")
|
||||
_test_NumberOfAtoms(t, "O2", "O2")
|
||||
_test_NumberOfAtoms(t, "HO", "HO")
|
||||
_test_NumberOfAtoms(t, "H2O", "H2O")
|
||||
_test_NumberOfAtoms(t, "H2SO4", "H2O4S")
|
||||
}
|
||||
|
||||
func Test_NumberOfAtoms_Medium(t *testing.T) {
|
||||
_test_NumberOfAtoms(t, "Mg(OH)2", "H2MgO2")
|
||||
_test_NumberOfAtoms(t, "C6H5OH", "C6H6O")
|
||||
_test_NumberOfAtoms(t, "C6H5CH3", "C7H8")
|
||||
}
|
||||
|
||||
func Test_NumberOfAtoms_Hard(t *testing.T) {
|
||||
_test_NumberOfAtoms(t, "K4(ON(SO3)2)2", "K4N2O14S4")
|
||||
}
|
Loading…
Reference in a new issue