An Analog Clock Problem

Sometimes it’s fun to see a single program written in many different programming languages.
Canvas isn’t supported on this browser.

Animation adapted from Mozilla

Phil Dorin created the following interesting problem: Determine the times in which the hour and minute hand of a 12-hour analog clock are antiparallel, and format them in the 12-hour U.S. style, producing the following output:

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

The answers must be computed, not hard-coded. There are two main approaches to this problem:

Here we’ll produce analytic solutions to the problem in 42 different languages. Sometimes we’ll make use of library routines to generate and format times, and sometimes we’ll compute hour, minute, and section fields using basic arithmetic only. We’ll go for really short, comment-free hacks with outrageous violations of proper coding styles, just to make the answers short. Our goal is to just show snippets of many different languages.


python-logo.png

Python

Using the time module:

import time
for i in range(0, 11):
    print(time.strftime('%I:%M:%S', time.gmtime((i + 0.5) * 43200 / 11)))

Calculating the time components ourselves:

for i in range(0, 11):
    t = (i + 0.5) * 43200 / 11
    h, t = divmod(t, 3600)
    m, s = divmod(t, 60)
    print('{:02}:{:02}:{:02}'.format(int(h if h else 12), int(m), int(s)))

On the command line:

python3 -c 'import sys,time;[sys.stdout.write(time.strftime("%I:%M:%S",\
    time.gmtime((i + 0.5) * 43200 / 11))+"\n") for i in range(0, 11)]'
ruby-logo.png

Ruby

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

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

Calculating the time components ourselves:

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

Directly from the command line:

ruby -e '0.upto(10) {|i| puts((Time.gm(0) + (i + 0.5) * 43200 / 11).strftime("%I:%M:%S"))}'
lua-logo.png

Lua

With the os time and date functions:

for i = 0, 10 do
  print(os.date("!%I:%M:%S", math.floor((i + 0.5) * 43200 / 11)))
end

This can even be on one line:

for i = 0, 10 do print(os.date("!%I:%M:%S", math.floor((i + 0.5) * 43200 / 11))) end

Here is the do-it-yourself formatting version:

for i = 0, 10 do
  local t = math.floor((i + 0.5) * 43200 / 11)
  local h = t // 3600
  local m = t % 3600
  print(string.format("%02d:%02d:%02d", (h < 1 and 12 or h), m // 60, m % 60))
end

And directly on the command line:

lua -e 'for i = 0, 10 do print(os.date("!%I:%M:%S", math.floor((i + 0.5) * 43200 / 11))) end'
tcl-logo.png

Tcl

This solution is due to B.J. Johnson:

for {set i 0} {$i < 11} {incr i} {
    puts [clock format [expr int(($i + 0.5) * 43200 / 11)] -format %I:%M:%S]
}
perl-logo.jpeg

Perl

Using the POSIX module for time formatting:

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

Calculating and formatting the time components ourselves:

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

Passing the program as a command line argument:

perl -MPOSIX -le 'print strftime("%I:%M:%S", gmtime(($_ + 0.5) * 43200 / 11)) for (0..10)'
awk-logo.png

AWK

The do-it-yourself way:

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

The GNU AWK dialect (that’s the AWK you get on GNU-based systems, Ubuntu, Debian, etc., and not macOS) has strftime built-in:

BEGIN {
    for (i = 0; i < 11; i++) {
        print strftime("%I:%M:%S", (i+0.5) * 43200.0/11, 1)
    }
}
c-logo.png

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() {
    for (int i = 0; i < 11; i++) {
        char s[9];
        time_t t = (time_t)((int)((i + 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;
}

Perhaps surprisingly, eschewing the library leads to smaller code:

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

C++

Most C programs are C++ programs, so we could take the C program above and change the include of <stdio.h> to <cstdio> and it would run fine. Or, we can use C++ streams for output:

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    for (auto i = 0; i < 11; i++) {
        int t = (i + 0.5) * 43200.0 / 11, h = t / 3600, m = t % 3600;
        cout << setfill('0') << setw(2) << (h ? h : 12)
             << ':' << setw(2) << (m / 60)
             << ':' << setw(2) << (m % 60)
             << endl;
    }
    return 0;
}
d-logo.png

D

D looks a little like C:

import core.stdc.stdio;

int main() {
    for (int i = 0; i < 11; i++) {
        int t = cast(int)((cast(double)i + 0.5) * 43200.0 / 11.0);
        int h = t / 3600;
        int m = t % 3600;
        printf("%02d:%02d:%02d\n", (h ? h : 12), m / 60, m % 60);
    }
    return 0;
}
rust-logo.png

Rust

Just the do-it yourself version for now:

fn main() {
    for i in 0..11 {
        let t = (((i as f64) + 0.5) * 43200.0 / 11.0) as i32;
        let h = t / 3600;
        let m = t % 3600;
        println!("{:02}:{:02}:{:02}", if h == 0 {12} else {h}, m / 60, m % 60);
    }
}
go-logo.png

Go

Just the do-it yourself version for now:

package main
import "fmt"
func main() {
    for i := 0; i < 11; i++ {
        t := int64((float64(i) + 0.5) * 43200.0 / 11.0)
        h := t / 3600
        m := t % 3600
        if h == 0 {h = 12}
        fmt.Printf("%02d:%02d:%02d\n", h, m / 60, m % 60)
    }
}
swift-logo.png

Swift

The do-it yourself formatting version:

import Foundation
for i in 0..<11 {
    let t = Int((Double(i) + 0.5) * 43200.0 / 11.0)
    let h = t / 3600
    let m = t % 3600
    print(String(format:"%02d:%02d:%02d", arguments:[(h==0 ? 12 : h), m / 60, m % 60]))
}
csharp-logo.png

C#

My first C# program:

using System;
public class AnalogClockHandsComputer
{
    public static void Main()
    {
        for (var i = 0; i < 11; i++)
        {
            var t = (int)((i + 0.5) * 43200.0 / 11);
            var h = t / 3600;
            var m = t % 3600;
            Console.WriteLine("{0:00}:{1:00}:{2:00}", (h != 0 ? h : 12), m / 60, m % 60);
        }
    }
}
java-logo.png

Java

Java 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.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class AntiparallelClockHandsComputer {
    public static void main(String[] args) {
        for (int i = 0; i < 11; i++) {
            LocalTime t = LocalTime.MIDNIGHT.plusSeconds((long)Math.floor((0.5 + i) * 43200.0 / 11));
            System.out.println(t.format(DateTimeFormatter.ofPattern("hh:mm:ss")));
        }
    }
}

Here’s the direct computation:

public class AntiparallelClockHandsComputer {
    public static void main(String[] args) {
        for (int i = 0; i < 11; i++) {
            int t = (int)((i + 0.5) * 43200.0 / 11), h = t / 3600, m = t % 3600;
            System.out.printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), m / 60, m % 60);
        }
    }
}
groovy-logo.png

Groovy

I hope this is okay. It gives the right answers at least.

0.upto(10) {i ->
    def t = (int)((i + 0.5) * 43200.0 / 11);
    def h = t.intdiv(3600);
    def m = t % 3600;
    printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), m.intdiv(60), m % 60);
}
scala-logo.jpeg

Scala

I just did this one by hand. It might be nice to use the functions from java.time.

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)
}
ceylon-logo.png

Ceylon

I’m not very good with Ceylon yet, so this is my first pass. I know there is a Ceylon time module, but I’ve not looked into it yet.

function pad(Integer n) => if (n < 10) then "0``n``" else "``n``";

for (i in 0:11) {
    Integer t = ((i + 0.5) * 43200.0 / 11).integer;
    Integer h = t / 3600;
    Integer m = t % 3600;
    print("``if (h==0) then 12 else h``:``pad(m / 60)``:``pad(m % 60)``");
}
kotlin-logo.png

Kotlin

Here’s a quick hack:

fun main(args: Array) {
    for (i in 0..10) {
      val t = ((i + 0.5) * 43200.0 / 11).toInt()
      val h = t / 3600
      val m = t % 3600
      println(String.format("%02d:%02d:%02d", if (h==0) 12 else h, m / 60, m % 60));
    }
}
js-logo.png

JavaScript

The built-in time formatting utilities are weak, but moment.js is a fabulous third-party library. Here’s a command line version for Node:

const moment = require('moment')
for (let h = 0; h < 11; h++) {
  console.log(moment.unix((h+0.5) * 43200/11).utcOffset(0).format('hh:mm:ss'));
}

If you don’t want to install a third party library, and you don’t mind an outrageous hack (extracting time fields by position from an ISO datetime), you can do this 😬:

for (let i = 0; i < 11; i += 1) {
  const d = new Date((i + 0.5) * 43200000 / 11);
  console.log(d.toISOString().substring(11,19).replace(/^00/, '12'));
}
coffeescript-logo128.png

CoffeeScript

Clean version, with the moment library:

moment = require 'moment'
for i in [0..10]
  console.log moment.unix((i+0.5) * 43200/11).utcOffset(0).format('hh:mm:ss')

And here’s the horrible hacky version:

(console.log new Date((i+0.5)*43200000/11).toISOString().substring(11,19).replace(/^00/,'12') for i in [0..10])
dart-logo.png

Dart

This one is due to Alex Schneider:

void main() {
    new Iterable.generate(11, (index) {
        var s = (index + 0.5) * 43200 / 11;
        var hm = [s ~/ 3600, s % 3600];
        var hms = [hm[0] == 0 ? 12 : hm[0], hm[1] ~/ 60, (hm[1] % 60).truncate()].map((m) =>
            m.toString().padLeft(2, '0')).toList();
        print('${hms[0]}:${hms[1]}:${hms[2]}');
    }).last;
}
sml-logo.png

Standard ML

Standard ML has access to the POSIX time formatting and parsing functions, but it (perhaps fortunately, gives them more sensible names):

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)))));
ocaml-logo.png

OCaml

This is my first try:

for i = 0 to 10 do
  let t = truncate ((float i +. 0.5) *. 43200.0 /. 11.0) in
  let h = t / 3600 in
  let m = t mod 3600 in
  Printf.printf ("%02d:%02d:%02d\n") (if h = 0 then 12 else h) (m / 60) (m mod 60)
done;;

There doesn’t seem to be any date formatting functions in the regular, standard, OCaml libraries, but there is a Date module in Batteries Included that will allow you to print the date with the traditional "%I:%M:%S" format string. fsharp-logo.png

F#

For now, I just have the direct version with no special time functions:

for i in 0..10 do
  let t = int ((float i + 0.5) * 43200.0 / 11.0) in
  let h = t / 3600 in
  let m = t % 3600 in
  printfn ("%02d:%02d:%02d") (if h = 0 then 12 else h) (m / 60) (m % 60)
elm-logo.png

Elm

Elm doesn’t really write to the console, so here we produce some HTML:

import Html exposing (text, pre)
import List exposing (map, range, repeat)
import String exposing (padLeft, join)

pad n = padLeft 2 '0' (toString n)

time i =
  let
    t = floor((toFloat i + 0.5) * 43200.0 / 11)
    h = t // 3600
    m = t % 3600
  in
    join ":" (map pad [if (h==0) then 12 else h, m // 60, m % 60])

main =
  range 0 10 |> map time |> join "\n" |> text |> repeat 1 |> pre []
haskell-logo.png

Haskell

This Haskell solution is courtesy of Mike Dillon:

import Text.Printf (printf)

antiParallel :: Int -> (Int,Int,Int)
antiParallel n = (if h == 0 then 12 else h, m, s)
    where t = truncate $ (fromIntegral n + 0.5) * 43200 / 11
          (h, ms) = t `divMod` 3600
          (m, s) = ms `divMod` 60

main = mapM_ (putStrLn . renderTime . antiParallel) [0..10]
    where renderTime (h,m,s) = printf "%02d:%02d:%02d" h m s
lisp-logo.png

Common Lisp

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. A lot of Lisp purists will be really unhappy with the for-loop and demand that it be rewritten with tail recursion, but whatever:

(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)))))
clojure-logo.png

Clojure

Here’s the version without the time functions:

(doseq [i (range 0 11)]
  (let [
    p (int (/ (* (+ i 0.5) 43200.0) 11))
    h (quot p 3600)
    m (rem p 3600)]
    (printf "%02d:%02d:%02d\n" (if (zero? h) 12 h) (quot m 60) (rem m 60))))
erlang-logo.png

Erlang

With the usual direct computation:

% First line is ignored when running with escript
main(_) ->
  lists:foreach(fun (I) ->
    P = trunc((I + 0.5) * 43200 / 11),
    H = trunc(P / 3600),
    M = trunc(P rem 3600),
    io:format("~2..0b:~2..0b:~2..0b~n", [trunc(case H of 0->12;_->H end), trunc(M/60), trunc(M rem 60)])
  end, lists:seq(0,10)).
ada-logo.png

Ada

The shortest solution I could find uses a non-standard package, from the GNU Ada distribution, GNAT:

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..10 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;
fortran-logo.png

Fortran

This one works with Fortran 90 and later. I haven’t learned if there is a nice time formatting function yet.

program antiparallel_clock_hands

    integer :: h, m, t

    do i = 0, 10
        t = int((i + 0.5) * 43200.0 / 11);
        h = t / 3600;
        m = mod(t, 3600);
        if (h == 0) h = 12
        write (*, '(i2.2,":",i2.2,":",i2.2)') h, m / 60, mod(m, 60)
    end do
end
matlab-logo.gif

MATLAB

Thanks to Juan Carrillo for this one:
t = ((0:10)+0.5)*43200/11;
hours = floor(t/3600)+12*(floor(t/3600) == 0);
minutes = floor(mod(t/60,60));
seconds = floor(mod(t,60));
fprintf('%02i:%02i:%02i\n',[hours;minutes;seconds])
julia-logo.jpeg

Julia

This is the direct way:
for i = 0:10
  t = (i + 0.5) * 43200.0 / 11
  h = div(t, 3600)
  m = mod(t, 3600)
  @printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), div(m, 60), mod(m,60))
end
r-logo.png

R

These solutions are courtesy of Sourav Sen Gupta. Here it is in three lines:
t <- ((0:10) + 0.5) * 43200 / 11
f <- format(.POSIXct(t,tz="GMT"), "%I:%M:%S")
write(f, stdout())
And as a nice one-liner:
write(format(.POSIXct(((0:10)+0.5)*43200/11, tz="GMT"), "%I:%M:%S"), stdout())
chapel-logo.png

Chapel

Well, obviously this is not a very good example of how cool Chapel is, but live with it:

for i in 0..10 {
  var t = (((i: real) + 0.5) * 43200.0 / 11.0): int;
  var h = (t / 3600) : int;
  var m = (t % 3600) : int;
  writef("%02i:%02i:%02i\n", if h==0 then 12 else h, m / 60, m % 60);
}
smalltalk-logo.png

Smalltalk

I tested this with the GNU Smalltalk dialect, but should work okay for most dialects. I got some good insights from Leandro Caniglia on Stack Overflow:

0 to: 10 do: [ :i |
  t := ((i + 0.5) * 43200.0 / 11) floor.
  h := t // 3600.
  h = 0 ifTrue: [h := 12].
  m := (t \\ 3600) // 60.
  s := t \\ 60.
  (Transcript show: ({'' . h . m . s} fold: [:r :t |
    pad := t < 10 ifTrue: ['0'] ifFalse: [''].
    colon := r isEmpty ifTrue: [''] ifFalse: [':'].
    r , colon , pad , (t asString)])) nl.]
gprolog-logo.png

Prolog

This solution is due to Matt Brown, and uses GNU Prolog:
antiParallel(N,H,M,S) :-
    T  is floor((N + 0.5) * 43200 / 11),
    H  is floor(T / 3600),
    Ms is mod(T,3600),
    M  is floor(Ms / 60),
    S  is mod(Ms,60).

formatTime(0,M,S) :- formatTime(12,M,S).
formatTime(H,M,S) :- H =\= 0, format('%02d:%02d:%02d\n', [H,M,S]).

clockHands(N) :-
    N =< 10,
    antiParallel(N,H,M,S),
    formatTime(H,M,S),
    N1 is N + 1,
    clockHands(N1).
clockHands(11).
apl-logo.png

APL

This works here. I had help from StackOverflow user MBass on this one.
pad ← {¯2↑,'0',⍕⍵}

time ← {
  H ← ⌊ ⍵ ÷ 3600
  H ← pad (H 12)[H = 0]
  M ← pad ⌊ (3600 | ⍵) ÷ 60
  S ← pad 60 | ⍵
  H,':',M,':',S
}

time¨ 11 1 ⍴ ⌊((⍳ 11) + 0.5) × 43200.0 ÷ 11
php-logo.png

PHP

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 />";
}
bash-logo.png

Bash

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

for i in {0..10}; do
    t=$(echo "scale=6; t=(($i+0.5)*43200/11); scale=0; t/=1; t" | bc)
    h=$((t / 3600))
    m=$((t % 3600))
    printf "%02d:%02d:%02d\n" $((h == 0 ? 12 : h)) $((m / 60)) $((m % 60))
done
gas-logo.png

GAS x86-64 Assembly Language

Not sure why I wasted an hour of my life on this:

         .global  main
         .text
main:
         push      %rdi                   # callee-save registers
         push      %rsi

         xor       %ecx,  %ecx            # ecx will count from 0 to 11
         jmp       test                   # start the loop

next:
         cvtsi2sd  %ecx, %xmm0            # i
         addsd     (half), %xmm0          # (i + 0.5)
         mulsd     (halfday), %xmm0       # (i _ 0.5) * 43200.0
         divsd     (eleven), %xmm0        # xmm0 contains time in seconds
         cvtsd2si  %xmm0, %eax            # eax has time in seconds from midnight
         xor       %edx, %edx
         mov       $3600, %r11
         div       %r11d                  # eax has hours, edx has minutes
         mov       %eax, %esi             # hours will be 2nd arg to printf
         mov       $12, %r11d
         cmp       $0, %esi
         cmovzl    %r11d, %esi            # use '12' rather than '0' for display
         mov       %edx, %eax             # break up total minutes
         xor       %edx, %edx
         mov       $60, %r11d             # eax has minutes, edx has seconds
         div       %r11d                  # eax has minutes, edx has seconds
         push      %rcx                   # save counter AND align stack!
         mov       %edx, %ecx             # seconds is 4th arg to printf
         mov       %eax, %edx             # minutes is 3rd arg to printf
         mov       $format, %edi
         call      printf                 # printf(format, h, m, s)
         pop       %rcx

         inc       %ecx                   # Next hour
test:
         cmp       $11, %ecx              # Done?
         jl        next                   # Nope

         pop       %rsi
         pop       %rdi
         ret

format:  .asciz   "%02d:%02d:%02d\n"
half:    .double  0.5
halfday: .double  43200.0
eleven:  .double  11.0
nasm-logo.png

NASM

This didn’t take too long; I just quickly translated from GAS:

; Antiparallel clockhands
; Targeted to ELF64 binaries only (e.g., not OS X)
;
; nasm -felf64 clockhands.asm && gcc clockhands.o && ./a.out

         global    main
         extern    printf

         section   .text

main:
         push      rdi                   ; callee-save registers
         push      rsi

         xor       ecx, ecx              ; ecx will count from 0 to 11
         jmp       check                 ; start the loop

next:
         cvtsi2sd  xmm0, ecx             ; i
         addsd     xmm0, [half]          ; (i + 0.5)
         mulsd     xmm0, [halfday]       ; (i _ 0.5) * 43200.0
         divsd     xmm0, [eleven]        ; xmm0 contains time in seconds
         cvtsd2si  eax, xmm0             ; eax has time in seconds from midnight
         xor       edx, edx
         mov       r11, 3600
         div       r11d                  ; eax has hours, edx has minutes
         mov       esi, eax              ; hours will be 2nd arg to printf
         mov       r11d, 12
         cmp       esi, 0
         cmovz     esi, r11d             ; use '12' rather than '0' for display
         mov       eax, edx              ; break up total minutes
         xor       edx, edx
         mov       r11d, 60              ; eax has minutes, edx has seconds
         div       r11d                  ; eax has minutes, edx has seconds
         push      rcx                   ; save counter AND align stack!
         mov       ecx, edx              ; seconds is 4th arg to printf
         mov       edx, eax              ; minutes is 3rd arg to printf
         lea       rdi, [format]
         call      printf               ; printf(format, h, m, s)
         pop       rcx

         inc       ecx                   ; Next hour
check:
         cmp       ecx, 11               ; Done?
         jl        next                  ; Nope

         pop       rsi
         pop       rdi
         ret


         section   .data
format:  db        "%02d:%02d:%02d", 10, 0
half:    dq        0.5
halfday: dq        43200.0
eleven:  dq        11.0