61 lines
1.1 KiB
Go
61 lines
1.1 KiB
Go
package wordladder
|
|
|
|
import "iter"
|
|
|
|
type wordSet map[string][]string
|
|
|
|
func (w wordSet) add(word string) {
|
|
buffer := []byte(word)
|
|
for i := range word {
|
|
buffer[i] = '*'
|
|
w[string(buffer)] = append(w[string(buffer)], word)
|
|
buffer[i] = word[i]
|
|
}
|
|
}
|
|
|
|
func (w wordSet) neighborsOf(word string) iter.Seq[string] {
|
|
return func(yield func(string) bool) {
|
|
buffer := []byte(word)
|
|
for i := range word {
|
|
buffer[i] = '*'
|
|
for _, neighbor := range w[string(buffer)] {
|
|
yield(neighbor)
|
|
}
|
|
buffer[i] = word[i]
|
|
}
|
|
}
|
|
}
|
|
|
|
func ladderLength(beginWord string, endWord string, wordList []string) int {
|
|
ws := wordSet{}
|
|
for _, word := range wordList {
|
|
ws.add(word)
|
|
}
|
|
|
|
idx, iteration, visited := 0, []string{beginWord}, map[string]bool{}
|
|
visited[beginWord] = true
|
|
|
|
for {
|
|
nextIteration := []string{}
|
|
for _, it := range iteration {
|
|
if it == endWord {
|
|
return idx
|
|
}
|
|
|
|
for neighbor := range ws.neighborsOf(it) {
|
|
if visited[neighbor] {
|
|
continue
|
|
}
|
|
|
|
visited[neighbor] = true
|
|
nextIteration = append(nextIteration, neighbor)
|
|
}
|
|
}
|
|
|
|
iteration = nextIteration
|
|
idx++
|
|
}
|
|
|
|
return 0
|
|
}
|