An Analog Clock Problem

Introduction

We're interested in determining the times in which the hour and minute hand of a 12-hour clock are antiparallel, and writing them in the U.S. style, that is, HH:MM:SS.

We want to write code that prints, to standard output, the following strings, obtaining them via actual computation:

    12:32:43
    01:38:10
    02:43:38
    03:49:05
    04:54:32
    06:00:00
    07:05:27
    08:10:54
    09:16:21
    10:21:49
    11:27:16

Small Solutions

Here are some solutions in different languages. All of them produce the correct output. We're looking for short answers, not readable ones. For once we will permit outrageous and evil hardcoding.

Perl Small Solutions

Using time formatting from the POSIX module:

use POSIX 'strftime';
print strftime("%I:%M:%S", gmtime(($_+0.5) * 43200.0/11))."\n" for (0..10);

Calculating the time components ourselves:

for my $i (0..10) {
    my $t = ($i + 0.5) * 43200.0 / 11;
    my $h = int($t / 3600);
    my $m = $t % 3600;
    printf("%02d:%02d:%02d\n", ($h ? $h : 12), $m / 60, $m % 60);
}

Python Small Solutions

Time formatting is in the time module:

from time import (strftime, gmtime)
for h in range(0,11): print strftime("%I:%M:%S", gmtime((h+0.5) * 43200.0/11))

Calculating the time components ourselves:

for i in range(0, 11):
    t = (i + 0.5) * 43200.0 / 11
    h, t = divmod(t, 3600)
    m, s = divmod(t, 60)
    print "%02d:%02d:%02d" % ((h if h else 12), m, s)

Ruby Small Solutions

Thanks to class Time being built-in, we have a true one-liner:

0.upto(10) {|h| puts((Time.gm(0) + (h+0.5) * 43200.0/11).strftime("%I:%M:%S"))}

Calculating the time components ourselves:

0.upto 10 do |i|
  t = (i + 0.5) * 43200.0 / 11
  h, t = t.divmod 3600
  m, s = t.divmod 60
  printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), m, s)
end

A Tcl Small Solution

foreach hr { 0 1 2 3 4 5 6 7 8 9 10 } {
    puts [clock format [expr int(($hr + 0.5) * 43200.0 / 11.0)] -format %I:%M:%S]
}

A Standard ML Small Solution

ML looks nicest with map, not while:

val _ = map print (List.tabulate(11, fn i => Date.fmt "%I:%M:%S\n"
    (Date.fromTimeUniv (Time.fromReal ((real(i)+0.5)*43200.0/11.0)))));

An OCaml Small Solution

TODO

A Java Small Solution

Java doesn't give direct access to the POSIX date formatter; instead, it has its own date format classes. It also requires all applications to be wrapped in classes and methods, making it impossible to write one or two line scripts.

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
public class AntiparallelClockHandsComputer {
    public static void main(String[] args) {
        long midnight = new GregorianCalendar(0, 0, 0).getTimeInMillis();
        for (int i = 0; i < 12; i++) {
            Date d = new Date(midnight + Math.round((0.5+i) * 43200000/11.0));
            System.out.println(new SimpleDateFormat("hh:mm:ss").format(d));
        }
    }
}

A Small Solution in Groovy

There is probably a better way...

midnight = new GregorianCalendar(0, 0, 0).getTimeInMillis();
0.upto(10) {i ->
    d = new Date(midnight + Math.round((0.5+i) * 43200000/11.0));
    println(new java.text.SimpleDateFormat("hh:mm:ss").format(d));
}

Small Solutions in Scala

Using classes from the Java platform

val midnight = new java.util.GregorianCalendar(0, 0, 0).getTimeInMillis()
for (i <- 0 until 11) {
    val date = new java.util.Date(midnight + Math.round((0.5 + i) * 43200000/11.0))
    println(new java.text.SimpleDateFormat("hh:mm:ss").format(date))
}

All by hand...

0 until 11 foreach { i =>
    val t = ((i + 0.5) * 43200/11).toInt; 
    val h = t/3600; 
    val m = t % 3600
    printf("%02d:%02d:%02d\n", if (h == 0) 12 else h, m / 60, m % 60)
}

Small Solutions in C

The C standard library for creating a time structure allocates the structure, so we need code to free that memory. The library code for formatting the time writes into a buffer that we have to specify a bound for. That's systems programming for you.

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
    int j;
    for (j = 0; j < 11; j++) {
        char s[9];
        time_t t = (time_t)((int)((j+0.5) * 43200.0 / 11));
        struct tm *st = gmtime(&t);
        strftime(s, 9, "%I:%M:%S", st);
        free(st);
        printf("%s\n",s);
    }
    return 0;
}

In C at least, eschewing the library leads to smaller code:

#include <stdio.h>
int main() {
    int i;
    for (i = 0; i < 11; i++) {
        int t = (i + 0.5) * 43200.0 / 11, h = t / 3600, m = t % 3600;
        printf("%02d:%02d:%02d\n", (t < 3600 ? 12 : h), m / 60, m % 60);
    }
    return 0;
}

A JavaScript Small Solution

JavaScript has no built-in classes for formatting dates nor really for formatting anything. Nor does it write anything to standard output. This code is inefficient and ugly but short:

function s(t) {t = Math.floor(t); return t < 10 ? "0" + t : t}
var report = "";
for (var i = 0; i < 11; i++) {
    var t = (i + 0.5) * 43200.0 / 11;
    var h = t / 3600;
    var m = t % 3600;
    report += s(t<3600 ? 12 : h) + ":" + s(m/60) + ":" + s(m % 60) + "\n";
}
alert(report);

A Common Lisp Small Solution

I'm not sure where in the extensive Common Lisp library the time formatting functions are. All I've been able to write is this crappy version:

(loop for i from 0 to 10 do
  (let*
    ((p (/ (* (+ i 0.5) 43200.0) 11))
     (h (/ p 3600))
     (m (mod p 3600)))
    (format t "~1,'0d:~2,'0d:~2,'0d~%"
      (truncate (if (< p 3600) 12 h))
      (truncate (/ m 60))
      (truncate (mod m 60)))))

A Smalltalk Small Solution

TODO

A Small Solution in Objective C

TODO

A Small Solution in D

TODO

A PHP Small Solution

PHP, love it or hate it, has thousands of built-in top-level functions, and one of them is gmstrftime:

for ($i = 0; $i < 11; $i++) {
    echo gmstrftime("%I:%M:%S", ($i+0.5) * 43200.0/11) . "<br />";
}

An Ada Small Solution

The shortest solution I could find uses a non-standard package

with Ada.Calendar, GNAT.Calendar.Time_IO. Ada.Text_IO;
use Ada.Calendar, GNAT.Calendar.Time_IO, Ada.Text_IO;

procedure Clock_Hands is
    T: Time;
begin
    for I in 0..11 loop
        T := Time_Of(2000, 1, 1, (Duration(I)+0.5)*Duration(43200.0/11.0));
        Put_Time(T, "%I:%M:%S"); New_Line;
    end loop;
end Clock_Hands;

A Small Solution in Prolog

TODO

A Small Solution in SQL (Oracle SQL Dialect)

TODO

A Small Script in Bash

Bash (at least as of 2007) can't do floating point arithmetic directly, so we can cheat by getting bc to do the calcs for us:

TODO

Discrete Simulation Solutions

The antiparallel hands problem makes a good case study for discrete event simulation, as shown in the paper by P. Dorin.

Variations

If we wanted the times at which the hands were parallel, rather than antiparallel, we would dispense with the adding of the 0.5 in the small solutions above.

Rather than having knowledge of a 12-hour clock hardcoded, parameters could be used for the number of hours per revolution, and the number of minutes per hour, and so on.