71 lines
1.3 KiB
Go
71 lines
1.3 KiB
Go
package q433
|
|
|
|
import "slices"
|
|
|
|
func canMutate(a, b string) bool {
|
|
diff := false
|
|
for i := range len(a) {
|
|
if a[i] != b[i] {
|
|
if diff {
|
|
return false
|
|
}
|
|
diff = true
|
|
}
|
|
}
|
|
return diff // exactly one mutation
|
|
}
|
|
|
|
func minMutation(startGene string, endGene string, bank []string) int {
|
|
reachables := make([][]int, len(bank))
|
|
initial := []int{}
|
|
target := -1
|
|
for i := range len(bank) - 1 {
|
|
for j := i + 1; j < len(bank); j++ {
|
|
if canMutate(bank[i], bank[j]) {
|
|
reachables[i] = append(reachables[i], j)
|
|
reachables[j] = append(reachables[j], i)
|
|
}
|
|
}
|
|
}
|
|
for i := range bank {
|
|
if bank[i] == endGene {
|
|
target = i
|
|
}
|
|
if canMutate(startGene, bank[i]) {
|
|
if i == target {
|
|
return 1
|
|
}
|
|
initial = append(initial, i)
|
|
}
|
|
}
|
|
if target == -1 {
|
|
return -1
|
|
}
|
|
|
|
type qElem struct {
|
|
path []int
|
|
}
|
|
queue := make([]qElem, 0, len(initial)*2)
|
|
for _, i := range initial {
|
|
queue = append(queue, qElem{path: []int{i}})
|
|
}
|
|
|
|
for ; len(queue) > 0; queue = queue[1:] {
|
|
cur := queue[0].path
|
|
last := cur[len(cur)-1]
|
|
next := reachables[last]
|
|
for _, n := range next {
|
|
if n == target {
|
|
return len(cur) + 1
|
|
}
|
|
if slices.Contains(cur, n) {
|
|
continue
|
|
}
|
|
queue = append(queue, qElem{path: append(cur, n)})
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
var _ = minMutation
|