Boggle using Trie
Given a dictionary, a method to do a lookup in the dictionary and a M x N board where every cell has one character. Find all possible words that can be formed by a sequence of adjacent characters. Note that we can move to any of 8 adjacent characters, but a word should not have multiple instances of the same cell.
Example:
Input: dictionary[] = {"GEEKS", "FOR", "QUIZ", "GO"}; boggle[][] = {{'G', 'I', 'Z'}, {'U', 'E', 'K'}, {'Q', 'S', 'E'}}; Output: Following words of the dictionary are present GEEKS QUIZ Explanation:
Input: dictionary[] = {"GEEKS", "ABCFIHGDE"}; boggle[][] = {{'A', 'B', 'C'}, {'D', 'E', 'F'}, {'G', 'H', 'I'}}; Output: Following words of the dictionary are present ABCFIHGDE Explanation:
We have discussed a Graph DFS based solution in below post.
Boggle (Find all possible words in a board of characters) | Set 1
Here we discuss a Trie based solution which is better than DFS based solution.
Given Dictionary dictionary[] = {“GEEKS”, “FOR”, “QUIZ”, “GO”}
1. Create an Empty trie and insert all words of given dictionary into trie
After insertion, Trie looks like(leaf nodes are in RED) root / G F Q / | | | O E O U | | | E R I | | K Z | S
2. After that we have pick only those character in boggle[][] which are child of root of Trie
Let for above we pick ‘G’ boggle[0][0], ‘Q’ boggle[2][0] (they both are present in boggle matrix)
3. search a word in a trie which start with character that we pick in step 2
1) Create bool visited boolean matrix (Visited[M][N] = false ) 2) Call SearchWord() for every cell (i, j) which has one of the first characters of dictionary words. In above example, we have 'G' and 'Q' as first characters. SearchWord(Trie *root, i, j, visited[][N]) if root->leaf == true print word if we have seen this element first time then make it visited. visited[i][j] = true do traverse all child of current root k goes (0 to 26 ) [there are only 26 Alphabet] add current char and search for next character find next character which is adjacent to boggle[i][j] they are 8 adjacent cells of boggle[i][j] (i+1, j+1), (i+1, j) (i-1, j) and so on. make it unvisited visited[i][j] = false
Below is the implementation of above idea:
C++
// C++ program for Boggle game #include <bits/stdc++.h> using namespace std; // Converts key current character into index // use only 'A' through 'Z' #define char_int(c) ((int)c - (int)'A') // Alphabet size #define SIZE (26) #define M 3 #define N 3 // trie Node struct TrieNode { TrieNode* Child[SIZE]; // isLeaf is true if the node represents // end of a word bool leaf; }; // Returns new trie node (initialized to NULLs) TrieNode* getNode() { TrieNode* newNode = new TrieNode; newNode->leaf = false ; for ( int i = 0; i < SIZE; i++) newNode->Child[i] = NULL; return newNode; } // If not present, inserts a key into the trie // If the key is a prefix of trie node, just // marks leaf node void insert(TrieNode* root, char * Key) { int n = strlen (Key); TrieNode* pChild = root; for ( int i = 0; i < n; i++) { int index = char_int(Key[i]); if (pChild->Child[index] == NULL) pChild->Child[index] = getNode(); pChild = pChild->Child[index]; } // make last node as leaf node pChild->leaf = true ; } // function to check that current location // (i and j) is in matrix range bool isSafe( int i, int j, bool visited[M][N]) { return (i >= 0 && i < M && j >= 0 && j < N && !visited[i][j]); } // A recursive function to print all words present on boggle void searchWord(TrieNode* root, char boggle[M][N], int i, int j, bool visited[][N], string str) { // if we found word in trie / dictionary if (root->leaf == true ) cout << str << endl; // If both I and j in range and we visited // that element of matrix first time if (isSafe(i, j, visited)) { // make it visited visited[i][j] = true ; // traverse all childs of current root for ( int K = 0; K < SIZE; K++) { if (root->Child[K] != NULL) { // current character char ch = ( char )K + ( char ) 'A' ; // Recursively search reaming character of word // in trie for all 8 adjacent cells of boggle[i][j] if (isSafe(i + 1, j + 1, visited) && boggle[i + 1][j + 1] == ch) searchWord(root->Child[K], boggle, i + 1, j + 1, visited, str + ch); if (isSafe(i, j + 1, visited) && boggle[i][j + 1] == ch) searchWord(root->Child[K], boggle, i, j + 1, visited, str + ch); if (isSafe(i - 1, j + 1, visited) && boggle[i - 1][j + 1] == ch) searchWord(root->Child[K], boggle, i - 1, j + 1, visited, str + ch); if (isSafe(i + 1, j, visited) && boggle[i + 1][j] == ch) searchWord(root->Child[K], boggle, i + 1, j, visited, str + ch); if (isSafe(i + 1, j - 1, visited) && boggle[i + 1][j - 1] == ch) searchWord(root->Child[K], boggle, i + 1, j - 1, visited, str + ch); if (isSafe(i, j - 1, visited) && boggle[i][j - 1] == ch) searchWord(root->Child[K], boggle, i, j - 1, visited, str + ch); if (isSafe(i - 1, j - 1, visited) && boggle[i - 1][j - 1] == ch) searchWord(root->Child[K], boggle, i - 1, j - 1, visited, str + ch); if (isSafe(i - 1, j, visited) && boggle[i - 1][j] == ch) searchWord(root->Child[K], boggle, i - 1, j, visited, str + ch); } } // make current element unvisited visited[i][j] = false ; } } // Prints all words present in dictionary. void findWords( char boggle[M][N], TrieNode* root) { // Mark all characters as not visited bool visited[M][N]; memset (visited, false , sizeof (visited)); TrieNode* pChild = root; string str = "" ; // traverse all matrix elements for ( int i = 0; i < M; i++) { for ( int j = 0; j < N; j++) { // we start searching for word in dictionary // if we found a character which is child // of Trie root if (pChild->Child[char_int(boggle[i][j])]) { str = str + boggle[i][j]; searchWord(pChild->Child[char_int(boggle[i][j])], boggle, i, j, visited, str); str = "" ; } } } } // Driver program to test above function int main() { // Let the given dictionary be following char * dictionary[] = { "GEEKS" , "FOR" , "QUIZ" , "GEE" }; // root Node of trie TrieNode* root = getNode(); // insert all words of dictionary into trie int n = sizeof (dictionary) / sizeof (dictionary[0]); for ( int i = 0; i < n; i++) insert(root, dictionary[i]); char boggle[M][N] = { { 'G' , 'I' , 'Z' }, { 'U' , 'E' , 'K' }, { 'Q' , 'S' , 'E' } }; findWords(boggle, root); return 0; } |
Java
// Java program for Boggle game public class Boggle { // Alphabet size static final int SIZE = 26 ; static final int M = 3 ; static final int N = 3 ; // trie Node static class TrieNode { TrieNode[] Child = new TrieNode[SIZE]; // isLeaf is true if the node represents // end of a word boolean leaf; // constructor public TrieNode() { leaf = false ; for ( int i = 0 ; i < SIZE; i++) Child[i] = null ; } } // If not present, inserts a key into the trie // If the key is a prefix of trie node, just // marks leaf node static void insert(TrieNode root, String Key) { int n = Key.length(); TrieNode pChild = root; for ( int i = 0 ; i < n; i++) { int index = Key.charAt(i) - 'A' ; if (pChild.Child[index] == null ) pChild.Child[index] = new TrieNode(); pChild = pChild.Child[index]; } // make last node as leaf node pChild.leaf = true ; } // function to check that current location // (i and j) is in matrix range static boolean isSafe( int i, int j, boolean visited[][]) { return (i >= 0 && i < M && j >= 0 && j < N && !visited[i][j]); } // A recursive function to print // all words present on boggle static void searchWord(TrieNode root, char boggle[][], int i, int j, boolean visited[][], String str) { // if we found word in trie / dictionary if (root.leaf == true ) System.out.println(str); // If both I and j in range and we visited // that element of matrix first time if (isSafe(i, j, visited)) { // make it visited visited[i][j] = true ; // traverse all child of current root for ( int K = 0 ; K < SIZE; K++) { if (root.Child[K] != null ) { // current character char ch = ( char )(K + 'A' ); // Recursively search reaming character of word // in trie for all 8 adjacent cells of // boggle[i][j] if (isSafe(i + 1 , j + 1 , visited) && boggle[i + 1 ][j + 1 ] == ch) searchWord(root.Child[K], boggle, i + 1 , j + 1 , visited, str + ch); if (isSafe(i, j + 1 , visited) && boggle[i][j + 1 ] == ch) searchWord(root.Child[K], boggle, i, j + 1 , visited, str + ch); if (isSafe(i - 1 , j + 1 , visited) && boggle[i - 1 ][j + 1 ] == ch) searchWord(root.Child[K], boggle, i - 1 , j + 1 , visited, str + ch); if (isSafe(i + 1 , j, visited) && boggle[i + 1 ][j] == ch) searchWord(root.Child[K], boggle, i + 1 , j, visited, str + ch); if (isSafe(i + 1 , j - 1 , visited) && boggle[i + 1 ][j - 1 ] == ch) searchWord(root.Child[K], boggle, i + 1 , j - 1 , visited, str + ch); if (isSafe(i, j - 1 , visited) && boggle[i][j - 1 ] == ch) searchWord(root.Child[K], boggle, i, j - 1 , visited, str + ch); if (isSafe(i - 1 , j - 1 , visited) && boggle[i - 1 ][j - 1 ] == ch) searchWord(root.Child[K], boggle, i - 1 , j - 1 , visited, str + ch); if (isSafe(i - 1 , j, visited) && boggle[i - 1 ][j] == ch) searchWord(root.Child[K], boggle, i - 1 , j, visited, str + ch); } } // make current element unvisited visited[i][j] = false ; } } // Prints all words present in dictionary. static void findWords( char boggle[][], TrieNode root) { // Mark all characters as not visited boolean [][] visited = new boolean [M][N]; TrieNode pChild = root; String str = "" ; // traverse all matrix elements for ( int i = 0 ; i < M; i++) { for ( int j = 0 ; j < N; j++) { // we start searching for word in dictionary // if we found a character which is child // of Trie root if (pChild.Child[(boggle[i][j]) - 'A' ] != null ) { str = str + boggle[i][j]; searchWord(pChild.Child[(boggle[i][j]) - 'A' ], boggle, i, j, visited, str); str = "" ; } } } } // Driver program to test above function public static void main(String args[]) { // Let the given dictionary be following String dictionary[] = { "GEEKS" , "FOR" , "QUIZ" , "GEE" }; // root Node of trie TrieNode root = new TrieNode(); // insert all words of dictionary into trie int n = dictionary.length; for ( int i = 0 ; i < n; i++) insert(root, dictionary[i]); char boggle[][] = { { 'G' , 'I' , 'Z' }, { 'U' , 'E' , 'K' }, { 'Q' , 'S' , 'E' } }; findWords(boggle, root); } } // This code is contributed by Sumit Ghosh |
Python3
# Python program for Boggle game class TrieNode: # Trie node class def __init__( self ): self .children = [ None ] * 26 # isEndOfWord is True if node represent the end of the word self .isEndOfWord = False M = 3 N = 3 class Boogle: # Trie data structure class def __init__( self ): self .root = self .getNode() def getNode( self ): # Returns new trie node (initialized to NULLs) return TrieNode() def _charToIndex( self , ch): # private helper function # Converts key current character into index # use only 'A' through 'Z' and upper case return ord (ch) - ord ( 'A' ) def insert( self , key): # If not present, inserts key into trie # If the key is prefix of trie node, # just marks leaf node pCrawl = self .root length = len (key) for level in range (length): index = self ._charToIndex(key[level]) # if current character is not present if not pCrawl.children[index]: pCrawl.children[index] = self .getNode() pCrawl = pCrawl.children[index] # print('h', self.root.children) # mark last node as leaf pCrawl.isEndOfWord = True def is_Safe(i, j, vis): return 0 < = i < M and 0 < = j < N and not vis[i][j] def search_word(root, boggle, i, j, vis, string): if root.isEndOfWord: print (string) if is_Safe(i, j, vis): vis[i][j] = True for K in range ( 26 ): if root.children[K] is not None : ch = chr (K + ord ( 'A' )) # Recursively search reaming character of word # in trie for all 8 adjacent cells of boggle[i][j] if is_Safe(i + 1 , j + 1 , vis) and boggle[i + 1 ][j + 1 ] = = ch: search_word(root.children[K], boggle, i + 1 , j + 1 , vis, string + ch) if is_Safe(i, j + 1 , vis) and boggle[i][j + 1 ] = = ch: search_word(root.children[K], boggle, i, j + 1 , vis, string + ch) if is_Safe(i - 1 , j + 1 , vis) and boggle[i - 1 ][j + 1 ] = = ch: search_word(root.children[K], boggle, i - 1 , j + 1 , vis, string + ch) if is_Safe(i + 1 , j, vis) and boggle[i + 1 ][j] = = ch: search_word(root.children[K], boggle, i + 1 , j, vis, string + ch) if is_Safe(i + 1 , j - 1 , vis) and boggle[i + 1 ][j - 1 ] = = ch: search_word(root.children[K], boggle, i + 1 , j - 1 , vis, string + ch) if is_Safe(i, j - 1 , vis) and boggle[i][j - 1 ] = = ch: search_word(root.children[K], boggle, i, j - 1 , vis, string + ch) if is_Safe(i - 1 , j - 1 , vis) and boggle[i - 1 ][j - 1 ] = = ch: search_word(root.children[K], boggle, i - 1 , j - 1 , vis, string + ch) if is_Safe(i - 1 , j, vis) and boggle[i - 1 ][j] = = ch: search_word(root.children[K], boggle, i - 1 , j, vis, string + ch) vis[i][j] = False def char_int(ch): # private helper function # Converts key current character into index # use only 'A' through 'Z' and upper case return ord (ch) - ord ( 'A' ) def findWords(boggle, root): # Mark all characters as not visited visited = [[ False for i in range (N)] for i in range (M)] pChild = root string = "" # traverse all matrix elements for i in range (M): for j in range (N): # we start searching for word in dictionary # if we found a character which is child # of Trie root if pChild.children[char_int(boggle[i][j])]: # print('h') string = string + boggle[i][j] search_word(pChild.children[char_int(boggle[i][j])], boggle, i, j, visited, string) string = "" dictionary = [ "GEEKS" , "FOR" , "QUIZ" , "GEE" ] # root Node of trie t = Boogle() # insert all words of dictionary into trie n = len (dictionary) for i in range (n): t.insert(dictionary[i]) root = t.root boggle = [[ 'G' , 'I' , 'Z' ], [ 'U' , 'E' , 'K' ], [ 'Q' , 'S' , 'E' ]] # print(root.children) findWords(boggle, root) # This code is contributed by Yashwant Kumar |
C#
// C# program for Boggle game using System; public class Boggle { // Alphabet size static readonly int SIZE = 26; static readonly int M = 3; static readonly int N = 3; // trie Node public class TrieNode { public TrieNode[] Child = new TrieNode[SIZE]; // isLeaf is true if the node represents // end of a word public bool leaf; // constructor public TrieNode() { leaf = false ; for ( int i = 0; i < SIZE; i++) Child[i] = null ; } } // If not present, inserts a key into the trie // If the key is a prefix of trie node, just // marks leaf node static void insert(TrieNode root, String Key) { int n = Key.Length; TrieNode pChild = root; for ( int i = 0; i < n; i++) { int index = Key[i] - 'A' ; if (pChild.Child[index] == null ) pChild.Child[index] = new TrieNode(); pChild = pChild.Child[index]; } // make last node as leaf node pChild.leaf = true ; } // function to check that current location // (i and j) is in matrix range static bool isSafe( int i, int j, bool [, ] visited) { return (i >= 0 && i < M && j >= 0 && j < N && !visited[i, j]); } // A recursive function to print all words present on boggle static void searchWord(TrieNode root, char [, ] boggle, int i, int j, bool [, ] visited, String str) { // if we found word in trie / dictionary if (root.leaf == true ) Console.WriteLine(str); // If both I and j in range and we visited // that element of matrix first time if (isSafe(i, j, visited)) { // make it visited visited[i, j] = true ; // traverse all child of current root for ( int K = 0; K < SIZE; K++) { if (root.Child[K] != null ) { // current character char ch = ( char )(K + 'A' ); // Recursively search reaming character of word // in trie for all 8 adjacent cells of // boggle[i, j] if (isSafe(i + 1, j + 1, visited) && boggle[i + 1, j + 1] == ch) searchWord(root.Child[K], boggle, i + 1, j + 1, visited, str + ch); if (isSafe(i, j + 1, visited) && boggle[i, j + 1] == ch) searchWord(root.Child[K], boggle, i, j + 1, visited, str + ch); if (isSafe(i - 1, j + 1, visited) && boggle[i - 1, j + 1] == ch) searchWord(root.Child[K], boggle, i - 1, j + 1, visited, str + ch); if (isSafe(i + 1, j, visited) && boggle[i + 1, j] == ch) searchWord(root.Child[K], boggle, i + 1, j, visited, str + ch); if (isSafe(i + 1, j - 1, visited) && boggle[i + 1, j - 1] == ch) searchWord(root.Child[K], boggle, i + 1, j - 1, visited, str + ch); if (isSafe(i, j - 1, visited) && boggle[i, j - 1] == ch) searchWord(root.Child[K], boggle, i, j - 1, visited, str + ch); if (isSafe(i - 1, j - 1, visited) && boggle[i - 1, j - 1] == ch) searchWord(root.Child[K], boggle, i - 1, j - 1, visited, str + ch); if (isSafe(i - 1, j, visited) && boggle[i - 1, j] == ch) searchWord(root.Child[K], boggle, i - 1, j, visited, str + ch); } } // make current element unvisited visited[i, j] = false ; } } // Prints all words present in dictionary. static void findWords( char [, ] boggle, TrieNode root) { // Mark all characters as not visited bool [, ] visited = new bool [M, N]; TrieNode pChild = root; String str = "" ; // traverse all matrix elements for ( int i = 0; i < M; i++) { for ( int j = 0; j < N; j++) { // we start searching for word in dictionary // if we found a character which is child // of Trie root if (pChild.Child[(boggle[i, j]) - 'A' ] != null ) { str = str + boggle[i, j]; searchWord(pChild.Child[(boggle[i, j]) - 'A' ], boggle, i, j, visited, str); str = "" ; } } } } // Driver program to test above function public static void Main(String[] args) { // Let the given dictionary be following String[] dictionary = { "GEEKS" , "FOR" , "QUIZ" , "GEE" }; // root Node of trie TrieNode root = new TrieNode(); // insert all words of dictionary into trie int n = dictionary.Length; for ( int i = 0; i < n; i++) insert(root, dictionary[i]); char [, ] boggle = { { 'G' , 'I' , 'Z' }, { 'U' , 'E' , 'K' }, { 'Q' , 'S' , 'E' } }; findWords(boggle, root); } } // This code has been contributed by 29AjayKumar |
Javascript
<script> // Javascript program for Boggle game // Alphabet size let SIZE = 26; let M = 3; let N = 3; // trie Node class TrieNode { constructor() { this .leaf= false ; this .Child = new Array(SIZE); for (let i = 0; i < SIZE; i++) this .Child[i]= null ; } } // If not present, inserts a key into the trie // If the key is a prefix of trie node, just // marks leaf node function insert(root,Key) { let n = Key.length; let pChild = root; for (let i = 0; i < n; i++) { let index = Key[i].charCodeAt(0) - 'A' .charCodeAt(0); if (pChild.Child[index] == null ) pChild.Child[index] = new TrieNode(); pChild = pChild.Child[index]; } // make last node as leaf node pChild.leaf = true ; } // function to check that current location // (i and j) is in matrix range function isSafe(i,j,visited) { return (i >= 0 && i < M && j >= 0 && j < N && !visited[i][j]); } // A recursive function to print // all words present on boggle function searchWord(root,boggle,i,j,visited,str) { // if we found word in trie / dictionary if (root.leaf == true ) document.write(str+ " <br>" ); // If both I and j in range and we visited // that element of matrix first time if (isSafe(i, j, visited)) { // make it visited visited[i][j] = true ; // traverse all child of current root for (let K = 0; K < SIZE; K++) { if (root.Child[K] != null ) { // current character let ch = String.fromCharCode(K + 'A' .charCodeAt(0)); // Recursively search reaming character of word // in trie for all 8 adjacent cells of // boggle[i][j] if (isSafe(i + 1, j + 1, visited) && boggle[i + 1][j + 1] == ch) searchWord(root.Child[K], boggle, i + 1, j + 1, visited, str + ch); if (isSafe(i, j + 1, visited) && boggle[i][j + 1] == ch) searchWord(root.Child[K], boggle, i, j + 1, visited, str + ch); if (isSafe(i - 1, j + 1, visited) && boggle[i - 1][j + 1] == ch) searchWord(root.Child[K], boggle, i - 1, j + 1, visited, str + ch); if (isSafe(i + 1, j, visited) && boggle[i + 1][j] == ch) searchWord(root.Child[K], boggle, i + 1, j, visited, str + ch); if (isSafe(i + 1, j - 1, visited) && boggle[i + 1][j - 1] == ch) searchWord(root.Child[K], boggle, i + 1, j - 1, visited, str + ch); if (isSafe(i, j - 1, visited) && boggle[i][j - 1] == ch) searchWord(root.Child[K], boggle, i, j - 1, visited, str + ch); if (isSafe(i - 1, j - 1, visited) && boggle[i - 1][j - 1] == ch) searchWord(root.Child[K], boggle, i - 1, j - 1, visited, str + ch); if (isSafe(i - 1, j, visited) && boggle[i - 1][j] == ch) searchWord(root.Child[K], boggle, i - 1, j, visited, str + ch); } } // make current element unvisited visited[i][j] = false ; } } // Prints all words present in dictionary. function findWords(boggle,root) { // Mark all characters as not visited let visited = new Array(M); for (let i=0;i<M;i++) { visited[i]= new Array(N); for (let j=0;j<N;j++) { visited[i][j]= false ; } } let pChild = root; let str = "" ; // traverse all matrix elements for (let i = 0; i < M; i++) { for (let j = 0; j < N; j++) { // we start searching for word in dictionary // if we found a character which is child // of Trie root if (pChild.Child[(boggle[i][j]).charCodeAt(0) - 'A' .charCodeAt(0)] != null ) { str = str + boggle[i][j]; searchWord(pChild.Child[(boggle[i][j]).charCodeAt(0) - 'A' .charCodeAt(0)], boggle, i, j, visited, str); str = "" ; } } } } // Driver program to test above function let dictionary=[ "GEEKS" , "FOR" , "QUIZ" , "GEE" ]; // root Node of trie let root = new TrieNode(); // insert all words of dictionary into trie let n = dictionary.length; for (let i = 0; i < n; i++) insert(root, dictionary[i]); let boggle = [[ 'G' , 'I' , 'Z' ], [ 'U' , 'E' , 'K' ], [ 'Q' , 'S' , 'E' ]]; findWords(boggle, root); // This code is contributed by rag2127 </script> |
GEE GEEKS QUIZ
Complexity Analysis:
- Time complexity: O(4^(N^2)).
Even after applying trie the time complexity remains same. For every cell there are 4 directions and there are N^2 cells. So the time complexity is O(4^(N^2)). - Auxiliary Space: O(N^2).
The maximum length of recursion can be N^2, where N is the side of the matrix. So the space Complexity is O(N^2).
OPTIMIZED APPROACH WITHOUT USING TRIE ( Short and Easy to understand with a better Time and Space complexity):
- First, we create a Set Data Structure and add all word in it to avoid duplicate word.
- Then we make a new array of type String and add those set elements to it.
- We check word by word using a for loop whether that particular word is present in the board and if it returns true , we shall add it our ArrayList<String>.
- While searching for a word in the board,we shall use backtracking so that while coming back,we can alter the board as it was before.
- Lastly we sort the array and print it.
C++
// C++ program for word Boggle #include <bits/stdc++.h> using namespace std; bool exist( char board[][3], string word, int r, int c); bool search( char board[][3], string word, int len, int i, int j, int r, int c); vector<string> wordBoggle( char board[][3], vector<string> dictionary) { int r = 3; int c = 3; vector<string> temp; set<string> st(dictionary.begin(), dictionary.end()); int n = st.size(); string dict[n]; int id = 0; for (string s : st) dict[id++] = s; for ( int i = 0; i < n; i++) { if (exist(board, dict[i], r, c)) temp.push_back(dict[i]); } return temp; } bool exist( char board[][3], string word, int r, int c) { for ( int i = 0; i < r; i++) { for ( int j = 0; j < c; j++) { if (board[i][j] == word[0] && search(board, word, 0, i, j, r, c)) return true ; } } return false ; } bool search( char board[][3], string word, int len, int i, int j, int r, int c) { if (i < 0 || i >= r || j < 0 || j >= c) return false ; if (board[i][j] != word[len]) return false ; if (len == word.length() - 1) return true ; char ch = board[i][j]; board[i][j] = '@' ; bool ans = search(board, word, len + 1, i - 1, j, r, c) || search(board, word, len + 1, i + 1, j, r, c) || search(board, word, len + 1, i, j - 1, r, c) || search(board, word, len + 1, i, j + 1, r, c) || search(board, word, len + 1, i - 1, j + 1, r, c) || search(board, word, len + 1, i - 1, j - 1, r, c) || search(board, word, len + 1, i + 1, j - 1, r, c) || search(board, word, len + 1, i + 1, j + 1, r, c); board[i][j] = ch; return ans; } int main() { vector<string> dictionary = { "GEEKS" , "FOR" , "QUIZ" , "GEE" }; char boggle[][3] = { { 'G' , 'I' , 'Z' }, { 'U' , 'E' , 'K' }, { 'Q' , 'S' , 'E' } }; vector<string> ans = wordBoggle(boggle, dictionary); if (ans.size() == 0) cout << "-1" << endl; else { sort(ans.begin(), ans.end()); for ( int i = 0; i < ans.size(); i++) { cout << ans[i] << " " ; } cout << endl; } return 0; } // Contributed by adityasha4x71 |
Java
// Java program for word Boggle import java.io.*; import java.util.*; public class Boggle { public static String[] wordBoggle( char board[][], String[] dictionary) { int r = board.length; int c = board[ 0 ].length; ArrayList<String> temp = new ArrayList<>(); Set<String> set = new HashSet<>(); for (String i : dictionary) set.add(i); int n = set.size(); String dict[] = new String[n]; int id = 0 ; for (String s : set) dict[id++] = s; for ( int i = 0 ; i < dict.length; i++) { if (exist(board, dict[i], r, c)) temp.add(dict[i]); } String[] ans = new String[temp.size()]; int idx = 0 ; for (String i : temp) ans[idx++] = i; return ans; } public static boolean exist( char board[][], String word, int r, int c) { for ( int i = 0 ; i < r; i++) { for ( int j = 0 ; j < c; j++) { if (board[i][j] == word.charAt( 0 ) && search(board, word, 0 , i, j, r, c)) return true ; } } return false ; } public static boolean search( char board[][], String word, int len, int i, int j, int r, int c) { if (i < 0 || i >= r || j < 0 || j >= c) return false ; if (board[i][j] != word.charAt(len)) return false ; if (len == word.length() - 1 ) return true ; char ch = board[i][j]; board[i][j] = '@' ; boolean ans = search(board, word, len + 1 , i - 1 , j, r, c) || search(board, word, len + 1 , i + 1 , j, r, c) || search(board, word, len + 1 , i, j - 1 , r, c) || search(board, word, len + 1 , i, j + 1 , r, c) || search(board, word, len + 1 , i - 1 , j + 1 , r, c) || search(board, word, len + 1 , i - 1 , j - 1 , r, c) || search(board, word, len + 1 , i + 1 , j - 1 , r, c) || search(board, word, len + 1 , i + 1 , j + 1 , r, c); board[i][j] = ch; return ans; } public static void main(String[] args) { String dictionary[] = { "GEEKS" , "FOR" , "QUIZ" , "GEE" }; char boggle[][] = { { 'G' , 'I' , 'Z' }, { 'U' , 'E' , 'K' }, { 'Q' , 'S' , 'E' } }; String ans[] = wordBoggle(boggle, dictionary); if (ans.length == 0 ) System.out.println( "-1" ); else { Arrays.sort(ans); for ( int i = 0 ; i < ans.length; i++) { System.out.print(ans[i] + " " ); } System.out.println(); } } } // This code is contributed by Raunak Singh |
Python3
# Python code addition def exist(board, word, r, c): for i in range (r): for j in range (c): if board[i][j] = = word[ 0 ] and search(board, word, 0 , i, j, r, c): return True return False def search(board, word, length, i, j, r, c): if i < 0 or i > = r or j < 0 or j > = c: return False if board[i][j] ! = word[length]: return False if length = = len (word) - 1 : return True ch = board[i][j] board[i][j] = '@' ans = search(board, word, length + 1 , i - 1 , j, r, c) or \ search(board, word, length + 1 , i + 1 , j, r, c) or \ search(board, word, length + 1 , i, j - 1 , r, c) or \ search(board, word, length + 1 , i, j + 1 , r, c) or \ search(board, word, length + 1 , i - 1 , j + 1 , r, c) or \ search(board, word, length + 1 , i - 1 , j - 1 , r, c) or \ search(board, word, length + 1 , i + 1 , j - 1 , r, c) or \ search(board, word, length + 1 , i + 1 , j + 1 , r, c) board[i][j] = ch return ans def word_boggle(board, dictionary): r, c = 3 , 3 temp = [] st = set (dictionary) n = len (st) dict = [] for s in st: dict .append(s) for i in range (n): if exist(board, dict [i], r, c): temp.append( dict [i]) return temp if __name__ = = '__main__' : dictionary = [ "GEEKS" , "FOR" , "QUIZ" , "GEE" ] boggle = [[ 'G' , 'I' , 'Z' ], [ 'U' , 'E' , 'K' ], [ 'Q' , 'S' , 'E' ]] ans = word_boggle(boggle, dictionary) if len (ans) = = 0 : print ( "-1" ) else : ans.sort() print ( " " .join(ans)) # The code is contributed by Nidhi goel. |
C#
using System; using System.Collections.Generic; using System.Linq; public class Boggle { public static string [] WordBoggle( char [,] board, string [] dictionary) { int r = board.GetLength(0); int c = board.GetLength(1); var temp = new List< string >(); var set = new HashSet< string >(dictionary); int n = set .Count; string [] dict = set .ToArray(); for ( int i = 0; i < dict.Length; i++) { if (Exist(board, dict[i], r, c)) { temp.Add(dict[i]); } } string [] ans = temp.ToArray(); return ans; } public static bool Exist( char [,] board, string word, int r, int c) { for ( int i = 0; i < r; i++) { for ( int j = 0; j < c; j++) { if (board[i, j] == word[0] && Search(board, word, 0, i, j, r, c)) { return true ; } } } return false ; } public static bool Search( char [,] board, string word, int len, int i, int j, int r, int c) { if (i < 0 || i >= r || j < 0 || j >= c) { return false ; } if (board[i, j] != word[len]) { return false ; } if (len == word.Length - 1) { return true ; } char ch = board[i, j]; board[i, j] = '@' ; bool ans = Search(board, word, len + 1, i - 1, j, r, c) || Search(board, word, len + 1, i + 1, j, r, c) || Search(board, word, len + 1, i, j - 1, r, c) || Search(board, word, len + 1, i, j + 1, r, c) || Search(board, word, len + 1, i - 1, j + 1, r, c) || Search(board, word, len + 1, i - 1, j - 1, r, c) || Search(board, word, len + 1, i + 1, j - 1, r, c) || Search(board, word, len + 1, i + 1, j + 1, r, c); board[i, j] = ch; return ans; } public static void Main( string [] args) { string [] dictionary = { "GEEKS" , "FOR" , "QUIZ" , "GEE" }; char [,] boggle = { { 'G' , 'I' , 'Z' }, { 'U' , 'E' , 'K' }, { 'Q' , 'S' , 'E' } }; string [] ans = WordBoggle(boggle, dictionary); if (ans.Length == 0) { Console.WriteLine( "-1" ); } else { Array.Sort(ans); foreach ( string word in ans) { Console.Write(word + " " ); } Console.WriteLine(); } } } |
Javascript
// JavaScript program for word Boggle function exist(board, word, r, c) { for (let i = 0; i < r; i++) { for (let j = 0; j < c; j++) { if (board[i][j] === word[0] && search(board, word, 0, i, j, r, c)) { return true ; } } } return false ; } function search(board, word, len, i, j, r, c) { if (i < 0 || i >= r || j < 0 || j >= c) { return false ; } if (board[i][j] !== word[len]) { return false ; } if (len === word.length - 1) { return true ; } const ch = board[i][j]; board[i][j] = '@' ; const ans = search(board, word, len + 1, i - 1, j, r, c) || search(board, word, len + 1, i + 1, j, r, c) || search(board, word, len + 1, i, j - 1, r, c) || search(board, word, len + 1, i, j + 1, r, c) || search(board, word, len + 1, i - 1, j + 1, r, c) || search(board, word, len + 1, i - 1, j - 1, r, c) || search(board, word, len + 1, i + 1, j - 1, r, c) || search(board, word, len + 1, i + 1, j + 1, r, c); board[i][j] = ch; return ans; } function wordBoggle(board, dictionary) { const r = 3; const c = 3; const temp = []; const st = new Set(dictionary); const n = st.size; const dict = Array.from(st); for (let i = 0; i < n; i++) { if (exist(board, dict[i], r, c)) { temp.push(dict[i]); } } return temp; } const dictionary = [ "GEEKS" , "FOR" , "QUIZ" , "GEE" ]; const boggle = [ [ "G" , "I" , "Z" ], [ "U" , "E" , "K" ], [ "Q" , "S" , "E" ], ]; const ans = wordBoggle(boggle, dictionary); if (ans.length === 0) { console.log( "-1" ); } else { ans.sort(); for (let i = 0; i < ans.length; i++) { console.log(ans[i] + " " ); } console.log( "" ); } // This code is contributed by user_dtewbxkn77n |
GEE GEEKS QUIZ
Time Complexity: O(N*W + R*C^2)
Space Complexity: O(N*W + R*C)
This article is contributed by Nishant Singh . If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Please Login to comment...