Saturday 23 July 2016

Saturday 16 July 2016

Blok Clok

When I was a boy, I was given a curious present: a perpetual desk calendar made from wooden cubes:
You can still buy them, so there must be some enduring appeal. The calendar interested me because of a strange quirk that isn't immediately obvious.

There are four blocks: one for the day of the week (with seven labels), two for the day of the month (1 to 31) and one for the month (with twelve labels). The "weekday" and "month" blocks are easy to label. For example, two months on each face fills the "month" block and, providing the container covers up the lower half of the block, all is peachy.

The two date blocks are a little more involved. Dates run from "01" to "31":


By inspection, we see that the only digits that appear twice on a single date are "1" and "2". However, if you sit down with a pencil and paper, it quickly becomes apparent that you'll also need two zeroes. That means that the following digits are required:


But, hang on! That's thirteen digits. Two cubes have only twelve faces between them. How do they fit? The clever "quirk" is that "6" and "9" occupy the same face; you simply flip the block around 180 degrees. This gives you the following faces for the two blocks:


This arrangement allows to you represent all integers between "00" to "32" inclusive; just enough! It's deceptively clever. And that's probably why I like my wooden perpetual calendar so much.

Fast forward several years, if not decades, and my current fascination with clocks led me to consider whether you could tell the time with a similar arrangement. I knew representing the hours would not be a problem: as we've seen, two blocks can represent all integers between "00" to "23" inclusive for a twenty-four-hour clock. But representing minutes is harder.

It is fairly obvious that you need at least three blocks to represent all integers between "00" to "59" inclusive. But are three sufficient? It turns out that they are; you don't even need to use the upside-down "9" trick. The solution uses an additional cube to display a colon between the hours and minutes digits. For example:


The "tens minutes" digit takes up a single block: "0" to "5" inclusive. So the problem simplifies to trying to represent the "units minutes" digit ("0" to "9") and a colon with two blocks. The following labelling is one solution:


Using three blocks to represent minutes between ":00" to ":59" inclusive can be repeated for the seconds. This gives us eight blocks:

  hours-a    0,1,2,3,4,5
  hours-b    0,1,2,6,7,8
minutes-a    :,0,1,2,3,4
minutes-b    0,1,2,3,4,5
minutes-c    :,5,6,7,8,9
seconds-a    :,0,1,2,3,4
seconds-b    0,1,2,3,4,5
seconds-c    :,5,6,7,8,9

Not only do the blocks need to rotate to any of their six faces (and in the case of "hours-b", the "6" sometimes has to be flipped to become a "9") but pairs of blocks also have to be swapped periodically:

hours-a <=> hours-b
minutes-a <=> minutes-c
seconds-a <=> seconds-c

Some extra fettling is needed to make the rotations aesthetically pleasing, but the result is a twenty-four-hour clock that twists and turns at a fair old lick.

Minimal Rotor Clock

The Rotor Clock I posted about last month is all very well, but there are a heck of a lot of moving parts: thirty-two rotors, each with ten faces. You could physically build it, but things would be a lot easier if there were fewer components. So I set about trying to reduce the number of rotors for a twelve-hour clock that displays the time as words.

The extreme (degenerate) case is a single rotor with 12 * 60 = 1440 faces. This would produce a working clock, but the rotor would need to be enormous (or the text very small). The next idea I had was a clock with two rotors: one for hours and one for minutes. You could repeat the twelve hours five times and make both rotors have 60 faces. This would still require very large rotors. Also, telling the time in a "natural" British English manner is quite tricky. Consider:


The solution I came up with (which may not be optimal, but is possibly close) is to use four rotors, each with at most twelve words or phrases plus a blank face:

    Rotor A      Rotor B      Rotor C         Rotor D
    =======      =======      =======         =======
    THIRTEEN     ONE          O'CLOCK         ONE
    FOURTEEN     TWO          MINUTE PAST     TWO
    EIGHTEEN     FIVE         HALF PAST       FIVE
    NINETEEN     SIX          QUARTER TO      SIX
    TWENTY       SEVEN        MINUTES TO      SEVEN
                 EIGHT        MINUTE TO       EIGHT
                 NINE                         NINE
                 TEN                          TEN
                 ELEVEN                       ELEVEN
                 TWELVE                       TWELVE

Note that rotor B is identical to rotor D.

This produces a clock that can tell the time as hoped for, but with the insertion of another blank face in rotor A and a bit of duplication in rotor C, I was able to reduce the number of large rotations quite considerably. This produces a series of relatively smooth transitions. The final rotors are organised thus:

    Rotor A      Rotor B      Rotor C         Rotor D
    =======      =======      =======         =======
    (blank)      (blank)      (blank)         (blank)
    THIRTEEN     ONE          O'CLOCK         ONE
    FOURTEEN     TWO          MINUTE PAST     TWO
    (blank)      THREE        MINUTES PAST    THREE
    EIGHTEEN     SIX          HALF PAST       SIX
    TWENTY       EIGHT        QUARTER TO      EIGHT
    (blank)      NINE         MINUTES TO      NINE
    (blank)      TEN          MINUTE TO       TEN
    (blank)      ELEVEN       (blank)         ELEVEN
    (blank)      TWELVE       (blank)         TWELVE

If you look at the JavaScript code, you'll see that control of the rotors is via two data tables. This scheme lends itself to efficient compression. Indeed, a slightly cut-down variation of the clock can be compressed into a single 1017-byte HTML page (providing you're using a highly-compliant browser such as Google Chrome or Mozilla Firefox).