A Monkey Puzzle Pattern

One of the persistent challenges in user interface design involves separating legitimate input from the noise, mistakes, and downright malicious signals that criss-crossing the online sphere. While many of these schemes focus on eliminating submissions and traffic from automated sources, others focus on reducing unintentional user errors. But all of these schemes share one thing in common: the assumption that a given user actually wants to execute a potentially regrettable transaction. That’s a fair assumption for most of the week, but things tend to change sometime around midnight on Friday.

When I recently worked on a project that expected a somewhat more…revelrous audience, we decided to tear a page from the book of GMail Goggles and devise a new kind of test aimed at reducing interpersonal errors. So, the next time you find yourself faced with a situation where the the Luhn algorithm just won’t cut it, I give you the CAPTHIHA: a completely automated public Turing test for telling humans and impaired humans apart.

It’s a simple test for frustrating users that probably shouldn’t be using your service in the first place, and you can find the salient pieces of the first prototype here.

The test we devised consisted of two parts:

  1. A model for generating a puzzle and computing its solution
  2. A view for rendering the puzzle and comparing the response with the solution

Of course, the real challenge lay in devising a test that can accurately a functioning, rational, and self-conscious actor from one that will regret their actions in the morning. After the original version proved trivially simple (see the demo), we introduced a second variation that introduces a more complex task. The general form takes a sequence of letters and asks the user to complete the pattern:

ADGJADGJADG[?]

One of the nice features of the original test was the use of a swappable build function in computing puzzles and solutions. Updating the test with a new puzzle simply requires extending the base puzzle with a new build function:

var PuzzleV2 = Puzzle.extend({

  build: function() {

    var current,
        repeat = this.random(1) + 3,
        step = this.random(2) + 1,
        first = this.random(14);

    var challenge = [],
        solution;

    while (challenge.length < 12) {
      current = first;
      for (i=0;i<repeat;i++) {
        challenge.push(String.fromCharCode(current + 65));
        current += step; 
      }
    }
    solution = challenge.pop();                    
    this.set({
      challenge: challenge.join('') + '[?]',
      computedSolution: solution
    });
  }
});

Though this variation fared slightly better than its predecessor in testing, our experience served as much as anything as a testament to the power of inebriated ingenuity. Still, trivial puzzles have some practical use in separating humans from very basic automatons, and the CAPTHIHA provides a plug-and-play implementation that can be easily altered to fit the needs of many other applications.

Let’s keep in touch

Get noise-free updates on software, product, and process.

Hey, I'm RJ: digital entomologist and intermittent micropoet, writing from the beautiful Rose City.