Solving Puzzlemaster Presents with JavaScript: April 15th

The Puzzlemaster Presents puzzles come from Will Shortz and NPR

I love solving puzzles, I love JavaScript, and I listen to Will Shortz’ Sunday Puzzle almost every week. Oftentimes, I find myself thinking of ways I could solve Will’s puzzles with code. This post, and the ones that follow, are a way for me to combine my passions and hopefully teach a bit of JavaScript and algorithms.

This is the first installment of solving Puzzlemaster Presents puzzles with JavaScript! I’ll try to do the puzzle every week using as much of a code mentality as possible, so stay tuned for more. I’ll try to touch on the benefits and drawbacks of design decisions, but please keep in mind that the code I write here won’t necessarily be optimized for speed. That being said, if you like the solutions, have an improvement, comment, or suggestion, please add a comment!

Today’s puzzle is a word jumble between countries and animals:

The letters of Switzerland can be rearranged to spell lizard and newts — lizard being the singular name of an animal and newts as a plural. Name another country with the same property. That is name another country whose letters can be rearranged to name two animals, one singular and one plural. It’s a major country. What country is it?

Right off the bat, we see that we’ll probably need a set of all the countries and a set of all the animals.

Countries aren’t too hard, and we can find a set of all of them from github user kalinchernev ‘countries’ gist:

Animals are a bit trickier. We can find a list of all the singular animals from github user atduskgreg’s ‘animals’ gist:

However it is important to consider that we’ll need to use the plurals of these animals. Most will have plurals that simply have an s tacked to the end, but some (like Deer or Goose) have special plurals. A google search for ‘animal plurals’ turns up the Wikipedia page on ‘Terms of Venery,’ aka what groups of animals are called like a ‘pod’ of whales. This page happens to list over 200 types of animals with their venery names, but all we care about are the plural forms of those animals:

Note that all the word data I use in this post (and probably posts to come) has been converted to all lowercase.

More importantly, the Wikipedia Venery page has some awesome names for animal groups like a murder of crows, a shrewdness of apes, and a shadow of jaguars. If you want to beef up on your vocab for your next pre-teen birthday party, spend some quality time on the venery pages.

Now lets plan out our solution given the data we have.

First, they give us the example of switzerland becoming lizard newts. How can we be sure they’re right? To prove it, we just need to prove that the country and the singular-plural animal pair are anagrams. One quick way to tell if two strings are anagrams is to sort the strings and compare the sorted values. It also helps to remove whitespace and other less-than-helpful characters. This combination is something I’ll call smoosh-sorting, and will be referred to as smooshing, sorting, or both from now on.

Once smooshed, we see that switzerland and lizard newts both become adeilnrstwz , and thus are anagrams of one another.

One way to find all the countries that can become singular-plural animal pairs (which will just be called animal pairs from now on) would be to create a set of all the smooshed countries and a list all the smooshed animal pairs, then check to see if any of the smooshed animal pairs are in the set of smooshed countries.

I’m choosing to use an ES6 Map for the smooshed countries because it will improve lookup time compared to using an array of the smooshed countries. We could have used a Set or a regular object, and but I like to use Maps because they are more expressive.

To create our Map of countries, all we need to do is load the countries from a .txt file, sort each country, then map each sorted country name to its original name:

The animals are, again, more difficult. We’ll need to create every possible combination of singular and plural animals. This is just the beginning of the list, but the full list will have a length of the total number of animals squared:

Keep in mind that the plural animals will need to include both the singular animals with an s tacked on as well as all the special animals we got from the Venery Wikipedia page. Also, a conspiracy of lemurs?!

Anyways, while we’re making pairs, we’ll want to create the smooshed version of our pairs so we can use them in the country Map later. Heres a function that creates this list of pairs with their sorted versions. It works by iterating over all the singular animals, creating every possible plural pair for that singular animal, smooshing each of those combinations, and storing the smooshed version and the original in a list that it returns in the end:

Finally, we can wrap everything together. We have our Map of smooshed countries and our list of smooshed animal pairs. All we need to do is filter out the animal pairs who’s smooshed versions aren’t in the smooshed country Map:

Running our script we get the result:

Nice! It looks like there are three solutions, one of which is the Switzerland/Newt/Lizards combination that Will Shortz gave us. It looks like the “major country” answer would be Mexico/Ox/Mice, but the Pakistan/Takin/Asp answer is totally valid too. In case you were wondering, as I was, about what a Takin and an Asp are, here are some pictures:

Using a pair of calls, I found that the script 2.79 seconds. This would be pretty terrible performance on a production server, but isn’t too bad if you have a whole week to find the answer.

I hope you enjoyed this week of Solving Puzzlemaster Presents with JavaScript! Now go charge off into the world of coding like a Crash or Rhinos.