Skip to content

Instantly share code, notes, and snippets.

@rrichardsonv
Created May 2, 2018 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rrichardsonv/ba7657adbb9096ab23b982b7c85bc67e to your computer and use it in GitHub Desktop.
Save rrichardsonv/ba7657adbb9096ab23b982b7c85bc67e to your computer and use it in GitHub Desktop.
Tries solution
class Node {
constructor(){
this.trie = {};
}
static traverseChildren(word, node){
if(!Object.keys(node).length){
return word;
}
return Object.keys(node)
.reduce((ac, k) => ac.concat(Node.traverseChildren(word+k, node[k])), []);
}
static buildTrie(string, trie = {}){
if(string.length === 0){
return trie;
}
if(trie[string[0]] === undefined){
return {
...trie,
...string
.split('')
.reduceRight((o,k) => ({ [k]: o }), {}),
}
}
return {
...trie,
[string[0]]: Node.buildTrie(
string.slice(1),
trie[string[0]]
),
};
}
add(string){
this.trie = Node.buildTrie(
string.toLowerCase(),
this.trie
);
}
complete(string) {
let node = this.trie;
string
.split('')
.forEach((char) => {
node = node[char];
});
return Node.traverseChildren(string, node).slice(0,3);
}
}
const createTrie = words => {
// you do not have to do it this way; this is just how I did it
const root = new Node("");
words.forEach((w) => {
root.add(w);
})
// more code should go here
return root;
};
// unit tests
// do not modify the below code
describe("tries", function() {
it("dataset of 10 – san", () => {
const root = createTrie(CITY_NAMES.slice(0, 10));
const completions = root.complete("san");
expect(completions.length).toBe(3);
expect(
_.intersection(completions, ["san antonio", "san diego", "san jose"])
.length
).toBe(3);
});
it("dataset of 10 – philadelph", () => {
const root = createTrie(CITY_NAMES.slice(0, 10));
const completions = root.complete("philadelph");
expect(completions.length).toBe(1);
expect(_.intersection(completions, ["philadelphia"]).length).toBe(1);
});
it("dataset of 25 – d", () => {
const root = createTrie(CITY_NAMES.slice(0, 25));
const completions = root.complete("d");
expect(completions.length).toBe(3);
expect(
_.intersection(completions, ["dallas", "detroit", "denver"]).length
).toBe(3);
});
it("dataset of 200 – new", () => {
const root = createTrie(CITY_NAMES.slice(0, 200));
const completions = root.complete("new");
expect(completions.length).toBe(3);
expect(
_.intersection(completions, [
"new york",
"new orleans",
"new haven",
"newark",
"newport news"
]).length
).toBe(3);
});
it("dataset of 200 – bo", () => {
const root = createTrie(CITY_NAMES.slice(0, 200));
const completions = root.complete("bo");
expect(completions.length).toBe(2);
expect(_.intersection(completions, ["boston", "boise city"]).length).toBe(
2
);
});
it("dataset of 500 – sal", () => {
const root = createTrie(CITY_NAMES.slice(0, 500));
const completions = root.complete("sal");
expect(completions.length).toBe(3);
expect(
_.intersection(completions, ["salt lake city", "salem", "salinas"]).length
).toBe(3);
});
it("dataset of 925 – san", () => {
const root = createTrie(CITY_NAMES);
const completions = root.complete("san");
expect(completions.length).toBe(3);
expect(
_.intersection(completions, [
"san antonio",
"san angelo",
"san diego",
"san jose",
"san jacinto",
"san francisco",
"san bernardino",
"san buenaventura",
"san bruno",
"san mateo",
"san marcos",
"san leandro",
"san luis obispo",
"san ramon",
"san rafael",
"san clemente",
"san gabriel",
"santa ana",
"santa clarita",
"santa clara",
"santa cruz",
"santa rosa",
"santa maria",
"santa monica",
"santa barbara",
"santa fe",
"santee",
"sandy",
"sandy springs",
"sanford"
]).length
).toBe(3);
});
});
xdescribe("edge cases", () => {
it("handle whole words – seattle", () => {
const root = createTrie(CITY_NAMES.slice(0, 30));
const completions = root.complete("seattle");
expect(completions.length).toBe(1);
expect(_.intersection(completions, ["seattle"]).length).toBe(1);
});
it("handle no match", () => {
const root = createTrie(CITY_NAMES.slice(0, 30));
const completions = root.complete("no match");
expect(completions.length).toBe(0);
});
it("handle words that are a subset of another string – salin", () => {
const root = createTrie(CITY_NAMES.slice(0, 800));
const completions = root.complete("salin");
expect(completions.length).toBe(2);
expect(_.intersection(completions, ["salina", "salinas"]).length).toBe(2);
});
});
@rrichardsonv
Copy link
Author

Note to self, deal with 3 edge cases

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