// time: 8^(rows*cols) // as 8 calls for each direction, for each of rows*cols squares bool boggle(m, word): if m == null || word == null: throw cols = m.length() rows = m[0].length() for c = 0, c < cols, col++: for r = 0, r < rows, r++: if boggle(m, c, cols, r, rows, word): return true return false bool boggle(m, c, cols, r, rows, word, i = 0, visited = new): // needs to be before the out-of-bounds checks if i == word.length(): return true if !(0 <= c < cols) || !(0 <= r < rows): return false if visited[i][j]: return false if m[i][j] != word[i]: return false visited[i][j] = true if boggle(m, c , cols, r+1, rows, word, i+1, visited) || boggle(m, c , cols, r-1, rows, word, i+1, visited) || boggle(m, c+1, cols, r , rows, word, i+1, visited) || boggle(m, c-1, cols, r , rows, word, i+1, visited) || boggle(m, c-1, cols, r+1, rows, word, i+1, visited) || boggle(m, c+1, cols, r+1, rows, word, i+1, visited) || boggle(m, c-1, cols, r-1, rows, word, i+1, visited) || boggle(m, c+1, cols, r-1, rows, word, i+1, visited): return true visited[i][j] = false return false[Hat tip to SM]
Optimization: Precompute all words using a dictionary.
boggle: trie trie set words ctor(m, trie): if m == null || trie == null: throw trie = trie words = bogglePrecompute(m, trie) result hasWord(word): if word == null: throw if !trie.hasWord(word): return result.wordNotInDictionary if !words.has(word): return result.wordNotInBoggle return result.Ok set[Hat tip to ML]bogglePrecompute(m, trie): set words = new for c = 0, c < cols, col++: for r = 0, r < rows, r++: bogglePrecompute(m, c, cols, r, rows, trie.root, words) return words bogglePrecompute(m, c, cols, r, rows, trieNode, words, visited = new, buffer = new): if !(0 <= r < rows) || !(0 <= c < cols): return if visited[c][r]: return ch = m[c][r] // word prefix not in dictionary if !trieNode.hasChild(ch): return visited[c][r] = true buffer.append(ch) trieNode = trieNode.getChild(ch) if trieNode.isWord(): words.add(buffer.toString()) boggle(m, c , cols, r+1, rows, trieNode, words, visited, buffer) boggle(m, c , cols, r-1, rows, trieNode, words, visited, buffer) boggle(m, c+1, cols, r , rows, trieNode, words, visited, buffer) boggle(m, c-1, cols, r , rows, trieNode, words, visited, buffer) boggle(m, c-1, cols, r+1, rows, trieNode, words, visited, buffer) boggle(m, c+1, cols, r+1, rows, trieNode, words, visited, buffer) boggle(m, c-1, cols, r-1, rows, trieNode, words, visited, buffer) boggle(m, c+1, cols, r-1, rows, trieNode, words, visited, buffer) visited[i][j] = false buffer.removeLast() // interfaces for trie itrie: trieNode root itrieNode: itrieNode getChild(ch): bool hasChild(ch): bool isWord():
No comments:
Post a Comment