Building a Word Unscrambler with JavaScript (part 2)
Bridget Amana
Posted on September 30, 2024
In my last article, I was stuck on a little bug. I thought I had fixed it, but well... let's just say I had an "oops" moment. All that was missing was the logical NOT operator “!” in the if
condition like this:
if (!uniquePermutations.includes(newPermutation)) {
uniquePermutations.push(newPermutation);
}
I added it and now, we move on to the next problem.
The Length Issue
After generating all the permutations, I noticed something else. My word unscrambler was only giving me permutations that were exactly the length of the input word. So if I typed in "wood," I got permutations like "doow" and "odwo" but never shorter words like "wo" or "ow." That's not what I wanted.
I needed to find a way to generate all possible combinations, not just those of the same length as the input word.
So, here’s what I did:
function generatePermutations(inputString) {
const uniquePermutations = [];
function generateUniquePermutations(arr, currentIndex, length) {
if (currentIndex === arr.length - 1) {
const newPermutation = arr.slice(0, length).join("");
if (!uniquePermutations.includes(newPermutation)) {
uniquePermutations.push(newPermutation);
}
} else {
for (let i = currentIndex; i < arr.length; i++) {
[arr[currentIndex], arr[i]] = [arr[i], arr[currentIndex]];
generateUniquePermutations([...arr], currentIndex + 1, length);
}
}
}
for (let length = 2; length <= inputString.length; length++) {
generateUniquePermutations(inputString.split(""), 0, length);
}
return uniquePermutations;
}
console.log(generatePermutations('wood'));
Breaking It Down:
I modified the generateUniquePermutations
function to accept a length argument, which slices the array and ensures it generates permutations of different lengths. I also added a loop that starts at 2 and goes up to the full length of the input word.
Categorizing by Length
Once I had all my word permutations, I thought it would be much nicer (and way easier on the eyes) if I could categorize them by word length. So here’s how I broke them down:
function categorizeByLength(combinations) {
const categorized = {};
combinations.forEach(word => {
const length = word.length;
if (!categorized[length]) {
categorized[length] = [];
}
categorized[length].push(word);
});
return categorized;
}
This function takes the list of permutations, groups them by their length, and returns an object where each key is a word length (2, 3, 4, etc.), and each value is an array of words of that length.
Displaying the Results
Next up, I wanted these categorized results to actually show up nicely in the browser. I wrote a function that dynamically creates sections in the HTML for each word length, then lists all the words under those sections.
function displayResults(categorizedWords) {
const resultsContainer = document.getElementById('resultsContainer');
resultsContainer.innerHTML = '';
for (const [length, words] of Object.entries(categorizedWords)) {
const section = document.createElement('div');
section.className = 'result-section';
const header = document.createElement('h2');
header.textContent = `${length}-Letter Words`;
section.appendChild(header);
const wordList = document.createElement('ul');
words.forEach(word => {
const listItem = document.createElement('li');
listItem.textContent = word;
wordList.appendChild(listItem);
});
section.appendChild(wordList);
resultsContainer.appendChild(section);
}
}
This is what we have
Next up? I need to work on filtering out the invalid words. Right now, I’m getting all sorts of gibberish, and I only want real, meaningful words. Still stick around 🙃
Posted on September 30, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.