Fun with Word Cubes

July 26th, 2010

Programming Praxis (PP) recently published a puzzle that piqued my interest. Basically, the challenge is to code a solver for Word Cubes. Since I’ve always been a Word Cube aficionado, I decided to take a crack at the problem and see if I can come up with a decent solution.

Before we move forward, I must provide some context for the uninitiated. Here’s the problem statement from PP:


Word cube is game in which players form words from the nine letters in a cube. Words must have four or more letters and must use the central letter from the cube; at least one word will use all nine letters in the cube. The player who forms the most words wins. Many newspapers publish a word cube on their puzzle page, and Stealthcopter publishes a word cube on line daily. Wikipedia describes word cubes under the caption “word polygon.” There are twelve words formed from the word cube at right: bonnie, bunion, coin, concubine, conic, cubic, ennui, icon, nice, nine, nuncio, and union.

Your task is to write a program that finds all matching words for a given word cube. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Now that we know what needs to be done, let’s focus our attention on a possible solution. But first, some essential mathematical concepts are in order.

Combinatorics 101

Math -> Maht -> Mhta -> Mhat

What do all the preceding words have in common? They seem to be permutations of a finite set (i.e. the set comprised of the letters “M”, “a”, “t”, and “h”). A permutation is nothing more than a given arrangement of a set’s elements. The notion is important because before we can exhaustively find all the possible English words that can be formed with the letters of a Word Cube, we need to compute the permutations for each combination of 4-, 5-, 6-, 7-, 8- and 9-letter words.

If you still remember anything from your discrete mathematics courses, you may know the formula to compute the number of possible permutations for a given set is the factorial of its size. Namely, if I wanted to know the number of different permutations that can be formed with the letters of the word “Math”, I’d do this:

4 x 3 x 2 x 1 = 24

We can verify this fact by generating all the possible groupings:

Math
Maht
Mtah
Mtha
Mhat
Mhta
aMth
aMht
atMh
athM
ahMt
ahtM
tMah
tMha
taMh
tahM
thMa
thaM
hMat
hMta
haMt
hatM
htMa
htaM

As it can be easily seen, the total number of groupings is indeed 24. The iterative multiplication of all the integers from one to the set’s size, inclusive,  gives us the number of different permutations without repetition. Incidentally, that’s exactly what the factorial is. The factorial is algebraically expressed as n! (e.g. 3! = 6, 4! = 24 and 6! = 720). We’d read “3!” as “three factorial”.

A combination is a similarly simple concept to grok. If I asked you to compute all the possible combinations of the word “Math”, choosing 3 characters at a time, you’d show me this:

Mat
Mah
Mth
ath

On the other hand, if I asked the same question, but instead I’d said “choosing 4 characters at a time”, you’d have showed me this:

Math

Do you see a pattern at play here? Combinations are arrangements of a set’s elements without repetition. Those arrangements are formed by taking characters out of the original set in accordance with the desired size of the resulting groupings (e.g. “choosing 3 characters at a time”, “choosing 4 characters at a time”, et cetera). In order to solve a word cube, we need to create a set with all the combinations that we’re interested on, and subsequently permute those combinations in the hopes of finding legitimate English words.

NOTE: This is a superficial treatment of two profound and very interesting concepts. If you’d like to go deeper down the rabbit hole, ask almighty Google.

NOTE 2: If you’d like to see how to compute the permutations and combinations of a set in Java code, you can read Michael Gilleland’s articles here and here. As you shall notice upon reviewing my code, I’m using his solutions extensively.

Implementation Details

Now that we’ve outlined the “hardcore” math behind the problem, let’s get to it. These are the steps we need to take if we are to successfully solve a Word Cube:

  1. Find all the possible words that can be put together using the characters from the 3 x 3 grid.
  2. Select the words that have four or more characters and contain the letter from the center of the grid.
  3. Select the words that comply with the above criteria and can also be found in an English dictionary.
  4. Display those words.

You can read the source code in its entirety here. For step (1), we need to generate all the possible combinations of the requested size (i.e. 4, 5, 6, 7, 8 and 9) and then permute each one of them. (2) is telling us that all the legal words must have the character that’s in the center of the grid. That’s an optimization right there. We don’t have to permute a combination which doesn’t have that letter. The method generateWords contains the code that’s performing these two tasks.

For (3) and (4), we need to validate and display all the generated English words. *nix operating systems (i.e. Unix-like operating systems) come with a standard English dictionary located at /usr/share/dict. Both Ubuntu 10.14 and OS X 10.5 have it. If you’re running Ubuntu, you’ll have to modify the enumeration FILES in the code so that it has the correct file names. If you’re on OS X 10.5, you have nothing to worry about. As soon as we get a set with all the generated words, checking if a word belongs to the dictionary is trivial. This is exactly what the method check does:

1
2
3
4
5
6
7
    private static void check(Set<String> words, Set<String> dict) {
        for (String word : words) {
            if (dict.contains(word)) {
                System.out.println(word);
            }
        }
    }

Here’s how the solver behaved for some cubes I threw at it:

Word Cube Execution Time (seconds)
iereprtem 1.516556
iymardida 1.625368
rirsgnaaa 1.549554
soasrcsbr 1.657542
odcaaldec 1.749831

Remember that performance may vary depending on your computer’s processing power and workload during execution. Considering that Webster’s Second International Dictionary (the default English dictionary bundled with OS X 10.5) contains 234,936 words, less than two seconds per cube is nothing to be ashamed of.

Run it!

If you’re interested in giving the solver a try, make sure you download the code and run it like this from the command line:

java progpraxis.WordCubeSolver ncbcioune /usr/share/dict

TECHNICAL NOTE: JRE 1.6 comes with a predefined memory allocation of 64 MB of RAM. This basically means your Java application has 64 MB of RAM available to do its thing and no more. If you exceed this limit knowingly or otherwise, you’ll get a big, intimidating exception (OutOfMemoryError). I completely disregarded the space complexity of my implementation (English translation: I didn’t pay attention to memory usage). Consequently, it’s very likely you’ll have to tweak your VM to allow for the successful execution of the code. If you run into any memory hurdles, just run the solver like this:

java -Xmx128M progpraxis.WordCubeSolver ncbcioune /usr/share/dict

Notice how we’re now telling the VM that it should allocate 128 MB of RAM instead of the default value. That should give the solver more than enough memory to complete its job.

TECHNICAL NOTE 2: Yes, this is a brute-force algorithm in all its glorious splendor. Aren’t those the best? If you come up with a faster, more efficient solution, please, don’t keep it to yourself. Spread the love! :)

If you like it, please share it:
  • Slashdot
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Technorati
  • Reddit
  • Twitter

You just got Vim’ed!

June 27th, 2010

An additional pet peeve of mine resulted in yet another simple hack. I’ve found myself using my mouse too much while reading lengthy articles online. This fact became acutely evident when I was going through Google’s Javascript Pacman implementation. Pressing the space bar in Firefox scrolls down, so that’s great (I don’t need to move my hands off of a typing position). But what if I wanted to scroll up with my keyboard too? Wouldn’t it be cool if I could start moving around a page as soon as I land on it using my keyboard and some good old Vim-like key presses? Yes, it’d be pretty awesome.

Vim has the following default keyboard mappings for moving around a document:

vim keyboard mappings

So if you want to scroll up, you press k. If you want to scroll down, you must press j. The Javascript code that gives Firefox the ability to scroll up and down using these key mappings is this:

function captureKeyPress(event){

    if(!event)
        event = window.event;
    var unicode = event.charCode ? event.charCode : event.keyCode;
    var actualkey = String.fromCharCode(unicode);

    if (actualkey == "j")
        window.scrollByLines(20);
    else if (actualkey == "k")
        window.scrollByLines(-20);
}
window.addEventListener("keypress", captureKeyPress, true);

Now you just need to get Greasemonkey, install the script, and you’ll be all set!

Vim’s key mappings image found at swaroopch.com.

If you like it, please share it:
  • Slashdot
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Technorati
  • Reddit
  • Twitter

Focus. Focus. Focus!

April 13th, 2010

This may be a huge pet peeve of mine, but I couldn’t possibly be alone. Don’t you hate when you land on a web page that asks for your username and password (or any other required information) and you realize you have to click on the first text box in order to start typing? Wouldn’t the world be a better place if you just could start typing immediately upon landing on such an egregious web page? I decided today I no longer need to put up with these shoddy web design practices. Enter Greasemonkey.

gmlogo

This amazing add-on for web browser Firefox allows you to execute Javascript snippets that can customize the look and feel of any site. I quickly cooked up a script that now sets the focus to the first text box on any web page. This is the ridiculously simple code that does the trick:

var inputs = document.getElementsByTagName('input');
for(i = 0; i < inputs.length; i++){
        if(inputs[i].type === "text"){
                inputs[i].focus();
                break;
        }
}

If you have Firefox and Greasemonkey, click on this link to install Focuser (you’ll see the code if you’re using a different browser). If you’d like Focuser to only do its job on certain web sites, you can easily modify the pages that are affected using Greasemonkey’s scripts manager.

Simple hacks like this make my day every time.

Greasemonkey art found at falsepositives.com.

If you like it, please share it:
  • Slashdot
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Technorati
  • Reddit
  • Twitter

Sustainability and IT – My magnum opus at RIT

February 15th, 2010

Scott Hawker, former adviser and head of my capstone project’s committee at RIT, emailed my publication-ready monograph not long ago:

presentation page

Here’s the abstract:

Information technology holds tremendous potential to help consumers and firms make more sustainable choices by providing information at key decision points. As one example, there are a number of software programs that help calculate and summarize environmental metrics for various products and processes. Surprisingly, while many printers are moving into the IT arena, the technology has not been fully utilized. For the most part, there is a lack of knowledge on the part of the consumer on the sustainability impacts of their communication decisions. Thus, this paper outlines a decision tool, presented to the consumer as they make a print decision, which estimates the energy consumption of printing a given document by analyzing the user’s requirements for the print job, the printer selected and the corresponding life-cycle criteria for these elements.

If you’d like to read more, here’s the link to the paper in PDF format. I’ll be uploading the other major component of this work (i.e. Java code) in the near future.

If you like it, please share it:
  • Slashdot
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Technorati
  • Reddit
  • Twitter

2 years + 56,000 dollars = ?

January 30th, 2010

After two years of blood, sweat, tears, and a scholarship worth US$56,000, here’s the end result:

ms degree and grades

(click for a larger view)

Sans the blood and the tears, it was quite an amazing ride. Traveling to Rochester, NY, spending 2 years at RIT and meeting all the awesome people I met along the way, is one of the most salient experiences of my short life. And to think I was morose and utterly worried because I didn’t know whether I was going to get a scholarship almost three years ago. It’s incredible what persistence and an optimistic mindset can do.

With the arrival of the certificate, this chapter of my life is officially over. It’s now time to move on and look for bigger, more difficult challenges. Up, up and away!

If you like it, please share it:
  • Slashdot
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Technorati
  • Reddit
  • Twitter