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 many different languages. We’ll use an algorithm that formats the 12-hour clock times for the number of seconds past midnight as the fractions $\frac{0.5}{11}$, $\frac{1.5}{11}$, $\frac{2.5}{11}$, $\frac{3.5}{11}$, $\frac{4.5}{11}$, $\frac{5.5}{11}$, $\frac{6.5}{11}$, $\frac{7.5}{11}$, $\frac{8.5}{11}$, $\frac{9.5}{11}$, and $\frac{10.5}{11}$ of a 43200-second cycle. This is equivalent to the integer-arithmetic only expression $\frac{43200 i + 21600}{11}$ for $i$ from 0 to 10.
We will generally format the 12-hour time string manually, but if a language has library function for formatting such times, we will provide a second solution for the language employing the library.
We’ll generally write short, comment-free hacks with violations of proper coding styles, just to make the answers short, but not too short. Our goal is to just show snippets of many different languages. For “professionally” golfed (shortened) solutions by brilliant code golfers, see this page on Code Golf and Coding Challenges StackExchange.
for i in range(0, 11): t = (43200 * i + 21600) // 11 h, t = divmod(t, 3600) m, s = divmod(t, 60) print(f'{(h or 12):02}:{m:02}:{s:02}')
import time for i in range(0, 11): print(time.strftime('%I:%M:%S', time.gmtime((43200 * i + 21600) // 11)))
0.upto 10 do |i| t = (43200 * i + 21600) / 11 h, t = t.divmod 3600 m, s = t.divmod 60 printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), m, s) end
0.upto(10) do |i| puts((Time.gm(0) + (43200 * i + 21600) / 11).strftime('%I:%M:%S')) end
for i = 0, 10 do local t = (43200 * i + 21600) // 11 local h, m, s = t // 3600, t // 60 % 60, t % 60 print(string.format("%02d:%02d:%02d", (h == 0 and 12 or h), m, s)) end
for i = 0, 10 do print(os.date("!%I:%M:%S", (43200 * i + 21600) // 11)) end
Here’s the PHP script itself; you’ll of course need to embed it in <php
and ?>
delimiters in real life:
for ($i = 0 ; $i < 11 ; $i++){ $t = floor((43200 * $i + 21600) / 11); $h = floor($t / 3600); $m = floor($t / 60) % 60; $s = $t % 60; echo sprintf("%02d:%02d:%02d\n", ($h == 0) ? 12 : $h, $m, $s); }
for ($i = 0; $i < 11; $i++) { echo gmstrftime("%I:%M:%S", (43200 * $i + 21600) / 11) . "<br />"; }
for {set i 0} {$i < 11} {incr i} { set t [expr (43200 * $i + 21600) / 11] set h [expr $t / 3600] set m [expr $t / 60 % 60] set s [expr $t % 60] puts [format "%02d:%02d:%02d" [expr {$h == 0 ? 12 : $h}] $m $s] }
Thanks to B.J. Johnson for this one.
for {set i 0} {$i < 11} {incr i} { puts [clock format [expr (43200 * $i + 21600) / 11] -format %I:%M:%S] }
for my $i (0..10) { my $t = int((43200 * $i + 21600) / 11); my ($h, $m, $s) = (int($t / 3600), int($t / 60) % 60, $t % 60); printf("%02d:%02d:%02d\n", ($h || 12), $m, $s); }
use POSIX 'strftime'; print strftime("%I:%M:%S", gmtime((43200 * $_ + 21600) / 11))."\n" for (0..10);
BEGIN { for (i = 0; i < 11; i++) { t = int((43200 * i + 21600) / 11) h = int(t / 3600) m = int(t / 60) % 60 s = t % 60 printf "%02d:%02d:%02d\n", (h ? h : 12), m, s } }
BEGIN { for (i = 0; i < 11; i++) { print strftime("%I:%M:%S", (43200 * i + 21600) / 11, 1) } }
#!/usr/bin/env bash for i in {0..10}; do t=$(( (43200 * i + 21600) / 11 )) h=$((t / 3600)) m=$((t / 60 % 60)) s=$((t % 60)) printf "%02d:%02d:%02d\n" $((h == 0 ? 12 : h)) $((m)) $((s)) done
#!/usr/bin/env zsh for i in $(seq 0 10); do t=$(( (43200 * i + 21600) / 11 )) h=$((t / 3600)) m=$((t / 60 % 60)) s=$((t % 60)) printf "%02d:%02d:%02d\n" $((h == 0 ? 12 : h)) $m $s done
#!/usr/bin/env fish for i in (seq 0 10) set t (math floor \(\(43200 x $i + 21600\) / 11\)) set h (math floor $t / 3600 ) set m (math floor $t / 60 % 60) set s (math $t % 60) if test $h -eq 0 set h 12 end printf "%02d:%02d:%02d\n" $h $m $s end
foreach ($i in 0..10) { $t = [int][Math]::Floor((43200 * $i + 21600) / 11) $h = [int][Math]::Floor($t / 3600) $m = [int][Math]::Floor($t / 60) % 60 $s = $t % 60 "{0:D2}:{1:D2}:{2:D2}" -f (($h -eq 0)? 12 : $h), $m, $s }
foreach ($i in 0..10) { Get-Date -UnixTimeSeconds ([int][Math]::Floor((43200 * $i + 21600) / 11)) -AsUTC -Format "hh:mm:ss" }
#include <stdio.h> int main() { for (int i = 0; i < 11; i++) { int t = (43200 * i + 21600) / 11; int h = t / 3600, m = t / 60 % 60, s = t % 60; printf("%02d:%02d:%02d\n", (h ? h : 12), m, s); } return 0; }
Calling gmtime
returns a pointer to some statically allocated memory somewhere that may be overwritten on subsequent calls, so you have to use your values right away. Then there is need to allocate a buffer for the formatted time string, which has to be 9 bytes, not 8, to make room for the 0 byte at the end of the string.
#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)((43200 * i + 21600) / 11); strftime(s, 9, "%I:%M:%S", gmtime(&t)); printf("%s\n", s); } 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 = (43200 * i + 21600) / 11; int h = t / 3600, m = t / 60 % 60, s = t % 60; cout << setfill('0') << setw(2) << (h ? h : 12) << ':' << setw(2) << m << ':' << setw(2) << s << endl; } return 0; }
import core.stdc.stdio; int main() { for (int i = 0; i < 11; i++) { int t = (43200 * i + 21600) / 11; int h = t / 3600, m = t / 60 % 60, s = t % 60; printf("%02d:%02d:%02d\n", (h ? h : 12), m, s); } return 0; }
fn main() { for i in 0..11 { let t = (43200 * i + 21600) / 11; let (h, m, s) = (t / 3600, t / 60 % 60, t % 60); println!("{:02}:{m:02}:{s:02}", if h == 0 {12} else {h}); } }
const print = @import("std").debug.print; pub fn main() void { for (0..11) |i| { const t = (43200 * i + 21600) / 11; const h = t / 3600; const m = t / 60 % 60; const s = t % 60; print("{d:0>2}:{d:0>2}:{d:0>2}\n", .{ if (h == 0) 12 else h, m, s}); } }
package main import "fmt" func main() { for i := 0; i < 11; i++ { t := (43200 * i + 21600) / 11 h, m, s := t / 3600, t / 60 % 60, t % 60 if h == 0 { h = 12 } fmt.Printf("%02d:%02d:%02d\n", h, m, s) } }
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 11; i++ {
t := int64((43200 * i + 21600) / 11)
fmt.Println(time.Unix(t, 0).UTC().Format("03:04:05"))
}
}
package main import "core:fmt" import "core:math" main :: proc() { for i in 0..=10 { t := (43200 * i + 21600) / 11 h, m, s := t / 3600, t / 60 % 60, t % 60 fmt.printf("%02d:%02d:%02d\n", 12 if h == 0 else h, m, s) } }
use core {printf} main :: () { for i in 0 ..= 10 { t: i32 = (43200 * i + 21600) / 11; h, m, s: i32 = t / 3600, t % 3600 / 60, t % 60 printf("{w2}:{w2}:{w2}\n", 12 if h == 0 else h, m, s); } }
fn main() { for i in 0 .. 11 { t := (43200 * i + 21600) / 11 h, m, s := t / 3600, t / 60 % 60, t % 60 println('${(if h == 0 { 12 } else { h }):02}:${m:02}:${s:02}') } }
import time fn main() { for i in 0 .. 11 { t := (43200 * i + 21600) / 11 println(time.unix(t).custom_format("hh:mm:ss")) } }
import std/strformat for i in 0..10: let t = (43200 * i + 21600) div 11 let h = t div 3600 let m = (t div 60) mod 60 let s = t mod 60 echo &"{(if h == 0: 12 else: h):02}:{m:02}:{s:02}"
using StringTools; class ClockHands { public static function main():Void { for (i in 0...11) { var t = Math.floor((43200 * i + 21600) / 11); var h = Math.floor(t / 3600); var m = Math.floor(t / 60) % 60; var s = t % 60; var pad = function(n:Int) return '${n}'.lpad("0", 2); haxe.Log.trace('${pad((h == 0) ? 12 : h)}:${pad((m))}:${pad(s)}', null); } } }
using DateTools; class ClockHands { public static function main():Void { for (i in 0...11) { var time = Date.fromTime((43200000 * i + 21600000) / 11 + Date.now().getTimezoneOffset() * 60000); haxe.Log.trace((DateTools.format(time, "%I:%M:%S")), null); } } }
var sprintf = $loader.loadprim("std@sprintf", 2) var i = 0 while (i < 11) { var t = $int((43200 * (i ++= 1) + 21600) / 11) var h = $int(t / 3600) var m = $int(t / 60) % 60 var s = t % 60 $print(sprintf("%0.2d:%0.2d:%0.2d\n", $array(if (h == 0) 12 else h, m, s))) }
import Foundation for i in 0 ..< 11 { let t = (43200 * i + 21600) / 11 let (h, a) = t.quotientAndRemainder(dividingBy: 3600) let (m, s) = a.quotientAndRemainder(dividingBy: 60) print(String(format:"%02d:%02d:%02d", arguments:[(h == 0 ? 12 : h), m, s])) }
using System; public class AntiparallelClockHandsComputer { public static void Main() { for (var i = 0; i < 11; i++) { var t = (43200 * i + 21600) / 11; (var h, var m, var s) = (t / 3600, t / 60 % 60, t % 60); Console.WriteLine("{0:00}:{1:00}:{2:00}", (h != 0 ? h : 12), m, s); } } }
public class AntiparallelClockHandsComputer { public static void main(String[] args) { for (var i = 0; i < 11; i++) { int t = (43200 * i + 21600) / 11; int h = t / 3600, m = t / 60 % 60, s = t % 60; System.out.printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), m, s); } } }
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((43200 * i + 21600) / 11); System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss"))); } } }
(0..10).each {i -> int t = (43200 * i + 21600) / 11 int h = t / 3600 int m = t / 60 % 60 int s = t % 60 println String.format("%02d:%02d:%02d", (h == 0 ? 12 : h), m, s) }
@main def clockhands() = for i <- 0 to 10 do val t = (43200 * i + 21600) / 11 val h = t / 3600 val m = t / 60 % 60 val s = t % 60 println(f"${if (h == 0) then 12 else h}%02d:${m}%02d:${s}%02d")
import java.time.LocalTime import java.time.format.DateTimeFormatter @main def clockhandsTime() = for i <- 0 to 10 do val time = LocalTime.MIDNIGHT.plusSeconds((43200 * i + 21600) / 11) println(DateTimeFormatter.ofPattern("hh:mm:ss").format(time))
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)``"); }
fun main(args: Array<String>) { for (i in 0..10) { val t = (43200 * i + 21600) / 11 val h = t / 3600 val m = t / 60 % 60 val s = t % 60 println(String.format("%02d:%02d:%02d", if (h==0) 12 else h, m, s)) } }
void main() { for (int i = 0; i < 11; i++) { int t = (int)((i + 0.5) * 43200 / 11); int h = t / 3600; int a = t % 3600; int m = a / 60; int s = a % 60; stdout.printf("%02d:%02d:%02d\n", h == 0 ? 12 : h, m, s); } }
0.upto 10 do |i| t = (43200 * i + 21600) / 11 h, t = t.divmod 3600 m, s = t.divmod 60 printf("%02d:%02d:%02d\n", (h == 0 ? 12 : h), m, s) end
def pad(n): return if n < 10: "0{n}" else: "{n}" for (11) i: let t = (43200 * i + 21600) / 11 var h = t / 3600 let m = t / 60 % 60 let s = t % 60 if h == 0: h = 12 print "{pad(h)}:{pad(m)}:{pad(s)}"
for (local i = 0 ; i < 11 ; i++) { local t = (43200 * i + 21600) / 11 local h = t / 3600 local m = t / 60 % 60 local s = t % 60 printf("%02d:%02d:%02d\n", h || 12, m, s) }
for (local i = 0 ; i < 11 ; i++) { local t = (43200 * i + 21600) / 11 printf("%02d:%02d:%02d\n", date(t, 'u').hour || 12, date(t).min, date(t).sec) }
const pad = (n) => `${n}`.padStart(2, "0") for (let i = 0; i < 11; i++) { const t = Math.floor((43200 * i + 21600) / 11) const [h, m, s] = [Math.floor(t / 3600), Math.floor(t / 60) % 60, t % 60] console.log(`${pad(h || 12)}:${pad(m)}:${pad(s)}`) }
for (let i = 0; i < 11; i++) { console.log(new Date((43200000 * i + 21600000) / 11). toISOString().substring(11, 19). replace(/^00/, '12')) }
It is a best practice to annotate function parameters, otherwise they get an implicit any
type.
const pad = (n: number) => `${n}`.padStart(2, "0") for (let i = 0; i < 11; i++) { const t = Math.floor((43200 * i + 21600) / 11) const [h, m, s] = [Math.floor(t / 3600), Math.floor(t / 60) % 60, t % 60] console.log(`${pad(h || 12)}:${pad(m)}:${pad(s)}`) }
pad = (n) -> "#{n}".padStart(2, "0") for i in [0..10] t = Math.floor (43200 * i + 21600) / 11 [h, m, s] = [(Math.floor t / 3600), (Math.floor t / 60) % 60, t % 60] console.log "#{pad(h || 12)}:#{pad m}:#{pad s}"
(console.log new Date((i+0.5)*43200000/11). toISOString().substring(11,19). replace(/^00/,'12') for i in [0..10])
pad = (n) -> "#{n}".padStart(2, "0") for i from 0 to 10 t = Math.floor (43200 * i + 21600) / 11 [h, m, s] = [(Math.floor t / 3600), (Math.floor t / 60) % 60, t % 60] console.log "#{pad(h || 12)}:#{pad m}:#{pad s}"
for i from 0 to 10 new Date(Math.floor((43200000 * i + 21600000) / 11)). toISOString().substring(11, 19). replace(/^00/, '12') |> console.log
void main() { String pad(int n) => n.toString().padLeft(2, '0'); for (int i = 0; i < 11; i++) { int t = (43200 * i + 21600) ~/ 11; int h = t ~/ 3600; int m = t ~/ 60 % 60; int s = t % 60; print('${pad(h == 0 ? 12 : h)}:${pad(m)}:${pad(s)}'); } }
using System.Console; def pad (n : int) { match (n) { | x when x < 10 => $"0$x"; | x => $"$x"; } } foreach (i in $[0..10]) { def t = (43200 * i + 21600) / 11; def h = t / 3600; def m = t / 60 % 60; def s = t % 60; WriteLine($"$(pad(if (h == 0) 12 else h)):$(pad(m)):$(pad(s))"); }
This works with the MLton command line compiler:
fun format_time i = let val pad = fn n => (if n < 10 then "0" else "") ^ Int.toString n val t = (43200 * i + 21600) div 11 val (h, m, s) = (t div 3600, t div 60 mod 60, t mod 60) in pad (if h = 0 then 12 else h) ^ ":" ^ pad m ^ ":" ^ pad s ^ "\n" end val _ = map print (List.tabulate (11, format_time))
This also uses MLton:
val _ = map print (List.tabulate(11, fn i => ((Date.fmt "%I:%M:%S\n" o Date.fromTimeUniv o Time.fromReal o real)( (43200 * i + 21600) div 11))));
for i = 0 to 10 do let t = (43200 * i + 21600) / 11 in let (h, m, s) = (t / 3600, t / 60 mod 60, t mod 60) in Printf.printf ("%02d:%02d:%02d\n") (if h = 0 then 12 else h) m s done;;
for i = 0 to 10 do let t = (43200 * i + 21600) / 11 let (h, m, s) = (t / 3600, t / 60 % 60, t % 60) printfn "%02d:%02d:%02d" (if h = 0 then 12 else h) m s
module ClockHands from "number" include Number let pad = (n) => if (n < 10) "0" ++ toString(n) else toString(n) for (let mut i = 0; i <= 10; i += 1) { let t = Number.trunc((43200 * i + 21600) / 11) let h = Number.trunc(t / 3600) and m = Number.trunc(t / 60) % 60 and s = t % 60 print(pad(if (h == 0) 12 else h) ++ ":" ++ pad(m) ++ ":" ++ pad(s)) }
import gleam/int import gleam/io import gleam/list import gleam/string pub fn main() { let pad = fn(n: Int) { string.pad_start(int.to_string(n), 2, "0") } list.range(0, 10) |> list.map(fn (i) { let t = {43200 * i + 21600} / 11 let h = t / 3600 let m = t / 60 % 60 let s = t % 60 let h = case h { 0 -> 12 _ -> h } io.println(pad(h) <> ":" <> pad(m) <> ":" <> pad(s)) }) }
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' (String.fromInt n) time i = let t = (43200 * i + 21600) // 11 h = t // 3600 m = modBy 60 (t // 60) s = modBy 60 t in join ":" (map pad [if (h==0) then 12 else h, m, s]) main = range 0 10 |> map time |> join "\n" |> text |> repeat 1 |> pre []
import Text.Printf (printf) formatted :: (Int, Int, Int) -> String formatted (h, m, s) = printf "%02d:%02d:%02d" h m s antiParallel :: Int -> (Int, Int, Int) antiParallel n = (if h == 0 then 12 else h, m, s) where t = (43200 * n + 21600) `div` 11 (h, t') = t `divMod` 3600 (m, s) = t' `divMod` 60 main = mapM_ (putStrLn . formatted . antiParallel) [0..10]
def printTimes : List (IO Unit) → IO Unit | [] => pure () | act :: actions => do printTimes actions act def pad : Nat → String | n + 10 => s!"{n + 10}" | n => s!"0{n}" def clock (t : Nat) : String := s!"{pad (if t / 3600 == 0 then 12 else t / 3600)}:{pad (t / 60 % 60)}:{pad (t % 60)}" def countdown : Nat → List (IO Unit) | 0 => [] | n + 1 => IO.println (clock ((43200 * (n) + 21600) / 11)) :: countdown n def main : IO Unit := printTimes (countdown 11)
(loop for i from 0 below 11 do (let* ((p (floor (+ (* i 43200) 21600) 11)) (h (floor p 3600)) (m (mod (floor p 60) 60)) (s (mod p 60))) (format t "~2,'0d:~2,'0d:~2,'0d~%" (if (zerop h) 12 h) m s)))
(for ([i 11]) (define t (floor (/ (+ (* 43200 i) 21600) 11))) (define-values (h m s) (values (floor (/ t 3600)) (remainder (floor (/ t 60)) 60) (remainder t 60))) (printf "~a:~a:~a~n" (~a (if (= h 0) 12 h) #:width 2 #:align 'right #:left-pad-string "0") (~a m #:width 2 #:align 'right #:left-pad-string "0") (~a s #:width 2 #:align 'right #:left-pad-string "0")))
(doseq [i (range 0 11)] (let [ t (quot (+ (* i 43200) 21600) 11) h (quot t 3600) m (rem (quot t 60) 60) s (rem t 60)] (printf "%02d:%02d:%02d\n" (if (zero? h) 12 h) m s)))
The quick and dirty approach is inefficient because it generates all of the times in a list:
% First line is ignored when running with escript main(_) -> lists:foreach(fun (I) -> T = (43200 * I + 21600) div 11, [H, M, S] = [T div 3600, M = T div 60 rem 60, S = T rem 60], io:format( "~2..0b:~2..0b:~2..0b~n", [(case H of 0 -> 12; _ -> H end), M, S]) end, lists:seq(0, 10)).
% First line is ignored when running with escript main(_) -> times(0, 10). times(10, _) -> ok; times(I, N) -> T = (43200 * I + 21600) div 11, [H, M, S] = [T div 3600, M = T div 60 rem 60, S = T rem 60], io:format( "~2..0b:~2..0b:~2..0b~n", [(case H of 0 -> 12; _ -> H end), M, S]), times(I + 1, N).
Elixir has lazy ranges, so the short version is efficient:
Enum.each 0..10, fn i -> t = div(43200 * i + 21600, 11) [h, m, s] = [div(t, 3600), rem(div(t, 60), 60), rem(t, 60)] IO.puts to_string( :io_lib.format("~2..0b:~2..0b:~2..0b", [if h == 0 do 12 else h end, m, s])) end
import ballerina/io; public function main() { foreach int i in 0...10 { int t = (43200 * i + 21600) / 11; int h = t / 3600; int m = t % 3600; io:println((h == 0 ? "12" : h.toString().padZero(2)) + ":" + (m / 60).toString().padZero(2) + ":" + (m % 60).toString().padZero(2)); } }
with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure Antiparallel_Clock_Hands is T, H, M, S : Integer; procedure Show(N: Integer) is begin if n < 10 then Put("0"); end if; Put(N, 0); end Show; begin for I in 0 .. 10 loop T := (43200 * I + 21600) / 11; H := T / 3600; M := (T / 60) mod 60; S := T mod 60; H := (if H = 0 then 12 else H); Show(H); Put(":"); Show(M); Put(":"); Show(S); New_Line; end loop; end Antiparallel_Clock_Hands;
program antiparallel_clock_hands integer :: i, t, h, m, s do i = 0, 10 t = (43200 * i + 21600) / 11 h = t / 3600 m = mod(t / 60, 60) s = mod(t, 60) if (h == 0) h = 12 write (*, '(i2.2,":",i2.2,":",i2.2)') h, m, s end do end
Thanks to Juan Carrillo for this MATLAB script. This program works both in MATLAB and the related language Octave.
t = ((0:10) * 43200 + 21600) / 11; h = floor(t / 3600) + 12 * (floor(t / 3600) == 0); m = floor(mod(t / 60, 60)); s = floor(mod(t, 60)); fprintf('%02i:%02i:%02i\n',[h; m; s])
t = ((0:10) * 43200 + 21600) / 11;
clock = datetime(t,'ConvertFrom','posixtime');
clock.Format = 'hh:mm:ss';
fprintf('%s\n', clock);
t <- floor((43200 * 0:10 + 21600) / 11) h <- floor(t / 3600) + 12 * (floor(t / 3600) == 0) m <- floor(t / 60) %% 60 s <- t %% 60 cat(paste(gettextf("%02d:%02d:%02d", h, m, s), collapse = "\n"))
write(format(.POSIXct(((0:10)*43200+21600)/11, tz="GMT"), "%I:%M:%S"), stdout())
using Printf seconds(i) = div(43200 * i + 21600, 11) zeroTo12(h) = h == 0 ? 12 : h parts(t) = (zeroTo12(div(t, 3600)), rem(div(t, 60), 60), rem(t, 60)) 0:10 .|> seconds .|> parts .|> t -> @printf("%02d:%02d:%02d\n", t...)
using Dates for i = 0:10 t = div(43200 * i + 21600, 11) println(Dates.format(Dates.unix2datetime(t),"II:MM:SS")) end
This one works with GnuCOBOL 3.2.
IDENTIFICATION DIVISION.
PROGRAM-ID. ClockHands.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 I PIC 9(2).
01 T FLOAT-LONG.
01 H PIC 9(2).
01 M PIC 9(2).
01 S PIC 9(2).
PROCEDURE DIVISION.
PERFORM VARYING I FROM 0 BY 1 UNTIL I >= 11
COMPUTE T = (43200 * I + 21600) / 11
DIVIDE T BY 3600 GIVING H REMAINDER T
DIVIDE T BY 60 GIVING M REMAINDER S
IF H EQUAL TO 0 SET H TO 12 END-IF
DISPLAY H, ":", M, ":", S
END-PERFORM.
STOP RUN.
Tested with the Genie compiler:
FOR i FROM 0 TO 10
DO INT t := (43200 * i + 21600) % 11;
INT h := t % 3600;
INT m := t % 60 %* 60;
INT s := t %* 60;
printf (($2d$, (h = 0 | 12 | h), $a$, ":", $2d$, m, $a$, ":", $2dl$, s))
OD
This solution uses the Free Pascal Compiler (fpc).
uses sysutils;
var
i, t, h, m, s : longint;
begin
for i := 0 to 10 do
begin
t := (43200 * i + 21600) div 11;
h := t div 3600;
m := t div 60 mod 60;
s := t mod 60;
if h = 0 then h := 12;
WriteLn(Format('%0.02d:%0.02d:%0.02d', [h, m, s]));
end;
end.
Since Chapel is all about parallelism, here’s a version that computes all the time strings concurrently (since it uses forall
rather than for
), then prints them in order:
use IO.FormattedIO; var times: [0..10] string; forall i in 0..10 { var t = (43200 * i + 21600) / 11; var h = t / 3600; var m = t / 60 % 60; var s = t % 60; times[i] = "%02i:%02i:%02i".format(if h == 0 then 12 else h, m, s); } for time in times { writeln(time); }
For a problem of this size, the sequential version will probably be faster.
def pad(n) -> String: return ("0{}" if n < 10 else "{}").format(n) def main(): for i in range(11): t = (43200 * i + 21600) // 11 h, t = divmod(t, 3600) m, s = divmod(t, 60) print("{}:{}:{}".format(pad(h or 12), pad(m), pad(s)))
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 := 43200 * i + 21600 // 11. h := t // 3600. h = 0 ifTrue: [h := 12]. m := t // 60 \\ 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.]
pad := method(n, if(n < 10, "0", "") .. n asString) for (i, 0, 10, t := ((43200 * i + 21600) / 11) floor h := (t / 3600) floor m := (t / 60) floor % 60 s := t % 60 (pad(if(h == 0, 12, h)) .. ":" .. pad(m) .. ":" .. pad(s)) println )
for (i, 0, 10, Date fromNumber((43200 * i + 21600) / 11 + Date gmtOffsetSeconds) asString("%I:%M:%S") println)
Thanks to Wesley Ng for this one.
{ :i >> t := ((i - 0.5) × 43200 ÷ 11) floor. >> h := (t ÷ 3600) floor. >> m := ((t ÷ 3600) modulo: 60) floor. >> s := t modulo: 60. h = 0 true: { h := 12.}. >> pad := { :n <- (n < 10 either: ['0'] or: ['']) + n.}. Out write: (pad apply: h) + [':'] + (pad apply: m) + [':'] + (pad apply: s) + ['\n']. } × 11.
pour chaque 11 t prend sol ((43200 * joker + 21600) / 11) h prend sol (t / 3600) m prend sol (t / 60) mod 60 s prend t mod 60 si (non h), h prend 12 affiche remplir (h) + ":" + remplir (m) + ":" + remplir (s) ferme remplir : y si (y < 10) retourne "0" + y sinon retourne y sol : x retourne x - x mod 1
import std::io import string from std::ascii function build_clock(int h, int m, int s) -> string: return ['0' + (h / 10), '0' + (h % 10), ':', '0' + (m / 10), '0' + (m % 10), ':', '0' + (s / 10), '0' + (s % 10)] public export method main(): int i = 0 while i < 11: int t = ((43200 * i) + 21600) / 11 int h = t / 3600 int m = (t / 60) % 60 int s = t % 60 if h == 0: h = 12 io::println(build_clock(h, m, s)) i = i + 1
Download this file to load into a Scratch workspace for execution.
extends SceneTree func _init(): for i in 11: var t = (43200 * i + 21600) / 11 var h = t / 3600 var m = t / 60 % 60 var s = t % 60 print("%02d:%02d:%02d" % [h if h else 12, m, s]) quit()
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), M is mod(floor(T / 60), 60), S is mod(T, 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).
module ClockHands;
integer i, t, h, m, s;
function reg [1:2*8] pad;
input integer n;
reg [1:2*8] format;
begin
format[1:8] = n / 10 + 48;
format[9:16] = n % 10 + 48;
pad = format;
end
endfunction
initial begin
for (i = 0 ; i < 11 ; i++) begin
t = (43200 * i + 21600) / 11;
h = t / 3600;
m = t / 60 % 60;
s = t % 60;
$display("%s:%s:%s", pad(h ? h : 12), pad(m), pad(s));
end
end
endmodule
: time-calc ( i -- h m s ) 43200 * 21600 + 11 / 3600 /mod swap ( -- h t ) 60 /mod rot ( -- s m h ) dup 0= if drop 12 then ; : two-digits ( n -- ) 0 <# # # #> type ; : antiparallel-clock-hands ( -- ) 11 0 do i time-calc two-digits ." :" two-digits ." :" two-digits cr loop ; antiparallel-clock-hands
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
pad: {$(x%10), $(x!10)} getTimes: {((pad(:[0=(x%3600); 12; x%3600])), ":", (pad(x%60)!60), ":", (pad(x!60)), "\n")} `0: ,//(getTimes' (((43200 * !11) + 21600) % 11))
Tested with Postgres 15:
WITH RECURSIVE nums(i) AS (
SELECT 0
UNION ALL
SELECT i + 1 FROM nums WHERE i < 10
)
SELECT
TO_CHAR(
MAKE_INTERVAL(secs := (43200 * i + 21600) / 11) + INTERVAL '0 second',
'HH12:MI:SS'
) AS formatted_time
FROM nums;
This solution was written by Wesley Ng. You can run the script here:
J60VhTK.D/*^J3+.5N55*JJ%P*"%02d:"3.n[|hK12.D.)KJ
Thanks to Wesley Ng for this CJam script:
B,0Bt{"%02d:"3*\[.5+43200*B/m[3600md60md]e%8Nt}/
Another Wesley Ng original:
60UT>LÁ.5+X3m*55÷Xn‰vy¤X‰1ǝ˜T‰J':ý,
Contributed by Wesley Ng:
60#=①›ɾ↻1½+#$³×55∻#$²‰#$‰(|n⎘ᐕ①‰“':j,
Run it here.
HAI 1.3 HOW IZ I PAD YR N DIFFRINT N AN BIGGR OF N AN 10, O RLY? YA RLY, FOUND YR SMOOSH "0" N MKAY NO WAI, FOUND YR N OIC IF U SAY SO IM IN YR CLOCK UPPIN YR I TIL BOTH SAEM I AN 11 I HAS A T ITZ QUOSHUNT OF SUM OF PRODUKT OF 43200 AN I AN 21600 AN 11 I HAS A H ITZ QUOSHUNT OF T AN 3600 I HAS A M ITZ MOD OF QUOSHUNT OF T AN 60 AN 60 I HAS A S ITZ MOD OF T AN 60 BOTH SAEM H AN 0, O RLY? YA RLY, H R 12 OIC H R I IZ PAD YR H MKAY M R I IZ PAD YR M MKAY S R I IZ PAD YR S MKAY VISIBLE ":{H}:::{M}:::{S}" IM OUTTA YR CLOCK KTHXBYE
Wesley Ng’s solution:
Another contribution by Esolang expert Wesley Ng.
v >:25*/68*+,25*%68*+v
0 v ,+*86%*52< | `9:< ,
#>:25*/68*+,^ >"0",86*+,# v
>:889355******489355*****+74+/::28955****/:|
+v*25< # v,+*< 86%*52< v$ <
1, v < v 8>:25*/68*+,^ >"21",,v
|:#!<^<|` 9:%**652,":"<>,6^|`9:%**652/**652,":"<
@>9`^ ^>#<"0",68*+^ ^"0"<
Courtey of Wesley Ng.
Thanks, Wesley!
' " " 1 0 ' ' 5
~ " ꣀ } = * { 呠 '
/ " * } & = { & = {
\ > & " : ! % ! ' ; }
\ = : { = & } = % ' & "
& " % ' & " : ! % ! } \ .
} & 1 " 1 * } } { { ; < $ @
8 } } { { 1 1 ~ } 1 1 . \ . .
+ { * 1 1 ' : " * & \ \ " +
2 1 * ' : ' ฐ { { < . . .
{ { * ' 1 & " ~ & 6 0 {
: ! % ! ' ; } { } { \
_ . . . . . . . . \
> . . . . . . - =
. . . . . . . .
Run the code here.
Wesley does it again:
-----------[[+>->-<<]>>[+<<->>]<+++++++++++>>++++++++++++++++++++++++[>+++++++<-]
++++++++++++++++++++++++++++++++[>>++++++<<-]<<[->+>+<<]>[-<+>]>[->>[->+>>+>+[->+
>+<<]>[-<+>]>[<<<->>>[-]]<<<<<<]>[-<+>]<<<]<<[->+>+<<]>[-<+>]>[->[->>+>+>+[->>+>+
<<<]>>[-<<+>>]>[<<<<->>>>[-]]<<<<<<<]>>[-<<+>>]<<<]>[-]>[-]++++++++++++++[>++++++
<-]>[->+>+[->>+>+<<<]>>[-<<+>>]>[<<<<->>>>[-]]<<<<<]<++++++++++++++++[>++++++<-]>
[->>[->>+>+<<<]>>[-<<+>>]>[<<<<+>>>>[-]]<<<+>+[->+>+<<]>[-<+>]>[<<<->>>[-]]<<<[->
>+>+<<<]>>[-<<+>>]>[<<<<->>>>[-]]<<<<<]<<<+++++++++++[[->+>+>+<<<]>[-<+>]>[->>>>>
+<<<<<]>>[->>>>+>+<<<<<]>>>>>[-<<<<<+>>>>>]<[>-<[-]]>+<<<<[->>>+>>+<<<<<]>>>>>[-<
<<<<+>>>>>]<<<[->[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>[-]++[->-<]>[>-<[-]]>+[<
<<<<<<[-]<<<[-]>>>>>>>>>>[-]]<<<<<<<[->->[->>+>+<<<]>>>[-<<<+>>>]<[<<<+>>>[-]]<<-
<<<+>]<[>>>>>>>>>>+<<<<<<<<<<[-]]<<]+++++++++++[[->+>+>+<<<]>[-<+>]>[->>>>>+<<<<<
]>>>[->>>+>+<<<<]>>>>[-<<<<+>>>>]<[>-<[-]]>+<<<[->>+>>+<<<<]>>>>[-<<<<+>>>>]<<<[-
>[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>[-]++[->-<]>[>-<[-]]>+[<<<<<<<[-]<<<[-]>
>>>>>>>>>[-]]<<<<<<<[->>->[->+>+<<]>>[-<<+>>]<[<<+>>[-]]<-<<<<+>]<[>>>>>>>>>>>+<<
<<<<<<<<<[-]]<<]>>>>>>[-]>++++++++++[->++++++<]>[[->+>+>+<<<]>[-<+>]>[->>>>+<<<<]
>>[->>>+>+<<<<]>>>>[-<<<<+>>>>]<<-[->[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>[-]>
[<<<<<[-]<<<[-]>>>>>>>>[-]]<<<<<[->-<<+>]<[>>>>>>>>>+<<<<<<<<<[-]]<<]<++++++++++[
->++++++<]>[[->+>+>+<<<]>[-<+>]>[->>>>+<<<<]>>[->>>+>+<<<<]>>>>[-<<<<+>>>>]<[>-<[
-]]>+<<<[->>+>>+<<<<]>>>>[-<<<<+>>>>]<<<[->[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<
]>[-]++[->-<]>[>-<[-]]>+[<<<<<<[-]<<<[-]>>>>>>>>>[-]]<<<<<<[->->[->+>+<<]>>[-<<+>
>]<[<<+>>[-]]<-<<<+>]<[>>>>>>>>>>+<<<<<<<<<<[-]]<<]>>>>>[-<<<<<<<<<<+>>>>>>>>>>]>
>>>>>[-<<<<<<<+>>>>>>>]>[-<<<<<<<+>>>>>>>]<<<<<<<<<<<<<++++++++++[->++++++<]>[[->
+>+>+<<<]>[-<+>]>[->>>>+<<<<]>>[->>>+>+<<<<]>>>>[-<<<<+>>>>]<[>-<[-]]>+<<<[->>+>>
+<<<<]>>>>[-<<<<+>>>>]<<<[->[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>[-]++[->-<]>[
>-<[-]]>+[<<<<<<[-]<<<[-]>>>>>>>>>[-]]<<<<<<[->->[->+>+<<]>>[-<<+>>]<[<<+>>[-]]<-
<<<+>]<[>>>>>>>>>+<<<<<<<<<[-]]<<]>>>>>>>>>>>[->+>+<<]>[>------------<[-]]>++++++
++++++<<<<++++++++++[[->+>+>+<<<]>[-<+>]>[->>>+<<<]>>[->>+>+<<<]>>>[-<<<+>>>]<<[-
>[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>[-]>[<<<<[-]<<<[-]>>>>>>>[-]]<<<<[->-<<+
>]<[>>>>>>>>+<<<<<<<<[-]]<<]>>>>>>>>>++++++++[->++++++<]>.[-]<<<<<++++++++[-<++++
++>]<.[-]++++++++++[->++++++<]>--.[-]<<<<<<<<<<<<<++++++++++[[->+>+>+<<<]>[-<+>]>
[->>>+<<<]>>[->>+>+<<<]>>>[-<<<+>>>]<<[->[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>
[-]>[<<<<[-]<<<[-]>>>>>>>[-]]<<<<[->-<<+>]<[>>>>>>>>+<<<<<<<<[-]]<<]>>>>>>>>>++++
++++[->++++++<]>.[-]<<<<<++++++++[-<++++++>]<.[-]++++++++++[->++++++<]>--.[-]<<<<
<<<<<<<<<<<++++++++++[[->+>+>+<<<]>[-<+>]>[->>>+<<<]>>[->>+>+<<<]>>>[-<<<+>>>]<<[
->[->>+>+<<<]>>>[-<<<+>>>]<[<->[-]]<+<-<]>[-]>[<<<<[-]<<<[-]>>>>>>>[-]]<<<<[->-<<
+>]<[>>>>>>>>+<<<<<<<<[-]]<<]>>>>>>>>>++++++++[->++++++<]>.[-]<<<<<++++++++[-<+++
+++>]<.[-]++++++++++.[-]<<<<<[-]<+]
Check out an annoted version of this program at PLE.
A solution by, you guessed it, Wesley Ng:
.-#0->--*--------\ /---*-------*---*-----*---*-----\
/#1[+] *-#43200[*] /[-] *-#3600[/] *-#60[/] \-#60[%]
| | *-#21600[+] \-\-\ | *-\ | *-\ |
| | *-#11---[/] /#1[%]| \-#1---[%]| *-#1-[%]| |
~---*--*--#10\ \--*---*-/ /-/-/ | /-/-/ |
\--{>}-------/ \[-] | \[-] |
/-----------------------------------/ \-#60[%] |
| /---\ /-----\ | |
*-~#12>-*---*-~$_"0">*$_# | |
\-/ \#9{<}/ \$_":" | |
/-----------------------------------------/ |
| /------\ |
*---*-~-$_"0">*$_# |
\#9{<}/ \$_":" |
/-------------------------------------------/
| /-----\
*---*-~$_"0">$#
\#9{<}/
Run the program here.
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