Skip to content

Instantly share code, notes, and snippets.

@YanivHaramati
Last active July 20, 2016 20:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YanivHaramati/177030fbefa0d0d2879f to your computer and use it in GitHub Desktop.
Save YanivHaramati/177030fbefa0d0d2879f to your computer and use it in GitHub Desktop.
var EnglishDictionary = function (words) {
var self = {};
var letterHash = initLeterHash();
// this is efficient enough to get 1mil primes fast.
function getPrimes(num) {
var primes = [2, 3];
for (var n = 5; primes.length < num; n += 2) {
var sqrt = Math.sqrt(n);
var isPrime = true;
for (var pi = 0; primes[pi] <= sqrt; pi++) {
if (n % primes[pi] == 0) {
isPrime = false;
break;
}
}
if (isPrime) primes.push(n);
}
return primes;
}
function getEnglishLetters() {
var a = "a".charCodeAt(0);
return Array.apply(null, Array(26)).map(
function(_, i) {
return String.fromCharCode(a+i);
});
}
function initLeterHash() {
var primes = getPrimes(26);
var letters = getEnglishLetters();
return letters.reduce(function(hashMap, letter, i) {
hashMap[letter] = primes[i];
return hashMap;
}, {});
}
function getHash(str) {
var total = 1;
str.split("").forEach(function (c) {
total *= letterHash[c];
});
return total;
}
self.dict = {};
self.addWord = function (str) {
var key = getHash(str);
var bucket = self.dict[key] || [];
bucket.push(str);
self.dict[key] = bucket;
};
self.init = function () {
if (words) {
words.map(function (word) {
self.addWord(word);
});
}
};
self.getAnagrams = function (str) {
var bucket = self.dict[getHash(str)];
if (!bucket) return "";
var wordIndex = bucket.indexOf(str);
var ret = bucket.slice(0, wordIndex).concat(bucket.slice(wordIndex + 1));
return ret.join(", ");
};
self.init();
return self;
};
var dict = new EnglishDictionary(["cat", "something", "act", "dog", "god"]);
console.log(dict.getAnagrams("cat"));
console.log(dict.getAnagrams("god"));
@YanivHaramati
Copy link
Author

As a clever way to get anagrams for a word from a given dictionary:
hashing the alphabet to prime numbers we can hash any word into a product of primes as the product of its letters.
I.e. any unique letter combo (unique word) will have a unique number composed of a unique set of prime factors (letter hashes).
If our simplified anagram dictionary sorts words into their hash buckets, any hash match will return the same bucket containing all other words with identical hash (anagrams), allowing for a constant time lookup for anagrams based on the prime product hash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment