The blog of dlaa.me

Posts from April 2021

Can you use it in a sentence? [An example of solving the New York Times Spelling Bee puzzle with JavaScript]

The New York Times Crossword app includes a daily puzzle called "Spelling Bee". The challenge is to make as many four-or-more letter words from a set of seven letters as you can. Each word must contain only those letters (using a letter multiple times is okay) and all of the words must include a specific letter (highlighted as part of the puzzle). It's pretty straightforward and the goal is to find a bunch of valid words with extra credit being given for long words and extra-extra credit for a word that uses all of the day's letters (known as a "pangram"). It's fun and you can spend as little or as much time as you want.

The app lets you see a list of all the previous day's words, but maybe you're stuck and want some ideas today. Or maybe you're bored and wonder what it would look like to solve this in code. Or both. I won't judge.

As usual, there are various ways to solve this problem. This one is mine. On iOS, my go-to application for writing JavaScript is Scriptable. It offers a modern JavaScript environment with handy helper functions and is pleasant to use on both iPhone and iPad. In this case, the Request.loadJSON method provides a concise way to load a list of popular English words from the Internet. The source I chose is dictionary.json from this GitHub repository. In addition to being a fairly comprehensive list of English words, this file is in JSON format which is automatically parsed by the API above.

The algorithm I use is fairly straightforward: download the list of words and loop through them looking for valid ones. Once found, check if the word is a pangram and write it to the console (red if so, white otherwise). I use a RegExp for the validity check and augment it with a function call to ensure the required letter is present. (I don't think there's an elegant way to do everything with a single regular expression, but I'd be happy to learn one! And I'm not interested in clunky ways because I already know a few of those.) The pangram check is basically also a loop, though it uses Array's reduce for conciseness. There are a couple of less-common practices to keep things interesting, but otherwise the code speaks for itself.

I didn't want to "spoil" a previously published puzzle, so the code below uses the seven unique letters of my full name with "d" as the required letter. Running the sample code with this set of letters doesn't output a pangram for any dictionary I tried, so it's unlikely to ever be a real Spelling Bee puzzle! (Fun fact: the longest valid word for this input seems to be "nondivision".)

// Puzzle letters; the first is required
const letters = "davinso";

// Source of word list JSON dictionary
const req = new Request("https://github.com/adambom/dictionary/blob/master/dictionary.json?raw=true");

// Output valid words to console log/error
const valid = new RegExp("^[" + letters + "]{4,}$");
const required = letters[0];
const optionals = letters.slice(1).split("");
req.loadJSON().then((dictionary) => {
  const sorted = Object.keys(dictionary).map((word) => word.toLowerCase());
  sorted.sort();
  for (const word of sorted) {
    if (valid.test(word) && word.includes(required)) {
      const pangram = optionals.reduce(
        (prev, curr) => prev && word.includes(curr),
        true
      );
      console[pangram ? "error" : "log"](word);
    }
  }
}).catch(console.error);