Skip to content

Instantly share code, notes, and snippets.

@jacopotarantino
Last active March 5, 2018 18:31
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 jacopotarantino/cb6431ba5fc368926d81b63b9dc6b254 to your computer and use it in GitHub Desktop.
Save jacopotarantino/cb6431ba5fc368926d81b63b9dc6b254 to your computer and use it in GitHub Desktop.
working prototype of a progressive anagram generator
// 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"
])
@jacopotarantino
Copy link
Author

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