12
\$\begingroup\$

Create a BCD binary clock in ASCII. As implied, it shall display time in six columns of dots:

Binary Clock
(source: Wikimedia Commons)

Each column is a binary-coded digit, reading hours, minutes and seconds from left to right. Hours are given in 24-hour format.

The time to display is read from the command-line or from stdin (whichever fits better). If empty, the current time should be used instead.

Output size is a little constrained here and we can only fit two lines of text. So you are required to put the dots into only two lines. The characters ., : and ' come in handy here.

Input

The time to display in ISO-8601 format, i.e. HH:MM:SS without fractional seconds. Mandatory 24-hour format. Input can be empty in which case the current time will be used.

Output

Two lines with represent the BCD binary clock as in the image above. Each line is exactly six characters long and the only allowed characters are space, period, colon and apostrophe.

Winner

Shortest code by byte count wins. In a tie, the solution posted first wins.

Sample input 1

 

(empty)

Sample output 1

     .
''. ::

Sample input 2

17:59:20

Sample output 2

 ..'  
.:..' 

Sample input 3

01:08:01

Sample output 3

   '  
 .   .
\$\endgroup\$

20 Answers 20

5
\$\begingroup\$

Golfscript (+ruby/date) - 46 chars

"#{`date`}"10>+9<" .':":S-.{4/12-S=}%n@{4%S=}%

You can replace `date` with Time.now if necessary (+2 chars).

\$\endgroup\$
1
  • \$\begingroup\$ I knew it was hopeless to even try Golfscripting ;-) \$\endgroup\$
    – Joey
    Feb 27, 2011 at 2:25
5
\$\begingroup\$

Ruby, 107 103 99 94 90 characters

$><<[$/,(gets||Time.now.to_s[11,8]).tr(z=" .':","").bytes.map{|a|$><<z[a/4-12];z[a%4]}]*""

Note that the input shouldn't contain a linebreak, so to test the solution use something like echo -n "01:08:01" | ruby1.9 bcd.rb.

To test the default behavior, run it with ruby1.9 bcd.rb and enter ^D (i.e. a literal EOF).

\$\endgroup\$
2
  • \$\begingroup\$ There's no such thing as a literal EOF! :-) \$\endgroup\$
    – J B
    Mar 4, 2011 at 20:17
  • 1
    \$\begingroup\$ You can shave off 4 characters with Time.now.to_s[11,8]. \$\endgroup\$ May 4, 2011 at 23:15
3
\$\begingroup\$

Windows PowerShell, 81

Since I did not create an implementation when writing the task I feel myself eligible to golf it from the start, too :-)

-join" .':
"[(($d="$(date)$args"[-8..-1]-ne58)|%{($_-band12)/4})+,4+($d|%{$_%4})]

History:

  • 2011-02-26 23:50 (119) First attempt.
  • 2011-02-26 23:55 (108) Inlining fun.
  • 2011-02-27 00:03 (102) Optimized selecting the first line. [Math]::Floor is waaaayy too long. I hate that.
  • 2011-02-27 02:22 (101) I don't need : for the first line.
  • 2011-02-27 02:53   (95) Optimized getting input or current time.
  • 2011-03-04 20:36   (88) Only a single join remains. Indexing every character needed (including the line break) from a single string.
  • 2011-03-04 20:39   (83) Using 58 instead of : which auto-casts to integer as well – no more need to enclose $_ in quotes :-)
  • 2011-03-04 20:42   (81) The parentheses after the -join are no longer necessary.
\$\endgroup\$
3
\$\begingroup\$

Jelly, 21 bytes

o7ŒT¤fØDV€d4Zị“.': ”Y

Try it online!

For the empty input, you can use either an empty string or no argument at all.

Explanation

o7ŒT¤fØDV€d4Zị“.': ”Y   Main monadic or niladic link
o                       Logical or (Python-like)
 7ŒT¤                     Current time in hh:mm:ss format
     f                  Filter
      ØD                  Digits
         €              Each
        V                 Evaluate
          d             Divmod
           4              4
            Z           Zip
             ị          Index into [1-indexed, auto-maps]
              “.': ”      ".': "
                    Y   Join with newlines
\$\endgroup\$
1
  • \$\begingroup\$ Didn't know jelly had a time function. Too bad there's none in Husk. \$\endgroup\$
    – Razetime
    Nov 12, 2020 at 9:40
2
\$\begingroup\$

Ruby - 124 chars

t=*((i=gets)=="
"? Time.now.strftime('%H%M%S'):i).tr(':
','').bytes
puts (0..1).map{|i|t.map{|_|" .':"[i<1? _/4-12:_%4]}*''}
\$\endgroup\$
2
\$\begingroup\$

C#

236 characters

using System;using System.Linq;class X{static void Main(){var d=Console.In.ReadToEnd().Replace(":","");for(int i=0;i<2;i++)Console.WriteLine(string.Join("",(d==""?DateTime.Now.ToString("HHmmss"):d).Select(c=>" .':"[i<1?c/4-12:c%4])));}}

Readable:

using System;
using System.Linq;
class X
{
    static void Main()
    {
        var d = Console.In.ReadToEnd().Replace(":", "");
        for (int i = 0; i < 2; i++)
            Console.WriteLine(string.Join("",
                (d == "" ? DateTime.Now.ToString("HHmmss") : d)
                .Select(c => " .':"[i < 1 ? c / 4 - 12 : c % 4])));
    }
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ There's no need to do - 48 when you are doing % 4, as 48 % 4 == 0 \$\endgroup\$
    – Dogbert
    Feb 27, 2011 at 0:14
  • \$\begingroup\$ @Dogbert: Brilliant, thank you! That also gave me the idea that c/4-12 is shorter than (c-48)/4... :) \$\endgroup\$
    – Timwi
    Feb 27, 2011 at 1:36
  • \$\begingroup\$ You can delete a lot of spaces and tabs too which would get rid of a lot of characters, also think about using the new top level code feature of c# \$\endgroup\$
    – Luke_
    Jul 20, 2021 at 12:16
2
\$\begingroup\$

Golfscript (+ Ruby), 63

."#{Time.now.strftime'%T'}"if':'-:|{4/12-" .':":@\=}%n|{4%@\=}%

Still a beginner with Golfscript. Don't hit me.

\$\endgroup\$
4
  • \$\begingroup\$ There's a few things to shorten (see my answer). Specific to what you have at the moment that isn't in my answer -- brackets can be omitted from ruby function calls, "" coerces to false so you can remove ,\. \$\endgroup\$
    – Nabb
    Feb 27, 2011 at 2:30
  • \$\begingroup\$ @Nabb: Thanks. Well, Ventero already told me he had it down to 63, though I couldn't bring him to tell me how ;-). Still, dragging Ruby into this through the string interpolation feels like cheating, somehow. I think I'll stay with my preferred language below and just try to beat Ruby :-) \$\endgroup\$
    – Joey
    Feb 27, 2011 at 2:33
  • \$\begingroup\$ well since the question required access to the current time, it's not really possible without resorting to ruby anyway \$\endgroup\$
    – gnibbler
    Feb 27, 2011 at 23:48
  • \$\begingroup\$ @gnibbler: I know. Still, it's the only really unportable feature of Golfscript and I don't particularly like using it due to that ;-) \$\endgroup\$
    – Joey
    Feb 28, 2011 at 18:53
2
\$\begingroup\$

Perl (84)

#!perl -pl
$_||=localtime;y/://d;/\d{6}/;$_=$&;y/0-9/    ....''/;$_.="\n$&";y/0-9/ .': .': ./
\$\endgroup\$
2
  • \$\begingroup\$ You can save one character by changing "\n$&" to $/.$& — common Perl-golf trick :) \$\endgroup\$
    – Timwi
    May 6, 2011 at 1:05
  • \$\begingroup\$ @Timwi I could use a real newline there :) \$\endgroup\$ May 7, 2011 at 12:33
2
\$\begingroup\$

Python 3, 136 chars

import time
d=input()
for i in(0,1):print(''.join([" .':"[[c>>2,c&3][i]]for c in map(int,d.replace(':','')or time.strftime('%H%M%S'))]))
\$\endgroup\$
1
  • \$\begingroup\$ I get 137 when I do a wc -c. Good work tho. +1 \$\endgroup\$
    – Kazark
    Aug 18, 2012 at 19:00
2
\$\begingroup\$

VimScript, 143 characters

if getline(1)==''
norm"=strftime("%T")^Mp
en
nm- "ax"=@a/4^MgP
nm, "ax"=@a%4^MgP
norm0YP--x--x--xP^M,,x,,x,,xP
%s/0/ /g
%s/1/./g
%s/2/'/g
%s/3/:/g
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Extended), 45 42 bytes

' .'':'[4 4⊤{×≢⍵:⍎¨⍵~':'⋄,⍉0 10⊤3↑3↓⎕TS}⍞]

Try it online!

A full program submission.

-3 bytes from Bubbler.

Very barely edges out Golfscript (Thanks, Bubbler!).

Explanation

' .'':'[4 4⊤⍎¨{×≢⍵:⍵~':'⋄,⍉ 0 10⊤3↑3↓⎕TS}⍞]
                                        ⍞    string input
              {×≢⍵:                          if length is nonzero:
                   ⍵~':'                     remove ':'s from it
                        ⋄            ⎕TS     otherwise get current time array
                                 3↑3↓        remove yymmdd and take hhmmss
                         ,⍉ 0 10⊤            convert to base 10 digits and transpose, then flatten
                                             (pads with a zero)
            ⍎¨                               convert each character to digit
        4 4⊤                                 encode into base 4 matrix
' .'':'[                                   ] index into string " .':"
\$\endgroup\$
2
\$\begingroup\$

Javascript, 232 165 characters

t=>(a=t.match(/\d/g).map(x=>(+x).toString(2)).flatMap(x=>x.padStart(4).match(/..?/g)).map(x=>" .':"[x%4])).filter((_,i)=>~i&1).join``+`
`+a.filter((_,i)=>i%2).join``

Snippet

(modified because i dont count console.log() and the function assignment/call in the byte count)

f=

// 215
t=>(a=t.match(/\d/g).map(x=>(+x).toString(2)).flatMap(x=>x.padStart(4).match(/..?/g)).map(x=>" .':"[x%4])).filter((_,i)=>~i&1).join``+`
`+a.filter((_,i)=>i%2).join``

console.log(f('17:59:20'))

\$\endgroup\$
2
\$\begingroup\$

Haskell, 192 180 174 166 bytes

-21 characters thanks to @Laikoni

import Data.Time
main=getCurrentTime>>=interact.(\x y->unlines[map(!!i)[mapM(pure" .':")"__"!!(fromEnum e-48)|e<-take 8$y++formatTime undefined"%T"x,e<':']|i<-[0,1]])

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ @Laikoni thank you! i noticed the transpose+unlines can be made shorter too \$\endgroup\$
    – tzlil
    Oct 12 at 22:18
  • \$\begingroup\$ Even shorter transpose: (\x y->(++).(++"\n").map(!!0)<*>map(!!1)$[ ... ]) can be (\x y->unlines[map(!!i)[ ... ]|i<-[0,1]]): Try it online! \$\endgroup\$
    – Laikoni
    Oct 15 at 15:55
1
\$\begingroup\$

Python - 201 172 characters

from time import*
t=raw_input()
if not t:t=strftime('%H:%M:%S')
t=t.replace(':','')
for i in(0,2):print''.join(" .':"[int(bin(int(d))[2:].rjust(4,'0')[i:i+2],2)]for d in t)
\$\endgroup\$
1
  • \$\begingroup\$ How about: t=raw_input().replace(':','') / if not t:t=strftime('%H%M%S') — saves you 5 characters :) \$\endgroup\$
    – Timwi
    Feb 26, 2011 at 23:00
1
\$\begingroup\$

Lua - 163 160 Chars

s=io.read():match"(%S+)"or os.date("%X",os.time())t=" .':"w=io.write for l=1,2 do for k in s:gmatch"(%d)"do y=1+select(l,(k-k%4)/4,k%4)w(t:sub(y,y))end w"\n"end
\$\endgroup\$
1
\$\begingroup\$

VBA (Excel), 150 148 132 bytes

Using Immediate Window and Cell [A1] as input.

a=Format(IIf([a1]="",Now,[a1]),"hhmmss"):b=Split(" ,.,',:",","):For c=1To Len(a):d=Mid(a,c,1):e=e &b(d\4):f=f &b(d Mod 4):Next:?e:?f
\$\endgroup\$
7
  • \$\begingroup\$ The time is given either from the command-line or from stdin. Neither seems to work here. \$\endgroup\$
    – Joey
    Feb 19, 2019 at 8:15
  • \$\begingroup\$ I'm sorry, what do you mean? \$\endgroup\$
    – remoel
    Feb 19, 2019 at 8:27
  • \$\begingroup\$ It's an older task with a fairly stringent input restriction and VBA probably cannot handle input like specified. In terms of the task given, this answer does not solve it as it chooses to ignore part of the requirements. \$\endgroup\$
    – Joey
    Feb 19, 2019 at 8:28
  • 1
    \$\begingroup\$ @remoel, You can improve this answer by bringing the If statement into the [..] notation, and using a non-breaking space instead of a regular space in the split statement (Alt+255), and then by using string addition instead of the string concatenation. Should look like a=Format([IF(A1,A1,NOW())],"hhmmss"):b=Split("  . ' :"):For c=1To Len(a):d=Mid(a,c,1):e=e+b(d\4):f=f+b(d Mod 4):Next:?e:?f, where the first character in the split statement is the nonbreaking space \$\endgroup\$ Feb 19, 2019 at 22:18
  • 1
    \$\begingroup\$ cool tricks of non-breaking space for split function. Learned new things again XD Nice! And Thanks! :D \$\endgroup\$
    – remoel
    Feb 20, 2019 at 6:27
1
\$\begingroup\$

K (ngn/k), 35 bytes

{-1_'" .':"@2/+0 2_2\.'(x^":"),"9"}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Scala, 222:

object C{def main(a:Array[String]){
val t=if(a.length==0)new java.text.SimpleDateFormat("HHmmss").format(new java.util.Date)else a(0).replaceAll(":","")
t.map(c=>print(" ,'"(c/4%4)));println;t.map(c=>print(" ,':"(c%4)))}}
\$\endgroup\$
0
\$\begingroup\$

Dash (SUSv2-compatible?), 202 200 193 169 138 137 bytes

Usage.

  • Requires input from positional argument.
  • Outputs to stdout, without trailing line.

I think I should change the language for golfing off.

Notes about 138 and 137 bytes:

  • May not SUSv2-compatible because it gives floating value to second argument for substr() in AWK.
  • It ran successfully on GAWK.
s='for(;++i<7;){D=substr($0,i,1);printf substr(" .'\'':",(h?D%4:D/4)+1,1)}i=h++'
echo ${1-`date +%H%M%S`}|tr -d :|awk "{$s;$s}"|fold -w 6

Try it online!

\$\endgroup\$
0
\$\begingroup\$

05AB1E, 28 bytes

õQižažbžc)T‰}Sþ4‰ø" .':"sèJ»

Try it online or verify all test cases.

Explanation:

õQi                # If the (implicit) input is empty/absent:
   ža              #  Push the current hours
     žb            #  Push the current minutes
       žc          #  Push the current seconds
         )         #  Wrap all three into a list
          T‰       #  Divmod each by 10 to add leading 0s
  }S               # After the if-statement: convert it to a flattened list of characters
                   # (which will use the implicit input-string if necessary)
    þ              # Only keep all digits to remove potential ":"
     4‰            # Divmod each digit by 4
       ø           # Zip/transpose; swapping rows/columns
        " .':"sè   # Index each into string " .':'
                J  # Join each row of characters together
                 » # Join the lines by newlines
                   # (after which the result is output implicitly)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.