Created
June 15, 2015 08:05
-
-
Save gabhi/663fbe9caf3ed052a52b to your computer and use it in GitHub Desktop.
boggle solver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.interview.algorithms.tree; | |
import java.io.BufferedReader; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.TreeSet; | |
import com.interview.basics.model.trie.Trie; | |
import com.interview.basics.model.trie.TrieNode; | |
import com.interview.utils.Timer; | |
/** | |
* Problem Description: | |
* http://stackoverflow.com/questions/746082/how-to-find-list-of-possible-words-from-a-letter-matrix-boggle-solver | |
* | |
* | |
* @author zouzhile | |
* | |
*/ | |
public class BoggleSolver { | |
class State { | |
public final int row, column; // row and column index | |
public final String prefix; // the next prefix equals to (prefix + data[i][j]) | |
public State(int row, int column, String prefix){ | |
this.row = row; this.column = column; this.prefix = prefix; | |
} | |
} | |
private Trie trie; | |
public BoggleSolver(String dictionary) { | |
this.trie = new Trie(); | |
this.buildTrie(dictionary); | |
} | |
public Set<String> findWords(char[][] data){ | |
Set<String> words = new HashSet<String>(); | |
for(int i = 0; i < data.length; i ++) | |
for(int j = 0; j < data[i].length; j ++) | |
words.addAll(this.findWords(data, i, j)); | |
return words; | |
} | |
private Set<String> findWords(char[][] data, int i, int j){ | |
Set<String> words = new HashSet<String>(); | |
List<State> queue = new ArrayList<State>(); | |
if(this.isInsideBound(data, i, j)) | |
queue.add(new State(i, j, "")); | |
while(queue.size() > 0) { | |
State state = queue.remove(0); | |
String prefix = state.prefix + data[state.row][state.column]; | |
TrieNode matchNode = this.trie.match(prefix); | |
if(matchNode != null) { | |
List<State> states = this.getStatesByAdjacentChars(data, state.row, state.column, prefix); | |
queue.addAll(states); | |
if(matchNode.isWord() && prefix.length() >= 3) { | |
words.add(prefix); | |
} | |
} | |
} | |
return words; | |
} | |
private List<State> getStatesByAdjacentChars(char[][] data, int currentRow, int currentColumn, String prefix){ | |
List<State> states = new ArrayList<State>(); | |
for(int rowDelta = -1; rowDelta <= 1; rowDelta ++) | |
for(int columnDelta = -1; columnDelta <= 1; columnDelta ++) { | |
int newRow = currentRow + rowDelta; | |
int newColumn = currentColumn + columnDelta; | |
if(this.isInsideBound(data, newRow, newColumn)) | |
states.add(new State(newRow, newColumn, prefix)); | |
} | |
return states; | |
} | |
private boolean isInsideBound(char[][] data, int i, int j){ | |
boolean inbound = (i >= 0 && i < data.length) && (j >= 0 && j < data[i].length); | |
return inbound; | |
} | |
private void buildTrie(String dictionary){ | |
BufferedReader reader = null; | |
try { | |
reader = new BufferedReader(new FileReader(dictionary)); | |
String line = null; | |
while( (line = reader.readLine()) != null) { | |
String word = line.trim().toLowerCase(); | |
this.trie.addWord(word); | |
} | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} finally { | |
if(reader != null) | |
try { | |
reader.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
/** | |
* @param args | |
*/ | |
public static void main(String[] args) { | |
String array = "djhi,klps,yeut,eorn"; | |
//String array = "fxie,amlo,ewbx,astu"; | |
String[] rows = array.split(","); | |
int rowsCount = rows.length; | |
int columnCount = rows[0].length(); | |
char[][] data = new char[rowsCount][columnCount]; | |
for(int i = 0; i < rowsCount; i ++) | |
for(int j = 0; j < columnCount; j ++) | |
data[i][j] = rows[i].charAt(j); | |
Timer timer = new Timer(); | |
timer.start(); | |
BoggleSolver solver = new BoggleSolver("./documents/dictionary"); | |
timer.stop(); | |
System.out.println("Trie build took " + timer); | |
timer.start(); | |
Set<String> words = solver.findWords(data); | |
timer.stop(); | |
System.out.println("Word binarysearch took " + timer); | |
TreeSet<String> sortedWords = new TreeSet<String>(); | |
sortedWords.addAll(words); | |
int count = 0; | |
System.out.println(); | |
for(String word : sortedWords) { | |
System.out.print(word + " "); | |
count ++; | |
if(count % 10 == 0) | |
System.out.println(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment