Last active
March 5, 2018 18:31
-
-
Save jacopotarantino/cb6431ba5fc368926d81b63b9dc6b254 to your computer and use it in GitHub Desktop.
working prototype of a progressive anagram generator
This file contains hidden or 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
// progressive anagram generator | |
// a function that takes in a list of words | |
// and returns a tree structure with an anagram letter at the head of each branch | |
function mapWordsToLetterFrequency (source_words) { | |
return source_words.reduce((accumulator, current_word) => { | |
current_word.letters.forEach(letter => { | |
if (!accumulator[letter]) { | |
accumulator[letter] = 0 | |
} | |
accumulator[letter]++ | |
}) | |
return accumulator | |
}, {}) | |
} | |
function mapLettersToIncludedWords (words) { | |
return words.reduce((accumulator, current_word) => { | |
current_word.letters.forEach(letter => { | |
if (!accumulator[letter]) { | |
accumulator[letter] = new Set() | |
} | |
accumulator[letter].add(current_word) | |
}) | |
return accumulator | |
}, {}) | |
} | |
function mapLettersToExcludedWords (letters, words) { | |
return Object.keys(letters).reduce((accumulator, letter) => { | |
if (!accumulator[letter]) { | |
accumulator[letter] = new Set() | |
} | |
const excluded_words = words.filter(word => { | |
return !word.letters.has(letter) | |
}) | |
excluded_words.forEach(word => accumulator[letter].add(word)) | |
return accumulator | |
}, {}) | |
} | |
function getLettersByFrequency (letters) { | |
return Object.keys(letters).map(letter => { | |
return [letter, letters[letter]] | |
}).sort((a, b) => { | |
if (a[1] === b[1]) { return 0 } | |
return (a[1] > b[1]) | |
? -1 | |
: 1 | |
}) | |
} | |
class Word { | |
constructor (word) { | |
this.original_word = word | |
this.letters = new Set(word.split('')) | |
} | |
} | |
class Letter { | |
constructor (letter, all_words) { | |
this.letter = letter | |
this.included_words = new Set(all_words.filter(word => word.letters.has(letter))) | |
this.excluded_words = new Set(all_words.filter(word => !word.letters.has(letter))) | |
} | |
} | |
class TreeNode { | |
constructor (letter, left, right) { | |
this.head = letter | |
this.left_children = left | |
this.right_children = right | |
} | |
} | |
function generateProgressiveAnagram (source_words) { | |
const words = source_words.map((word) => new Word(word)) | |
const letter_counter = mapWordsToLetterFrequency(words) | |
const letters_used = Object.keys(letter_counter) | |
const total_remaining_words = words.splice(0) | |
const total_remaining_letters = letters_used.map(letter => new Letter(letter, words)) | |
console.log(JSON.stringify(getTree(total_remaining_words, total_remaining_letters, []), null, 2)) | |
} | |
function getTree (words, letters, used_letters) { | |
if (words.length === 0 || letters.length === 0) { return null } | |
const current_letter = letters.shift() | |
used_letters.push(current_letter) | |
const new_letters = Object.keys(mapWordsToLetterFrequency(words)) | |
.filter(letter => !used_letters.includes(letter)) | |
const included_words = words.filter(word => word.letters.has(current_letter)) | |
const excluded_words = words.filter(word => !word.letters.has(current_letter)) | |
return new TreeNode( | |
current_letter, | |
getTree(excluded_words, new_letters, used_letters), | |
getTree(included_words, new_letters, used_letters)) | |
} | |
generateProgressiveAnagram([ | |
"aries", "taurus", "gemini", "cancer", "leo", "virgo", | |
"libra", "scorpio", "sagittarius", "capricorn", "aquarius", "pisces" | |
]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://repl.it/repls/HomelyOilyApplets