package com.interview.algorithms.string;
import com.interview.algorithms.general.C1_59_PrimeNumber;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
/**
* Created_By: stefanie
* Date: 14-9-17
* Time: 下午10:20
*
* Solution:
* Assumption: Every integer can be divided into a unique combination of primes numbers:
* int = p1 ^ n1 * p2 ^ n2 * ....
* So create a character to prime numbers map, and map each word into prime int.
* Than, if two words have same prime int, it should be brother words.
*/
public class C11_28_BrotherWords {
public static C11_28_BrotherWords INSTANCE = new C11_28_BrotherWords();
public final static String DICTIONARY = "./documents/dictionary";
public Map<Long, Set<String>> WORDMAP = new HashMap<Long, Set<String>>();
public int[] CHARMAP;
private C11_28_BrotherWords(){
CHARMAP = C1_59_PrimeNumber.generate(26);
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(DICTIONARY));
String line = null;
while( (line = reader.readLine()) != null) {
String word = line.trim().toLowerCase();
long score = getScore(word);
Set<String> words = WORDMAP.get(score);
if(words == null){
words = new HashSet<String>();
WORDMAP.put(score, words);
}
words.add(word);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader != null)
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private long getScore(String word){
long score = 1;
for(char ch : word.toCharArray()) score *= CHARMAP[ch - 'a'];
return score;
}
public Set<String> brotherWords(String word){
long score = getScore(word);
return WORDMAP.get(score);
}
}