Five years or five minutes

Written by

in

A friend of mine posted a link on Facebook to this story about an old lady who spent five years compiling a list of three-letter words for Scrabble. I thought this was a perfect example of applicability vs avoidability.

Scripting to the rescue 

I happen to have dedicated a bit of time to the study of Scrabble. I wrote a crossword-setting program for my computer-science project in Matric, and have always enjoyed word games of all kinds. Scrabble also happens to be the thing that got me onto Facebook. The fact that these combinatorial problems are ideally suited to computer analysis is obvious to me, although many people think it would be cheating. This is why I know that there are easily downloadable official scrabble wordlists. They all have names like CSWyy.txt, with yy a two-digit year. There are ’06, ’07 and ’12 versions, which you can easily download from several sources, for instance (from the Zyzzyva website):
$ wget http://www.zyzzyva.net/lexicons/CSW{06,07,12}.txt

A little bit of regular expression knowledge will help you to do the following:

$ grep "^...$" CSW12.txt

This gives you a full list of all the three letter words in the wordlist.

Of course, now we want to be able to figure out the scores of the words. The letter scores of the words are easily found on Wikipedia:

  • 1 pointE ×12, A ×9, I ×9, O ×8, N ×6, R ×6, T ×6, L ×4, S ×4, U ×4
  • 2 pointsD ×4, G ×3
  • 3 pointsB ×2, C ×2, M ×2, P ×2
  • 4 pointsF ×2, H ×2, V ×2, W ×2, Y ×2
  • 5 pointsK ×1
  • 8 pointsJ ×1, X ×1
  • 10 pointsQ ×1, Z ×1

I wrote a quick Awk program to calculate the word scores, taking advantage of a couple of cool Awk features (like automatic conversion of strings to numbers):

BEGIN {score="0D1G1B2C2M2P2F3H3V3W3Y3K4J7X7Q9Z9"} # score table
/^...$/ { # Match three-letter words
   s=0; # accumulator for scores
   for(i=1;i<=length($0);i++) {
      # Find the current character in the score table
      # move one down for the score and add one
      s += 1+substr(score, 1+index(score, substr($1, i, 1)))}; 
      print s, $1
   }
}

The version above has been commented, but it started out as a one-liner, which can be used as follows:

$ awk 'BEGIN {score="0D1G1B2C2M2P2F3H3V3W3Y3K4J7X7Q9Z9"} /^...$/ {s=0; for(i=1;i<=length($0);i++) {s+=1+substr(score, 1+index(score, substr($1, i, 1)))}; print s, $1}' CSW12.txt | sort -nr | head

This gives us my version of the table in the article:

30 ZZZ
21 ZUZ
21 ZIZ
19 ZEX
19 ZAX
19 JIZ
16 ZEK
15 ZHO
15 WIZ
15 PYX

Notice that she missed out quite a few high-scoring words, and spent five years on this, while it took me a couple of minutes to bash out the script.

My observations are first, that it is clearly possible to compile a list like the article describes without using programming, but it would have taken her a lot less time to learn programming and then compile the list than it probably took her to compile it by hand. In this case, programming is avoidable, but definitely applicable.

I suppose she could also just have downloaded Zyzzyva (a scrabble word-lookup GUI program), but to be honest, I couldn’t get the list above as quickly, because the word scores weren’t in the program by default and I couldn’t figure out how to get them there.

Other implementations

I did a quick Python implementation as well, slightly less suited for one-liners on the commandline, but perhaps a little more legible:

table = {'A': 1, 'B': 3, 'C': 3, 'D': 2, 'E': 1, 'F': 4, 'G': 2, 'H': 4,
         'I': 1, 'J': 8, 'K': 5, 'L': 1, 'M': 3, 'N': 1, 'O': 1, 'P': 3,
         'Q': 10, 'R': 1, 'S': 1, 'T': 1, 'U': 1, 'V': 4, 'W': 4, 'X': 8,
         'Y': 4, 'Z': 1,
         }

wordsandscores = [(sum(table[c] for c in word), word) for word in
                  [w.strip() for w in open('CSW12.txt')] if len(word)==3]
wordsandscores.sort(reverse=True)

for s, w in wordsandscores[:10]:
    print s, w

I’m also very keen to have someone post the solution to this problem using Windows Powershell.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.