11
\$\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\$

15 Answers 15

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).

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I knew it was hopeless to even try Golfscripting ;-) \$\endgroup\$ – Joey Feb 27 '11 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).

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ There's no such thing as a literal EOF! :-) \$\endgroup\$ – J B Mar 4 '11 at 20:17
  • 1
    \$\begingroup\$ You can shave off 4 characters with Time.now.to_s[11,8]. \$\endgroup\$ – Lars Haugseth May 4 '11 at 23:15
  • \$\begingroup\$ @Lars: Changed it, thanks! \$\endgroup\$ – Ventero May 6 '11 at 17:23
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.
| improve this answer | |
\$\endgroup\$
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]}*''}
| improve this answer | |
\$\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])));
    }
}
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ There's no need to do - 48 when you are doing % 4, as 48 % 4 == 0 \$\endgroup\$ – Dogbert Feb 27 '11 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 '11 at 1:36
2
\$\begingroup\$

Golfscript (+ Ruby), 63

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

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

| improve this answer | |
\$\endgroup\$
  • \$\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 '11 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 '11 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 '11 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 '11 at 18:53
2
\$\begingroup\$

Perl (84)

#!perl -pl
$_||=localtime;y/://d;/\d{6}/;$_=$&;y/0-9/    ....''/;$_.="\n$&";y/0-9/ .': .': ./
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can save one character by changing "\n$&" to $/.$& — common Perl-golf trick :) \$\endgroup\$ – Timwi May 6 '11 at 1:05
  • \$\begingroup\$ @Timwi I could use a real newline there :) \$\endgroup\$ – chinese perl goth May 7 '11 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'))]))
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I get 137 when I do a wc -c. Good work tho. +1 \$\endgroup\$ – Kazark Aug 18 '12 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
| improve this answer | |
\$\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 " .':"
| improve this answer | |
\$\endgroup\$
2
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Didn't know jelly had a time function. Too bad there's none in Husk. \$\endgroup\$ – Razetime Nov 12 at 9:40
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)
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ How about: t=raw_input().replace(':','') / if not t:t=strftime('%H%M%S') — saves you 5 characters :) \$\endgroup\$ – Timwi Feb 26 '11 at 23:00
  • \$\begingroup\$ @Timwi Thanks for that! \$\endgroup\$ – Juan Feb 26 '11 at 23:04
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
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ The time is given either from the command-line or from stdin. Neither seems to work here. \$\endgroup\$ – Joey Feb 19 '19 at 8:15
  • \$\begingroup\$ I'm sorry, what do you mean? \$\endgroup\$ – remoel Feb 19 '19 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 '19 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\$ – Taylor Scott Feb 19 '19 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 '19 at 6:27
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)))}}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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