// 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 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():
[Hat tip to ML]
No comments:
Post a Comment