Letter Jam word search
by thirdender
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css">
<div class="input-group m-3 w-auto">
<input type="text" class="form-control" aria-label="Letters" placeholder="Enter up to 5 letters to search" aria-describedby="search-button">
<button class="btn btn-primary" type="button" id="search-button" disabled>Search</button>
</div>
<ul class="list-group m-3"></ul>
JavaScript
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
const input = document.querySelector('input');
const button = document.querySelector('button');
const list = document.querySelector('ul');
(async () => {
// Read in /usr/share/dict/words, lowercasing words and removing non-alphabet characters
const nonAlphaRe = /\W/g;
const words = String(await fetch('https://api.github.com/gists/8927565').then((res) => res.json()).then((data) => data.files.words.content))
.split('\n')
.map((word) => word.toLowerCase().replace(nonAlphaRe, ''));
// Map all words to the unique letters that make up each word
const dictionary = {};
for (const word of words) {
if (word.length < 5) {
continue;
}
const letters = [...new Set(word.split(''))].sort().join('');
if (!(letters in dictionary)) {
dictionary[letters] = [];
}
dictionary[letters].push(word);
}
button.removeAttribute('disabled');
button.addEventListener('click', () => {
const inputLetters = input.value.toLowerCase().split('');
const results = {};
for (const letter of alphabet) {
if (inputLetters.includes(letter)) {
continue;
}
const allLetters = [...inputLetters, letter].sort().join('');
for (let i = 1; i < 32; i++) {
let key = '';
for (let j = 0; j < 5; j++) {
if (Math.pow(2, j) & i) {
key += allLetters[j];
}
}
if (key in dictionary) {
results[key] = dictionary[key];
}
}
}
[...list.childNodes].forEach((el) => list.removeChild(el));
[...new Set(Object.values(results).reduce((acc, arr) => [...acc, ...arr], []))]
.sort()
.forEach((word) => {
const li = document.createElement('li');
li.className = 'list-group-item';
li.textContent = word;
list.appendChild(li);
});
});
})();