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 list them, in order, using 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.
In Python, using the time
module:
import time for h in range(0, 11): print(time.strftime('%I:%M:%S', time.gmtime((h+0.5) * 43200.0/11)))
Calculating the time components ourselves:
for i in range(0, 11): t = int((i + 0.5) * 43200.0 / 11) h, t = divmod(t, 3600) m, s = divmod(t, 60) print(f'{(h if h else 12):02}:{m:02}:{s:02}')
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)]'
Thanks to class Time
being built-in, in Ruby, 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 has an os
module with 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'
This Tcl 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 time! 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)'
Here it is in AWK, under the do-it-yourself way:
BEGIN { for (i = 0; i < 11; i++) { t = int((i + 0.5) * 43200.0 / 11) 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) } }
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; }
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 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; }
I only have the do-it yourself version in Rust 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); } }
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) } }
The do-it yourself formatting version:
import Foundation for i in 0..<11 { let t = Int((Double(i) + 0.5) * 43200.0 / 11) let (h, m) = t.quotientAndRemainder(dividingBy: 3600) print(String(format:"%02d:%02d:%02d", arguments:[(h==0 ? 12 : h), m / 60, m % 60])) }
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); } } }
Using the built-in date and time classes:
import java.time.LocalTime; import java.time.format.DateTimeFormatter; public class AntiparallelClockHandsComputer { public static void main(String[] args) { for (var i = 0; i < 11; i++) { var time = LocalTime.MIDNIGHT.plusSeconds(Math.round((0.5+i)*43200.0/11)); System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss"))); } } }
And the direct computation:
public class AntiparallelClockHandsComputer { public static void main(String[] args) { for (var 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); } } }
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); }
I did this Scala one real quick. 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) }
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)``"); }
Here’s my quick Kotlin 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)); } }
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')); }
CoffeScript can use the moment library too:
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])
This one is due to Alex Schneider, who is very good at Dart:
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; }
Standard ML has access to the POSIX time formatting and parsing functions, just with different 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)))));
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;;
I couldn’t find date formatting functions in the standard, OCaml libraries, but there is a
Date
module in Batteries Included
supporting the traditional "%I:%M:%S"
format string.
Here it is in F# 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 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 []
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
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)))))
Here’s the Clojure 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))))
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)).
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;
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 endThanks to Juan Carrillo for this MATLAB script:
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])This is the direct way:
using Printf for i = 0:10 t = trunc((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)) endThese 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())
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); }
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.]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).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, 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 (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
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
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