Tales from the jar side: My company name, good enough answers, and solving the daily Jumble
Trying to solve "cautla" and "agileo" forced me to write my own unscrambler
Welcome to Tales from the jar side, the Kousen IT newsletter, for the week of June 7 - 14, 2012. This week I didn’t have any classes to teach, so I spent it mostly writing my Managing Your Manager book and keeping up with current events. I also did a bit of a side project with Java and Groovy.
Before I get to any of that, I owe an apology to my good friend and awesome subscriber Bill Fly. I mentioned him in my last newsletter and somehow managed to mangle his name. Ugh. Mea culpa, mea culpa, mea maxima culpa. You would think that with my last name, I’d be more careful about the names of others.
Kousen IT? What’s up with that?
Since I’m on the subject, for those who might not know, my last name Kousen is pronounced as though it were spelled like the relative, cousin. I don’t know why. My paternal grandfather emigrated into the US by dubious means back in the 1920s (I think) and our last name was altered in the process. He was an odd duck on the best of days and he hated talking about the past, so we never got a straight answer about where he came from or anything about that world. All I know is that our history was basically an Anatevka story — my ancestors lived in a small village in the Pale of Settlement, probably in what is now called the Ukraine but back then was just Russia, and our town was wiped out during a pogrom in the early part of the 20th century. He and his brothers somehow managed to make it over here, thank goodness.
The odd pronunciation/spelling of my last name means my company name, Kousen IT, is a bit of a gag — I say “Kousen Eye-Tee”, but my wife says Cousin Itt, like the character from the Addams Family. Hey, it was her idea.
That’s also why my company logo looks like this:
My friend John Swanson designed the logo for me when I first went into business on my own back in 2005. I asked him to add the mortarboard and tassel, the glasses, and the smile. I kind of wish I’d pushed for a pocket protector, too, but he said it wouldn’t show up well.
So far I still haven’t heard any objections from the Charles Addams estate. If I don’t get a haircut soon, though, I’ll resemble that image closely enough that no one will notice any differences anyway.
Keeping Up With Current Events
My wife got a new sign for our lawn.
We live in a relatively rural area (my town now has two (!) stop lights) about half and hour southeast of Hartford, CT. For us, and for the town we live in, this is making a statement.
On the other hand, this isn’t exactly high on the bravery scale. If a trans PoC (person of color) getting attacked with chemical weapons and rubber bullets near the White House on the day our Fearful Leader decides to create a photo op is assigned 100 out of 100, then this is about a 5. Maybe a 7. My town has one cop assigned to it, who is borrowed from a neighboring town. Still, I’m glad we’re doing something more than just contributing to causes (and saying something in this newsletter).
Before I get to this week’s stories, I also want to say a quick word about the controversies involving trans people that came up this week. I’m an older white male, so that whole world is outside my direct experience. To learn more I follow a couple of trans creators on YouTube, two of whom I want to mention. Almost everything I know about trans issues comes from them, and I’m happy to support them both on Patreon.
One is Natalie Wynn, who has a YouTube channel called Contrapoints and a Patreon page. She gained a measure of fame a couple of years ago by releasing a video that explained much about the incel movement. She is also known for her willingness to take on the alt-right and somehow stay positive in the process.
The other trans person I follow is Jessie Gender, who also has a YouTube channel and a Patreon page and was quite active this week. Her most recent video is a response to the strange essay published by JK Rowling that tried to clarify Rowling’s recent statements about trans people, but instead solidified her as a TERF (trans-exclusionary radical feminist).
A lot of people wondered why JK Rowling would chose this moment in history to attack trans people, given that we’re dealing with a pandemic, a crisis in race relations, violence by police, and an economic disaster that somehow hasn’t yet expressed itself in the stock market yet, all at the same time. But there must be something in the air, because on Friday, we got this:
Ugh. At this point my “outrage circuits” are pretty much burned out from constant use, so when something like this happens I just get depressed. I know The Cruelty Is The Point, but it’s disheartening to see it in practice. I do try to help, and of course I’m going to vote. I only hope my vote means something this time.
I’ll leave it as this: I will fully support my LGBTQ+ friends in any way I can. I would not have thought that was a terribly controversial position, yet here we are.
Finally, on the subject of the pandemic, if you’re in the US and you want to know how your state is doing, see this site for information on how the re-opening is going. (My thanks to Michael Carducci for that link.)
Managing Your Manager
One of the chapters in my upcoming book has the working title Good Enough Answers and is about responsiveness. I try to make the case that:
A good answer today is much, much better than a great answer next week.
In order to accomplish that, I suggest that when your boss asks you an open-ended, unanswerable question (“how are the recent advances in artificial intelligence going to affect our product in the future?”), you answer quickly, with a template like:
This is what I know (add what you know)
This is what I think (add what you believe will happen)
This is where I would go to find out more information
And then the magic question:
Do you want me to look into it?
The problem with open-ended questions is that they’re open-ended. They don’t have a simple, immediate answer. That means when you get one, you’re tempted to either not answer (because you don’t want to be wrong), or put all your work aside and dig into it (because you don’t want to be wrong). The suggested template gives you a quick out. Virtually every time you answer that way, the response will be, “thanks, that’s all I wanted; no need to spend more time on it.” That saves you both time and effort. Also, in that 1 in 100 case where the boss wants to you dig in, now you can say they told you to do it when the rest of your projects are late.
This week a Dilbert cartoon was released that tied directly into that idea, though in a typically much more cynical way:
(The image is linked directly to this page and was included in a tweet. Also, this newsletter is free. So, Scott Adams, despite your highly litigious reputation, please do not sue me.)
I love that second panel. “It’s better to be timely than right, because our boss can’t judge the quality of our work, but he knows when it’s late.” I wish I could include that in my book, but I’m sure we can’t afford it. It’s nice to see a principle I’m writing about randomly surface in the popular media, however.
Jumble Solver
The newspaper industry is in the midst of a catastrophic slump based on several factors, not the least of which is being acquired by venture capitalists who strip them down for parts and then declare bankruptcy. For many years I subscribed to my local paper, the Hartford Courant (pronounced “current”), but grew disenchanted with it and stopped. A few weeks ago I decided to try their electronic edition again just to be supportive, and it’s been pretty decent so far.
One side-effect of that decision is that I now see their daily Jumble puzzle. Here is a sample:
A typical jumble, from the Hartford Courant, 11 June 2020. Solutions below.
Usually I can get the five-letter words pretty quickly, but the six-letter words are a lot harder. I stare and stare, and sometimes I can’t make them resolve correctly.
It occurred to me that it wouldn’t be hard to write my own Jumble solver, especially if I used Groovy. The Groovy JDK adds a method to java.util.Iterable called permutations.
That means if I take a word and convert it to a list of characters, I can get all the reorderings of that word in one call. On Macs (and any operating system ultimately based on BSD), there is a file called “words” in the /usr/share/dict directory which contains all 235,000 words from Webster’s Second International dictionary, copyright 1934, one word per line. I can search that file for each permutation and get the solution to the jumble.
I’m planning a blog post on this, but I couldn’t free up enough time this week to really flesh that out. Instead, I’ll show one key observation here. My first solution can be found in this gist containing the file Jumble.groovy and looked like:
import groovy.transform.CompileStatic
@CompileStatic
class Jumble {
// dictionary words
private List wordList =
new File('/usr/share/dict/words').readLines()
.findAll { it.size() == 5 || it.size() == 6 }
String solve(String clue) {
List<String> letters = clue.split('').toList()
letters.permutations()
.collect { it.join('') }
.find { wordList.contains(it) }
}
}
(The gist has a test as well. See the link for details.)
This works, but relies on that permutations method. I was thinking of re-implementing this in both Java and Kotlin, but neither of those languages have a similar method.
I decided to show my Groovy version to my friend and brilliant developer Tim Yates, who is just about the best person at algorithms I’ve ever met. He suggested a different approach, which is listed as Jumble2.groovy in the same gist.
@CompileStatic
class Jumble2 {
private Map<String, List<String>> wordMap =
new File('/usr/share/dict/words').readLines()
.findAll {it.size() == 5 || it.size() == 6 }
.groupBy { it.toList().sort().join('') }
String solve(String clue) {
def key = clue.toList().sort().join('')
wordMap[key].head()
}
}
The key observation is to take each word and sort its letters alphabetically*. Then the groupBy operation generates a map of each key to a list of words that have the same letters. With that, given a clue you can generate the key, look it up in the map, and return the first word found there. As I said, brilliant. :)
*Okay, the natural sort for strings is not actually alphabetical, it’s lexicographical, meaning capital letters come before lowercase letters. Whatever.
The downside to this approach is that the each key could possibly map to more than one word in the dictionary, so there might be multiple solutions. As a simple example, the letters eeirvw unscramble to both review and viewer. Tim just returned the first one. I worried about that problem (what if the word I needed is not the first one?) and then realized that’s not my problem — it’s the Jumble maker’s problem. Both are right, but if they prefer one over the other, they have to provide more information, or, more likely, pick jumbles that only sort to a single word.
There’s another problem, though, and I hit it with the example shown. The first three words unscramble to AMAZE, CROWD, and FLAUNT. So far, so good. But the last one unscrambles to BOOGIE, which my solver didn’t find. It turns out that although the first usage of that word goes back to at least 1929, apparently the 1934 edition of Webster’s dictionary didn’t include it yet. The current online version has it, of course.
I have a Java version of the solver that uses streams and I’ve implemented it so I can search for all four words in parallel (if you’re going to do a silly project, you might as well go all out). My current version of that is in the class JumbleJ.java in the same gist. I also want to solve the problem in Kotlin and maybe generate a native image using GraalVM. Maybe I’ll have time to do that and write the full blog post next week. Or maybe I’ll come to my senses and decide that’s enough, though I wouldn’t count on it.
By the way, the answer to the clue in the image (“the psychiatrist’s new plush furniture helped to create a —”) is COMFORT ZONE.
Upcoming Classes
I’m teaching two NFJS Virtual Workshops next week. One is a basic Kotlin workshop:
NOTE: The time is wrong. It’s actually 11am to 2:30pm EDT.
The other is a deep dive into the Spring framework:
The actual time (correct on the web site) is 11am to 6pm EDT
If you sign up for either one, be sure to say hi when you join. :)
If you’re still stuck on this issue’s subtitle
The word cautla unscrambles to actual and agileo becomes goalie.
Last week:
Mostly writing my Managing Your Manager book
This week:
Kotlin Basics and Beyond NFJS virtual workshop
Spring and Spring Boot Deep Dive NFJS virtual workshop
More writing, and maybe that silly blog post referenced above