master
1description =<<-DOC
2Given two words, beginWord and endWord, and a wordList of approved words, find the length of the shortest transformation sequence from beginWord to endWord such that:
3
4Only one letter can be changed at a time
5Each transformed word must exist in the wordList.
6Return the length of the shortest transformation sequence, or 0 if no such transformation sequence exists.
7
8Note: beginWord does not count as a transformed word. You can assume that beginWord and endWord are not empty and are not the same.
9
10Example
11
12For beginWord = "hit", endWord = "cog", and wordList = ["hot", "dot", "dog", "lot", "log", "cog"], the output should be
13wordLadder(beginWord, endWord, wordList) = 5.
14
15The shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog" with a length of 5.
16
17Input/Output
18
19[time limit] 4000ms (rb)
20[input] string beginWord
21
22Guaranteed constraints:
231 ≤ beginWord.length ≤ 5.
24
25[input] string endWord
26
27Guaranteed constraints:
28endWord.length = beginWord.length.
29
30[input] array.string wordList
31
32An array containing all of the approved words. All words in the array are the same length and contain only lowercase English letters. You can assume that there are no duplicates in wordList.
33
34Guaranteed constraints:
352 ≤ wordList.length ≤ 600,
36wordList[i].length = beginWord.length.
37
38[output] integer
39
40An integer representing the length of the shortest transformation sequence from beginWord to endWord using only words from wordList as described above.
41DOC
42
43describe "word_ladder" do
44 def match?(word, other)
45 failures = 0
46 word.size.times do |n|
47 if word[n] != other[n]
48 failures += 1
49 return false if failures > 1
50 end
51 end
52 true
53 end
54
55 # use a queue to do a breadth (level) first search.
56 def word_ladder(words, begin_word:, end_word:)
57 queue = [word: begin_word, level: 1]
58 words.delete(begin_word)
59 until queue.empty?
60 top = queue.shift
61 return top[:level] if top[:word] == end_word
62
63 words.dup.each do |word|
64 if match?(top[:word], word)
65 queue.push(word: word, level: top[:level] + 1)
66 words.delete(word)
67 end
68 end
69 end
70 0
71 end
72
73 it do
74 words = ["hot", "dot", "dog", "lot", "log"]
75 expect(word_ladder(words, begin_word: "hit", end_word: "cog")).to eql(0)
76 end
77
78 it do
79 words = ["hot", "dot", "dog", "lot", "log", "cog"]
80 expect(word_ladder(words, begin_word: "hit", end_word: "cog")).to eql(5)
81 end
82
83 it do
84 expect(word_ladder(["a", "b", "c"], begin_word: "a", end_word: "c")).to eql(2)
85 end
86
87 it do
88 expect(word_ladder(["hot", "dog"], begin_word: "hot", end_word: "dog")).to eql(0)
89 end
90
91 it do
92 words = ["hot", "dog", "cog", "pot", "dot"]
93 expect(word_ladder(words, begin_word: "hot", end_word: "dog")).to eql(3)
94 end
95
96 it do
97 words = ["hot", "cog", "dot", "dog", "hit", "lot", "log"]
98 expect(word_ladder(words, begin_word: "hit", end_word: "cog")).to eql(5)
99 end
100
101 it do
102 words = ["most", "fist", "lost", "cost", "fish"]
103 expect(word_ladder(words, begin_word: "lost", end_word: "cost")).to eql(2)
104 end
105
106 it do
107 words = ["talk", "tons", "fall", "tail", "gale", "hall", "negs"]
108 expect(word_ladder(words, begin_word: "talk", end_word: "tail")).to eql(0)
109 end
110
111 it do
112 words = ["peale", "wilts", "place", "fetch", "purer", "pooch", "peace", "poach", "berra", "teach", "rheum", "peach"]
113 expect(word_ladder(words, begin_word: "teach", end_word: "place")).to eql(4)
114 end
115
116 it do
117 words = ['chai', 'chat', 'coat', 'cost', 'cast', 'case', 'came', 'tame']
118 expect(word_ladder(words, begin_word: "chai", end_word: "tame")).to eql(8)
119 end
120end