# Build an analog clock

Write a program which displays the current system time as an analog clock, using ASCII graphics. The clock must show at least the hour and minute pointers, and must have enough resolution of at least 5 minutes.

The display can be as small and as ugly as you wish, but the shown time should be easily recognizable.

The program has to run continuously and update its status. If your system can clear the screen, use it, otherwise it's enough to repaint the clock when its state changes.

You get a -20% bonus on the character count if the clock has at least a 1 minute resolution.

-
When you say analog clock do you mean the usual one or any form of analog rappresentation of time? – Marco Martinelli Feb 25 '13 at 19:08
Extra bonus for 1 second resolution? – Shmiddty Feb 25 '13 at 20:10
Is that "get a -20% bonus" for real? Shouldn't it be... positive? – Timtech Nov 27 '13 at 20:46
@Timtech : if you really want it, I could add 20% to your character count... – vsz Nov 27 '13 at 20:47
@vsz What do you mean ;? – Timtech Nov 27 '13 at 21:13

# Mathematica 207 - 42 = 165

The ticks and hour labels are placed on the unit circle. `H` and `M` revolve around the clock center showing the whole number of completed hours and minutes, respectively. `S` updates its position several times each second.

Two versions are shown: a version that plots text in the Cartesian plane, and another that displays text characters in a grid.

This version plots the characters into the Cartesian plane.

``````d = Dynamic; t = Table; x = Text;i_~u~k_ := {Sin[2 \[Pi] i/k], Cos[2 \[Pi] i/k]};
d[{f = Date[], Clock[{1, 1}, 1]}]
Graphics[d@{t[x[".", u[i, 60]], {i, 60}],t[x[i, u[i, 12]], {i, 12}],
x["H", .7 u[f〚4〛, 12]],x["M", .8 u[f〚5〛, 60]],x["S", .9 u[f〚6〛, 60]]}]
``````

The clock below shows the time 3:08:17.

Terminal or Grid Version: 430 316 chars (253 with bonus discount)

This version works much the same, but places the characters in a 61 x 61 cell grid rather than in the Cartesian plane. It could still be golfed a bit, but I merely wanted to show a (sloppier) terminal-like output in Mathematica.

``````d = Dynamic; i_~u~k_ := Round /@ (10 {Sin[2 \[Pi] (i + 3 k/4)/k],
Cos[2 \[Pi] (i + 3 k/4)/k]}); d[{f = Date[], Clock[]}]
z = Round /@ (# u[f[[#2]], #3] + 11) -> #4 &;
t = Table[( u[i, 12] + 11) -> i, {i, 12}];
d@Grid[ReplacePart[ConstantArray["", {21, 21}],
Join[z @@@ {{.9, 5, 60, "M"}, {.8, 4, 12, "H"}},
DeleteCases[Table[( u[i, 60] + 11) -> "*", {i, 60}], x_ /; MemberQ[t[[All, 1]], x[[1]]]], t]]]
``````

The clock below displays 11:06.

Just for fun:

Here's a non-Ascii version of the analog clock. (60 chars) No external libraries were used.

``````Dynamic@Refresh[ClockGauge@AbsoluteTime[], UpdateInterval -> 1]
``````

-
Doesn't look like ASCII art to me. – Joe Z. Feb 23 '13 at 20:22
I followed the definition given in Wikipedia: "ASCII art is a graphic design technique that uses computers for presentation and consists of pictures pieced together from the 95 printable (from a total of 128) characters defined by the ASCII Standard from 1963 and ASCII compliant character sets with proprietary extended characters (beyond the 128 characters of standard 7-bit ASCII). The term is also loosely used to refer to text based visual art in general." – DavidC Feb 23 '13 at 20:27
Hmm. I suppose that works. I expect that vsz was expecting terminal art, though. Perhaps he can clarify. – Joe Z. Feb 23 '13 at 20:28

## Python, 328 - 65 = 263

Prints a new clock every second, with the minute hand updating every minute.

``````import math,time
def p(t,r):c[int(25-r*math.cos(t))][int(25+r*math.sin(t))]='*'
while 1:
time.sleep(1);c=[[' ']*50 for i in range(50)];t=time.localtime();h=t.tm_hour*6.283+t.tm_min/9.549
for i in range(999):
p(i/158.0,24);p(h,i*.02);p(h/12,i*.01)
for q in range(12):p(q/1.91,24-i*.005)
for y in range(50):print''.join(c[y])
``````

The clocks it prints look like this (it's not as stretched in my terminal):

``````                  **************
****      *     ****
***         *        ***
***           *          ***
** **          *         ** **
**   *                    *   **
**    **                  **    **
*       *                  *      **
**                                  **
**                                    **
**                                      **
*                                        *
***                                      ***
* ***                                  *** *
**   **                                **   **
*                                            *
*                                            *
**                                            **
*                                              *
*   *                                          *
*   ******                                     *
*        ******                                *
*             ******                           *
*                  *****                       *
*****                   *                  ******
*                       **                     *
*                        **                    *
*                         *                    *
*                         **                   *
*                          **                  *
**                          **                **
*                           *                *
*                           *                *
**   **                                **   **
* ***                                  *** *
***                                      ***
*                                        *
**                                      **
**                                    **
**                                  **
*       *                  *       *
**    **                  **    **
**   *                    *   **
** **          *         ** **
***           *          ***
***         *        ***
****      *     ****
**************
*
``````
-
How does one read off the seconds? – DavidC Feb 24 '13 at 13:23
One doesn't. It prints every second but only updates every minute. – cardboard_box Feb 24 '13 at 13:49

## Javascript 370 - 74 = 296

http://jsfiddle.net/wBKQ6/7/

(This only works in Chrome because I'm abusing the fact that element IDs are added to the global scope).

``````(function loop(){
M=Math;p=M.PI/2;z=M.pow;q=M.sqrt;d=new Date();h=(d.getHours()%12/3*p+p)%(p*4);m=(d.getMinutes()/15*p+p)%(p*4);s=(d.getSeconds()/15*p+p)%(p*4);e=49;o='';

for(r=0;r<99;r++){
for(c=0;c<99;c++){
d=q(z(r-e,2)+z(c-e,2));
a=(M.atan2(e-r,e-c)+p*4)%(p*4);
E=(d<e*.8&&M.abs(m-a)*d<.5) || (d<e*.5&&M.abs(h-a)*d<.5) || (d<e*1&&M.abs(s-a)*d<.5);
o+=d-e>0||d<1||E||(e-d<5&&a%p==0)?'●':'○';
//■□●○
}
o+='\n';
}
O.innerText=o
setTimeout(loop,1000);
})()
``````

Golfed (370):

``````!function L(){p=M.PI/2;q=p*4;P=M.pow;d=new Date();s=(d.getSeconds(S=d.getMinutes(e=40))/15*p+p)%q;m=(S/15*p+p)%q;h=(d.getHours(A=M.abs)%12/3*p+S/180*p+p)%q;for(r=o='';r<81;r++,o+='\n')for(c=0;c<81;){d=M.sqrt(P(r-e,2)+P(c-e,2));a=(M.atan2(e-r,e-c++)+q)%q;o+='○●'[d-e>0|d<e*.8&A(m-a)*d<1|d<e/2&A(h-a)*d<1|d<e&A(s-a)*d<1|e-d<5&a%p==0]}O.innerText=o;setTimeout(L,9)}(M=Math)
``````

Sample Output (much more condensed in demo):

``````●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●○○○○○○●○○○○○○●●●●●●●●●●●●●●
●●●●●●●●●●●●○○○○○○○○●○○○○○○○○●●●●●●●●●●●●
●●●●●●●●●●○○○○○○○○○○●○○○○○○○○○○●●●●●●●●●●
●●●●●●●●○○○○○○○○○○○○●○○○○○○○○○○○○●●●●●●●●
●●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●
●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●
●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○●○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○○●●○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○○○○●
●●●●●○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○●●●●●
●○○○○○○○○○○○○○○○○○○●○●○○○○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○○●○○●○○○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○●○○○○●●○○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○○●○○○○○●●○○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○○●○○○○○○○●●○○○○○○○○○○○○○●
●○○○○○○○○○○○○○○○●●○○○○○○○○●●○○○○○○○○○○○○●
●●○○○○○○○○○○○○○○●○○○○○○○○○○○●○○○○○○○○○○●●
●●○○○○○○○○○○○○○●○○○○○○○○○○○○○●○○○○○○○○○●●
●●●○○○○○○○○○○○○●○○○○○○○○○○○○○○●○○○○○○○●●●
●●●○○○○○○○○○○○●○○○○○○○○○○○○○○○○●○○○○○○●●●
●●●●○○○○○○○○○○●○○○○○○○○○○○○○○○○○●○○○○●●●●
●●●●○○○○○○○○○●○○○○○○○○○○○○○○○○○○○●●○○●●●●
●●●●●○○○○○○○●●○○○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●
●●●●●●●○○○○○○○○○○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●●●○○○○○○○○○○○○●○○○○○○○○○○○○●●●●●●●●
●●●●●●●●●●○○○○○○○○○○●○○○○○○○○○○●●●●●●●●●●
●●●●●●●●●●●●○○○○○○○○●○○○○○○○○●●●●●●●●●●●●
●●●●●●●●●●●●●●○○○○○○●○○○○○○●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
``````
-
I could probably bring the score below 263 if I remove the second hand, but I like it! – Shmiddty Feb 26 '13 at 0:31
Smiley faces like to be clocks too: jsfiddle.net/wBKQ6/17/show/light – Shmiddty Feb 26 '13 at 17:25
the fiddle isnt working... – tryingToGetProgrammingStraight Oct 21 '13 at 17:23
@tryingToGetProgrammingStraight It's working for me in Chrome 30 – Shmiddty Oct 21 '13 at 18:21
im running firefox 24.0, just tried it in chrome - it worked, i can only change my vote if you edit... – tryingToGetProgrammingStraight Oct 21 '13 at 19:33

## 100% pure bash only! Without fork!

A finalized and upgraded version could be found there or on this page: ascii-clock for geeks. But don't use it! Read the note at end of this answer, you've been warned! Use this perl version instead!

### First simple clock without second tick.

Scalable and editable:

``````time 2>&1 /tmp/asci-art.sh 10 10 10
. . . 12. . .
11.               . 1
.                       .
.                           .
.                               .
10                                  2
.     H                           M .
.                                       .
.                                       .
.                                       .
9                                       3
.                                       .
.                                       .
.                                       .
.                                   .
8                                   4
.                               .
.                           .
.                       .
7 .               . 5
. . . 6 . . .

real    0m0.356s
user    0m0.348s
sys     0m0.004s
``````

Draw a 21x21 (10x2+1) clock at 10H10 in less than one second.

This accept 3 arguments: `Usage: ascii-clock.sh [ray of clock] [Hour] [Min]` where default ray is 12, clock drawing is `2 x ray + 1` lines height and double width because of space added to try to obtain a round shape.

If the script is called with `0` or `1` argument, it will loop to redraw each minute. Else if at least Hour (second param) is specified, It will draw only once and exit.

The `H` marker is located at 70% of ray and the `M` marker is located at 90% of ray.

No use of external binaries like `date` or `bc` for the draw!

(Thanks to @manatwork for the builtin `read -t` in place if `/bin/sleep`).

So all this is done by builtin shell commands.

It use ANSI sequence, but only for loop and to make markers bold.

``````#!/bin/bash
# Analog clock in Ascii-Art written in BASH V4.2 +=

RAY=\${1:-12} NowH=\$2 NowM=\$3

sqrt() {
local -a _xx=(600000 200000)
local _x1=\${_xx[\$((\$1&1))]} _x0=1
while [ \$_x0 -ne \$_x1 ] ;do
_x0=\$_x1
[ \$_x0 -eq 0 ] && _x1=0000 ||
printf -v _x1 "%u" \$(( (\${_x0}000 + \${1}00000000000/\${_x0} )/2 ))
printf -v _x1 "%.0f" \${_x1:0:\${#_x1}-3}.\${_x1:\${#_x1}-3}
done
_x1=0000\$_x1
printf \${2+-v} \$2 "%.3f" \${_x1:0:\${#_x1}-4}.\${_x1:\${#_x1}-4}
}
clksin() { # \$1:moment [0-60], \$2:path length, \$3:variable name
local _csin=(0 104528 207912 309017 406737 500000 587785 669131
743145 809017 866025 913545 951057 978148 994522 1000000)
local xsign=1 x=\$1 ysign=-1 y=\$1
[ \$x -gt 30 ] && xsign=-1 x=\$((60-x))
[ \$x -gt 15 ] && x=\$((30-x))
x=00000\$((RAY*1000000+xsign*\${2:-10}*\${_csin[\$x]}))
[ \$y -gt 30 ] && y=\$((60-y))
[ \$y -gt 15 ] && ysign=1 y=\$((30-y))
y=00000\$((RAY*1000000+ysign*\${2:-10}*\${_csin[15-\$y]}))
printf \${3+-v} \$3 "%.0f %.0f" \
\${y:0:\${#y}-6}.\${y:\${#y}-6} \${x:0:\${#x}-6}.\${x:\${#x}-6}
};

MLEN=000\$((900*RAY))
printf -v MLEN "%.0f" \${MLEN:0:\${#MLEN}-3}.\${MLEN:\${#MLEN}-3}
HLEN=000\$((700*RAY))
printf -v HLEN "%.0f" \${HLEN:0:\${#HLEN}-3}.\${HLEN:\${#HLEN}-3}

declare -A ticks
for ((i=1;i<=12;i++));do
clksin \$((5*(i%12))) \$RAY tick
ticks[\$tick]=\$i
done

while :;do
[ "\$NowM" ] || printf -v NowM "%(%M)T\n" -1
clksin \${NowM#0} \$MLEN NowM
[ "\$NowH" ] || printf -v NowH "%(%H)T\n" -1
clksin \$((5*(\${NowH#0}%12))) \$HLEN NowH

[ "\$2" ] || echo -en \\e[H; # ANSI sequence for top left of console
for ((i=0;i<=2*RAY;i++));do
x=\$((RAY-i))
sqrt \$((RAY**2 - \${x#-}**2 )) y0
printf -v y0 "%.0f" \$y0
for ((l=0;l<=2*RAY;l++));do
y=\$((RAY-l));
sqrt \$((RAY**2 - \${y#-}**2 )) x0
printf -v x0 "%.0f" \$x0
if [ "\${ticks["\$i \$l"]}" ] ;then
printf "%-2s" \${ticks["\$i \$l"]}
elif [ \${x#-} -eq \$x0 ] || [ \${y#-} -eq \$y0 ] ;then
echo -n .\
elif [ "\$i \$l" = "\$NowM" ] ;then
echo -en \\e[1mM\ \\e[0m
elif [ "\$i \$l" = "\$NowH" ] ;then
echo -en \\e[1mH\ \\e[0m
else
echo -n \ \
fi
done
echo -e \\e[K
done
echo -en \\e[J
[ "\$2" ] && break # Exit if at least Hour was specified
printf -v SleepS "%(%S)T" -1
unset NowH NowM
done
``````

This could by run as:

``````for time in 10:10 15:00 12:30 06:00 09:15 16:40 ;do
echo - \$time -{,}{,}{,}
./ascii-clock.sh 5 \${time//:/ }
echo -{,,,,,}{,}
done |
sed 's/\o033\[\(.m\|[JK]\)//g;/-\$/!s/\$/|/;s/-\$/+/' |
column -c 80
``````

This will produce something like:

``````+- 10:10 - - - - - - - + - 12:30 - - - - - - - + - 09:15 - - - - - - - +
|      . . 12. .       |       . . 12. .       |       . . 12. .       |
|    11          1     |     11    H     1     |     11          1     |
|  10              2   |   10              2   |   10              2   |
|.   H           M   . | .                   . | .                   . |
|.                   . | .                   . | .                   . |
|9                   3 | 9                   3 | 9 H               M 3 |
|.                   . | .                   . | .                   . |
|.                   . | .                   . | .                   . |
|  8               4   |   8               4   |   8               4   |
|    7           5     |     7     M     5     |     7           5     |
|      . . 6 . .       |       . . 6 . .       |       . . 6 . .       |
+- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +
+- 15:00 - - - - - - - + - 06:00 - - - - - - - + - 16:40 - - - - - - - +
|      . . 12. .       |       . . 12. .       |       . . 12. .       |
|    11    M     1     |     11    M     1     |     11          1     |
|  10              2   |   10              2   |   10              2   |
|.                   . | .                   . | .                   . |
|.                   . | .                   . | .                   . |
|9                 H 3 | 9                   3 | 9                   3 |
|.                   . | .                   . | .                   . |
|.                   . | .                   . | .   M           H   . |
|  8               4   |   8               4   |   8               4   |
|    7           5     |     7     H     5     |     7           5     |
|      . . 6 . .       |       . . 6 . .       |       . . 6 . .       |
+- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +
``````

Or could be run as:

``````xterm -geom 86x44 -bg black -fg grey -e ./ascii-clock.sh 21 &

xterm -geom 103x52 -fn nil2 -bg black -fg grey -e ./ascii-clock.sh 25 &

gnome-terminal --geometry 103x52 --zoom .5 -e "./ascii-clock.sh 25" &
``````

### Alternative: With full path drawing:

``````#!/bin/bash
# Analog clock in Ascii-Art written in BASH V4.2 +=

RAY=\${1:-12} NowH=\$2 NowM=\$3

sqrt() {
local -a _xx=(600000 200000)
local _x1=\${_xx[\$((\$1&1))]} _x0=1
while [ \$_x0 -ne \$_x1 ] ;do
_x0=\$_x1
[ \$_x0 -eq 0 ] && _x1=0000 ||
printf -v _x1 "%u" \$(( (\${_x0}000 + \${1}00000000000/\${_x0} )/2 ))
printf -v _x1 "%.0f" \${_x1:0:\${#_x1}-3}.\${_x1:\${#_x1}-3}
done
_x1=0000\$_x1
printf \${2+-v} \$2 "%.3f" \${_x1:0:\${#_x1}-4}.\${_x1:\${#_x1}-4}
}
clksin() { # \$1:moment [0-60], \$2:path length, \$3:variable name
local _csin=(0 104528 207912 309017 406737 500000 587785 669131
743145 809017 866025 913545 951057 978148 994522 1000000)
local xsign=1 x=\$1 ysign=-1 y=\$1
[ \$x -gt 30 ] && xsign=-1 x=\$((60-x))
[ \$x -gt 15 ] && x=\$((30-x))
x=00000\$((RAY*1000000+xsign*\${2:-10}*\${_csin[\$x]}))
[ \$y -gt 30 ] && y=\$((60-y))
[ \$y -gt 15 ] && ysign=1 y=\$((30-y))
y=00000\$((RAY*1000000+ysign*\${2:-10}*\${_csin[15-\$y]}))
printf \${3+-v} \$3 "%.0f %.0f" \
\${y:0:\${#y}-6}.\${y:\${#y}-6} \${x:0:\${#x}-6}.\${x:\${#x}-6}
};

MLEN=000\$((900*RAY))
printf -v MLEN "%.0f" \${MLEN:0:\${#MLEN}-3}.\${MLEN:\${#MLEN}-3}
HLEN=000\$((700*RAY))
printf -v HLEN "%.0f" \${HLEN:0:\${#HLEN}-3}.\${HLEN:\${#HLEN}-3}

declare -A ticks
for ((i=1;i<=12;i++));do
clksin \$((5*(i%12))) \$RAY tick
ticks[\$tick]=\$i
done

while :;do
[ "\$NowM" ] || printf -v NowM "%(%M)T\n" -1
unset MPath
declare -A MPath
for ((i=1;i<=MLEN;i++));do
clksin \${NowM#0} \$i tick
MPath[\$tick]=M
done
[ "\$NowH" ] || printf -v NowH "%(%H)T\n" -1
unset HPath
declare -A HPath
for ((i=1;i<=HLEN;i++));do
clksin \$((5*(\${NowH#0}%12))) \$i tick
HPath[\$tick]=H
done

[ "\$2" ] || echo -en \\e[H; # ANSI sequence for top left of console
for ((i=0;i<=2*RAY;i++));do
x=\$((RAY-i))
sqrt \$((RAY**2 - \${x#-}**2 )) y0
printf -v y0 "%.0f" \$y0
for ((l=0;l<=2*RAY;l++));do
y=\$((RAY-l));
sqrt \$((RAY**2 - \${y#-}**2 )) x0
printf -v x0 "%.0f" \$x0
if [ "\${MPath["\$i \$l"]}" ] ;then
echo -en \\e[1m\${MPath["\$i \$l"]}\ \\e[0m
elif [ "\${HPath["\$i \$l"]}" ] ;then
echo -en \\e[1m\${HPath["\$i \$l"]}\ \\e[0m
elif [ "\${ticks["\$i \$l"]}" ] ;then
printf "%-2s" \${ticks["\$i \$l"]}
elif [ \${x#-} -eq \$x0 ] || [ \${y#-} -eq \$y0 ] ;then
echo -n .\
else
echo -n \ \
fi
done
echo -e \\e[K
done
echo -en \\e[J
[ "\$2" ] && break # Exit if at least Hour was specified
printf -v SleepS "%(%S)T" -1
unset NowH NowM
done
``````

could produce:

``````+- 10:10 - - - - - - - + - 12:30 - - - - - - - + - 09:15 - - - - - - - +
|      . . 12. .       |       . . 12. .       |       . . 12. .       |
|    11          1     |     11    H     1     |     11          1     |
|  10              2   |   10      H       2   |   10              2   |
|.   H           M   . | .         H         . | .                   . |
|.   H H H   M M M   . | .         H         . | .                   . |
|9                   3 | 9                   3 | 9 H H H H   M M M M 3 |
|.                   . | .         M         . | .                   . |
|.                   . | .         M         . | .                   . |
|  8               4   |   8       M       4   |   8               4   |
|    7           5     |     7     M     5     |     7           5     |
|      . . 6 . .       |       . . 6 . .       |       . . 6 . .       |
+- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +
+- 15:00 - - - - - - - + - 06:00 - - - - - - - + - 16:40 - - - - - - - +
|      . . 12. .       |       . . 12. .       |       . . 12. .       |
|    11    M     1     |     11    M     1     |     11          1     |
|  10      M       2   |   10      M       2   |   10              2   |
|.         M         . | .         M         . | .                   . |
|.         M         . | .         M         . | .                   . |
|9           H H H H 3 | 9                   3 | 9                   3 |
|.                   . | .         H         . | .   M M M   H H H   . |
|.                   . | .         H         . | .   M           H   . |
|  8               4   |   8       H       4   |   8               4   |
|    7           5     |     7     H     5     |     7           5     |
|      . . 6 . .       |       . . 6 . .       |       . . 6 . .       |
+- - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - +
``````

or

``````                                . . . . 12. . . .
. . .                   . . .
. .                               . .
. 11                                      1 .
.                                               .
.                                                   .
.                                                       .
.                                                           .
.                                                               .
.                                                                   .
10                                                                  2
.                                                                   M   .
.                                                             M M M     .
.             H                                               M             .
.               H H                                       M M               .
.                   H                                   M                   .
.                       H H H                       M M M                       .
.                             H                   M                             .
.                               H H           M M                               .
.                                   H       M                                   .
9                                     H   M                                     3
.                                                                               .
.                                                                               .
.                                                                               .
.                                                                               .
.                                                                           .
.                                                                           .
.                                                                           .
.                                                                       .
.                                                                       .
8                                                                   4
.                                                                   .
.                                                               .
.                                                           .
.                                                       .
.                                                   .
.                                               .
. 7                                       5 .
. .                               . .
. . .                   . . .
. . . . 6 . . . .
``````

### Last version with Seconds ticks rendering and nanosleep to sync.

This work only on recent Linux, as this use `/proc/timer_list` to compute fraction of second to sleep between each refresh.

``````#!/bin/bash
# Analog clock in Ascii-Art written in BASH V4.2 +=

RAY=\${1:-12} NowH=\$2 NowM=\$3

# Hires Sleep Until
# there is a need to store offset in a static var

mapfile  </proc/timer_list _timer_list
for ((_i=0;_i<\${#_timer_list[@]};_i++));do
[[ \${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_SKIP=\$_i
[[ \${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
TIMER_LIST_OFFSET=\${_timer_list[_i]//[a-z.: ]} && \
break
done
unset _i _timer_list

sleepUntilHires() {
local slp tzoff now quiet=false nsnow nsslp
local hms=(\${1//:/ })
mapfile -n 1 -s \$TIMER_LIST_SKIP nsnow </proc/timer_list
printf -v now '%(%s)T' -1
printf -v tzoff '%(%z)T\n' \$now
nsnow=\$((\${nsnow//[a-z ]}+TIMER_LIST_OFFSET))
nsslp=\$((2000000000-10#\${nsnow:\${#nsnow}-9}))
tzoff=\$((0\${tzoff:0:1}(3600*\${tzoff:1:2}+60*\${tzoff:3:2})))
slp=\$(( ( 86400 + ( now - now%86400 ) +
10#\$hms*3600+10#\${hms[1]}*60+10#\${hms[2]} -
tzoff - now - 1
) % 86400)).\${nsslp:1}
}

sqrt() {
local -a _xx=(600000 200000)
local _x1=\${_xx[\$((\$1&1))]} _x0=1
while [ \$_x0 -ne \$_x1 ] ;do
_x0=\$_x1
[ \$_x0 -eq 0 ] && _x1=0000 ||
printf -v _x1 "%u" \$(( (\${_x0}000 + \${1}00000000000/\${_x0} )/2 ))
printf -v _x1 "%.0f" \${_x1:0:\${#_x1}-3}.\${_x1:\${#_x1}-3}
done
_x1=0000\$_x1
printf \${2+-v} \$2 "%.3f" \${_x1:0:\${#_x1}-4}.\${_x1:\${#_x1}-4}
}
clksin() { # \$1:moment [0-60], \$2:path length, \$3:variable name
local _csin=(0 104528 207912 309017 406737 500000 587785 669131
743145 809017 866025 913545 951057 978148 994522 1000000)
local xsign=1 x=\$1 ysign=-1 y=\$1
[ \$x -gt 30 ] && xsign=-1 x=\$((60-x))
[ \$x -gt 15 ] && x=\$((30-x))
x=00000\$((RAY*1000000+xsign*\${2:-10}*\${_csin[\$x]}))
[ \$y -gt 30 ] && y=\$((60-y))
[ \$y -gt 15 ] && ysign=1 y=\$((30-y))
y=00000\$((RAY*1000000+ysign*\${2:-10}*\${_csin[15-\$y]}))
printf \${3+-v} \$3 "%.0f %.0f" \
\${y:0:\${#y}-6}.\${y:\${#y}-6} \${x:0:\${#x}-6}.\${x:\${#x}-6}
};

SLEN=000\$((870*RAY))
printf -v SLEN "%.0f" \${SLEN:0:\${#SLEN}-3}.\${SLEN:\${#SLEN}-3}
MLEN=000\$((780*RAY))
printf -v MLEN "%.0f" \${MLEN:0:\${#MLEN}-3}.\${MLEN:\${#MLEN}-3}
HLEN=000\$((650*RAY))
printf -v HLEN "%.0f" \${HLEN:0:\${#HLEN}-3}.\${HLEN:\${#HLEN}-3}

declare -A ticks
for ((i=1;i<=12;i++));do
clksin \$((5*(i%12))) \$RAY tick
ticks[\$tick]=\$i
done

while :;do
[ "\$NowM" ] || printf -v NowM "%(%M)T\n" -1
unset MPath
declare -A MPath
for ((i=1;i<=MLEN;i++));do
clksin \${NowM#0} \$i tick
MPath[\$tick]=M
done
[ "\$NowH" ] || printf -v NowH "%(%H)T\n" -1
unset HPath
declare -A HPath
for ((i=1;i<=HLEN;i++));do
clksin \$((5*(\${NowH#0}%12))) \$i tick
HPath[\$tick]=H
done
printf -v NowS "%(%S)T\n" -1
clksin \${NowS#0} \$SLEN STick

[ "\$2" ] || echo -en \\e[H; # ANSI sequence for top left of console
for ((i=0;i<=2*RAY;i++));do
x=\$((RAY-i))
sqrt \$((RAY**2 - \${x#-}**2 )) y0
printf -v y0 "%.0f" \$y0
for ((l=0;l<=2*RAY;l++));do
y=\$((RAY-l));
sqrt \$((RAY**2 - \${y#-}**2 )) x0
printf -v x0 "%.0f" \$x0
if [ "\$i \$l" = "\$STick" ] ;then
echo -en \\e[1ms\ \\e[0m
elif [ "\${MPath["\$i \$l"]}" ] ;then
echo -en \\e[1m\${MPath["\$i \$l"]}\ \\e[0m
elif [ "\${HPath["\$i \$l"]}" ] ;then
echo -en \\e[1m\${HPath["\$i \$l"]}\ \\e[0m
elif [ "\${ticks["\$i \$l"]}" ] ;then
printf "%-2s" \${ticks["\$i \$l"]}
elif [ \${x#-} -eq \$x0 ] || [ \${y#-} -eq \$y0 ] ;then
echo -n .\
else
echo -n \ \
fi
done
echo -e \\e[K
done
echo -en \\e[J
[ "\$2" ] && break # Exit if at least Hour was specified
printf -v SleepS "%(%s)T" -1
printf -v SleepS "%(%T)T" \$((1+SleepS))
sleepUntilHires \$SleepS
unset NowH NowM
done
``````

### More obfuscated version (2702 bytes):

As requested by @manatwork, there is a more golfed version.

This version is colorized and present digital time on corners.

``````#!/bin/bash
W=/proc;J=\${1:-12} B=\$2 A=\$3 LANG=C R=\$W/timer_list;if [ -f \$R ];then Q=10
mapfile <\$R e;for ((P=0;P<\${#e[@]};P++));do ((Q+=\${#e[P]}));[[ \${e[P]} =~ ^now
]]&&U=\$Q;[[ \${e[P]} =~ offset:.*[1-9] ]]&&a=\${e[P]//[a-z.: ]}&&break;done;c(){
local q p;read -N\$U q <\$R;q=\${q%% nse*};q=\$[\${q##* }+a];p=\$[2000000000-10#\${q:
-10#\${H#*.}];read -t .\${H:1} M;};fi;u(){ local E=({6,2}00000) F=\${E[\$1&1]} G=1
while [ \$G -ne \$F ];do G=\$F;[ \$G -eq 0 ]&&F=0000||printf -v F "%u" \$(((\${G}000
+\${1}00000000000/\${G})/2));printf -v F "%.0f" \${F:0:\${#F}-3}.\${F:\${#F}-3};done
F=0000\$F;printf -v \$2 "%.3f" \${F:0:\${#F}-4}.\${F:\${#F}-4};};g(){ local t=(\$[7#0
] 104528 207912 309017 406737 500000 587785 669131 743145 809017 866025 913545
951057 978148 994522 1000000) j=1 x=\$1 h=-1 y=\$1;[ \$x -gt 30 ]&&j=-1 x=\$[60-x]
((x>15))&&x=\$[30-x];x=00000\$[J*1000000+j*\${2:-10}*\${t[\$x]}];((y>30))&&y=\$[60-y
];((y>15))&&h=1 y=\$[30-y];y=00000\$[J*1000000+h*\${2:-10}*\${t[15-y]}];printf -v\
\$3 "%.0f %.0f" \${y:0:\${#y}-6}.\${y:\${#y}-6} \${x:0:\${#x}-6}.\${x:\${#x}-6};};v=000
v+=\$((870 *J));printf -v v "%.0f" \${v:0:\${#v}-3}.\${v:\${#v}-3};C=000\$((780*J));
printf -v C "%.0f" \${C:0:\${#C}-3}.\${C:\${#C}-3};D=000\$[650*J];printf -v D %.f \
\${D:0:\${#D}-3}.\${D:\${#D}-3};declare -A m;for ((i=1;i<=12;i++));do g \$[5*(i%12)
] \$J w;m[\$w]=\$i;done;printf -v T "\e[1m%s\e[0m " . + \* o O;T=(\${T});m["\${J: \
} \$J"]=\${T} ;printf "\e[?25l\e[H\e[J";trap "printf '\e[?12l\e[?25h\e[\$((2*J +3
))H\e[J';exit" 0 1 2 3 6 9 15; printf -v S "\\e[1;%dH%%(%%H)T\\e[%dH%%(%%M\${Z:
})T\\e[%d;%dH%%(%%S)T" \$[4*J] \$[2*J+1] \$[2*J+1] \$[4*J];declare -A V;V["\$[2 * J
] \$[2*\$J]"]="  ";while :;do [ "\$A" ]||printf -v A "%(%M)T" -1;unset r;declare\
-A r;for ((i=1;i<=C;i++));do g \${A#0} \$i w;r[\$w]=M;done;[ "\$B" ]||printf -v \
B "%(%H)T" -1;unset s;declare -A s;for ((i=1;i<=D;i++));do g \$((5*( \${B#0}%12)
)) \$i w;s[\$w]=H;done;printf -v z "%(%S)T" -1;g \${z#0} \$v n;[ "\$2" ]||echo -en\
\\e[H;for ((i=0;i<=2*J;i++));do x=\$[J-i];u \$[J*J-\${x#-}**2] N;printf -v N\${Z:
} %.f \$N;for ((l=0;l<=2*J;l++));do y=\$[J-l];u \$[J*J-\${y#-}**2] O;printf -v O \
%.f \$O;c="  ";if [ "\$i \$l" = "\$n" ];then c=\$'\e[36;1ms \e[m';elif [ "\${r["\${i:
} \$l"]}" ] ;then c=\$'\e[32;1m'\${r["\$i \$l"]}\$' \e[0m';elif [ "\${s["\$i \$l"]}" ];
then c=\$'\e[34;1m'\${s["\$i \$l"]}\$' \e[0m';elif [ "\${m["\$i \$l"]}" ];then printf\
-v c "%-2s" "\${m["\$i \$l"]}";elif [ \${x#-} -eq \$O ] || [ \${y#-} -eq \$N ] ;then
c=.\ ;else c="  ";fi;[ "\$c" != "\${V["\$i \$l"]}" ]&& V["\$i \$l"]="\$c" && printf \
"\e[%s;%sH%-2s" \$((1+i)) \$[1+l*2] "\$c";done;done;[ "\$2" ] &&break;printf "\${Z:
}\e[H\e[7mS\e[0m";c ;printf "\e[H \$S" -1 -1 -1;m["\$J \$J"]=\${T[\$[10#\$z%\${#T[@]:
}]]};unset B A;done
``````

### Note: Don't use this anyway!

As this is programm and as bash is not a programmation language, this is not well to use for a while.

There is a little demo of memory consumption in only 5 hours, with a drawing of 7 character length ray:

``````\$ ascii-clock.sh 7

After     PMem   PCpu      Mem
0'30"  0.0%  21.6%   12.98M
10'30"  1.0%  20.9%   48.91M
1h 0'30"  5.6%  20.8%  228.63M
2h 0'31" 11.2%  20.8%  444.25M
3h 0'32" 16.8%  20.8%  659.91M
5h 0'00" 27.9%  20.8%   1.064G
``````

The main advantage of this that when I need memory, I just have to kill the clock.

( Nota: I've merged this, the perl version and a version of same on ascii-clock for geeks ;-)

-
@manatwork Why? It's analog, run continuously and make the draw in less than 1 second... What do I mis readed? – F. Hauri Oct 25 '13 at 17:31
Oops. My mistake. First I tried it on `bash` 4.1. On 4.2 indeed runs continuously and not requires the command line parameters. – manatwork Oct 25 '13 at 17:51
There is no size limit on requirement. And doing this in pure bash is a real challenge! Doing this shorther without fork seem not simple (if even possible). – F. Hauri Oct 25 '13 at 17:54
Right, there is no size limit and accomplishing it with pure `bash` is a demonstration of great skill. (/me takes of his hat and clicks the upvote link) But those 2529 characters could still be reduced in the spirit of code-golf challenges: “Code-golf is a competition to solve a particular problem in the fewest bytes of source code.” – manatwork Oct 25 '13 at 18:04
+1 for no external libraries, and a detailed answer – Timtech Nov 27 '13 at 20:48

# Python 2 - 207

``````import time as T
while 1:t=T.localtime();m=t.tm_min/5;l=[12]+range(1,12);l[m]='';l[t.tm_hour%12]='H';l[m]+='M';a='  %s\n';print(a+('%s'+a)*5+a)%tuple(str(l[x])for x in[0,11,1,10,2,9,3,8,4,7,5,6]);T.sleep(9)
``````

It is very ugly, but readable. Prints every 9 sec (you can change to 1 sec if you prefer), updates every 5 min. I don't have much experience with code golfing in python so I expect it can be improved.

Example output:

``````  12
11  1
10  2
9  M
8  4
7  H
6
``````
-
Your clock appears to be a Dali. Bravo! – Shmiddty Feb 24 '13 at 21:40

### Perl 5 x 65 = 325 - 65(20%) = 260 chars!!

Clean, circular, with a second tick and updated every seconds.

``````perl -E '
\$r=11;\$p=atan2(1,1)/7.5;sub c{(\$A,\$R,\$C)=@_;\$a[\$r-\$R*cos(\$A*\$p)][
\$r+\$R*sin(\$A*\$p)]=\$C." "x(\$C!~/../)};while(::){@a=map{[map{"  "}(
0..\$r*2)]}(0..\$r*2);map{c\$_*5,\$r,\$_}(1..12);@t=localtime;for\$i(qw
|H:6:5:2 M:8:1:1 s:9:1:0 |){(\$S,\$P,\$F,\$T)=split":",\$i;map{c\$F*\$t[
\$T],\$_,\$S}(do{\$T?1:\$P}/10*\$r..\$P/10*\$r)};map{say@{\$_}}@a;sleep 1}
'
``````

On a 24 lines console look good (It's 00:12:56):

``````                    12
11                    1
s

10                  H                 2
H
H
H           M M
H     M M M
M M M
9                                           3

8                                     4

7                     5

6
``````

And there is a colored, nicer and smarter version:

``````#!                               /usr/bin/perl
use Time::HiRes qw|sleep time|
;\$h=11;\$h=\$ARGV[0]if\$ARGV[0];\$P=atan2
(1,1)/7.5;\$V =4*\$h; \$v= 2* \$h+ 1;@r=(0..2*\$v)
;sub p{printf @_       }sub        b{ return"\e[1m"
.pop."\e[0m"              };\$              |=p"\e[?25".
"l\e[H\e[" ."J"            ;\$             SIG{ 'INT'}=sub
{p"\e[?1"    ."2l"                        ."\e"     ."[?25h".
"\e[%dH"        ."\e"                       ."[J"      ,\$v+2;exit;
};@z=map                                                  {[map{" "
}@r] }(0                                                     ..2*\$v);
@Z=map{[@                                                  {\$z[\$_]}]}@r
;sub c{(\$A,\$r ,\$s                                       )=@_;\$z[\$h-\$r*cos
(\$A*\$P)    +.5 ][\$h+\$                                 r*sin(\$A*\$P)+.5]=\$s;}
for\$x(        0..\$h) {\$y=                         int(sqrt(\$h**2     -\$x**2
)+.5);\$         z[\$h-\$x][\$h-\$                  y]=".";\$z[\$h+\$x        ][\$h-\$y
]=".";             \$z[\$h-\$x][\$h+\$           y]=".";\$z[\$h+\$x            ][\$h+\$
y]=".";                \$z[\$h-\$y][\$h-\$    x]=".";\$z[\$h+\$y                ][\$h-\$x
]=".";                    \$z[\$h-\$y][\$h+\$x]=".";\$z[\$h+                    \$y][\$h
+\$x]="."};map{               c\$_*5,\$h,b\$_}(1..12);                @R=map{[@{\$z[
\$_]}]}@r;while                (::){@t=localtime;                   p"\e[H\e[1;\$
{V}H%0"                       ."2d\e[\${v}H%02d\e"                        ."[\${v
};\${ V                         }H%02d",\$t[2],\$t[                         1],\$t[
0];@z=                         map{[     @{\$R[                         \$_]}]}(
0..2*\$                                                                 v);for
\$i('H:'                                                              .'65:5:'
.'2:4',     ""                                               x1    .'M:78:'
."1:1" .":2",                                               "s:8". "7:1:"
.'0:6'){(\$                                                  l,\$p,\$F,\$u,\$
c)=split                                                    ":",\$i;map
{c\$F*\$t                                                     [\$u],\$_
,b("\e["                                                ."3\${c}m\$
l")}(do{\$u     ?1:\$                         p} /     100*\$h..\$p
/100*\$h);}  \$z[\$            h][            \$h]=  b((".","+"
,"*","o","O")             [\$t             [0]%5]);for\$x
(@r){for\$y(@r           ){\$           Z[\$x][\$y]ne\$z
[\$x][\$y]?p"\e[%d;%dH".\$z  [ \$x] [\$y],\$x+1,2*\$
y+1:''};};@Z=map{[@{\$z[\$_]}]}@r;\$n=1-\$1
if time=~/(\..*)\$/;p"\e[H\e[7m"
."S\e[0m";sleep\$n}
``````

This version is strongly linked to this other answer, with the main advantage: You could run this quietly, for a while! So you could find an upgraded version there or on this ascii-clock for geeks web page.

As a demonstration that doing approx same in require less resources:

``````\$ ascii-clock.pl 7

After     PMem   PCpu      Mem
0' 0"  0.0%   0.0%    23.5M
10'30"  0.0%   0.0%    23.5M
1h 0' 0"  0.0%   0.0%    23.5M
2h 0' 0"  0.0%   0.0%    23.5M
``````

for approx same features:

• wait for begin of each seconds for doing a refresh
• draw with color and bold attributes
• draw full circle with dots, hour tick, hour and minutes full path and a `s` dot for second handler.
• draw digital clock prompting hour at top right, minutes at bottom left and seconds at bottom right.
• prompt a `S` at top left, when sleeping (look for difference with version)

Plus

• The upgraded version authorize `-a` argument for drawing hour and minute path in fraction (11h59 place hour path approx at 12h).

### Let another perl version!!!

Using the following (beautiful) picture:

Than you could simply:

``````curl http://i.stack.imgur.com/xvbHP.png |
perl -e 'use GD;GD::Image->trueColor(1);\$i=GD::Image->newFromPng(
STDIN);my(\$x,\$y)=\$i->getBounds();for my\$k(0..\$x-1){for my\$l(0
..\$y-1){\$_.=pack"UUU",\$i->rgb(\$i->getPixel(\$k,\$l))};};eval'
``````

Ok, this require having gd2-perl installed. But you could replace `curl` by `wget -O -` ;-)

( Note: This picture is near 1.5Kb. I've built another same picture, but 900 bytes length. You may find this picture, well as a version of same at ascii-clock for geeks :-)

-
In last sample, I (strongly recommend/) suggest to replace `eval` by `print` in order before running unknown downloaded code ;-) – F. Hauri Nov 24 '13 at 23:59

### Javascript 2169 - 434 = 1735

Ok, it's a lot, but they are fine and work same as my previous variant in previous posts (bash and perl).

This version is more obfuscated than the one you may find on my ascii-clock for geeks

``````var x='<div class="m">&nbsp;M</div>',v='<div class="s">&nbsp;s</div>',w='&nbsp;'
,r=10,q,w='&nbsp;',y='<div class="h">&nbsp;H</div>',f=new Object();function d(){
q=document.getElementById("asciiclock");var t=document.location.toString().match
(/[?]([0-9]+)/);if (t!=null) r=t[1]*1.0;a();b();}function m(e){r=e;a();}function
a(){f=[];for (var i=1;r>i;i++){var u=Math.round(Math.sqrt(Math.pow(r,2)-Math.pow
(r-i,2)));f[(2*r-i)+"x"+(r+u)]=w+".";f[(i)+"x"+(r+u)]=w+".";f[(2*r-i)+"x"+(r-u)]
=w+".";f[(i)+"x"+(r-u)]=w+".";f[(r+u)+"x"+(2*r-i)]=w+".";f[(r+u)+"x"+(i)]=w+".";
f[(r-u)+"x"+(2*r-i)]=w+".";f[(r-u)+"x"+(i)]=w+".";}for(var i=1;13>i;i++){f[Math.
round(r+r*Math.sin(Math.PI/6*i-Math.PI/2))+"x"+Math.round(r+r*Math.cos(Math.PI/6
*i-Math.PI/2))]='<div class="t">'+(i<10?w+i:i)+'</div>';}}function b(){var z='';
var s=new Date(), o=s.getMinutes()*1.0+1.0*s.getSeconds()/60,p=s.getHours()*1.0+
1.0*o/60,n=s.getSeconds()*1.0,k=s.getHours();if (k<10) k=w+k;var j=s.getMinutes(
);if (j<10) j=w+j;var h=s.getSeconds();if (h<10)h=w+h;var g=new Object();for(var
i=1;r*.78>=i;i++) {g[Math.round(r+i*Math.sin (Math.PI/30*o-Math.PI/2))+"x"+Math.
round(r+i*Math.cos(Math.PI/30*o-Math.PI/2))]=x;};for (var i=1;r*.62 >=i;i++) {g[
Math.round(r+i*Math.sin(Math.PI/6*p-Math.PI/2))+"x"+Math.round(r+i*Math.cos(Math
.PI/6*p-Math.PI/2))]=y;};g[Math.round(r+.87*r*Math.sin(Math.PI/30*n-Math.PI/2))+
"x"+Math.round(r+.87*r*Math.cos(Math.PI/30*n-Math.PI/2))]=v;for (var i=0;2*r>=i;
i++){for(var l=0;2*r>=l;l++){if((i==r)&&(l==i)){z+=w+'<div class="t">'+['.','+',
'*','o','O'][n%5]+'</div>';}else if(f[i+"x"+l]!=undefined){z+=f[i+"x"+l]}else if
(g[i+"x"+l]!=undefined){z+=g[i+"x"+l];}else if(l==2*r){if(i==0){z+=w+'<div clas'
+'s="t">'+k+'</div>';}else if(i==l){z+=w+'<div class="t">'+h+'</div>';}else{z+=w
+w;};}else if(l==0){if(i==2*r){z+='<div class="t">'+j+'</div>';}else if(i==0){z=
'<div class="r">S</div>'+w;}else{z+=w+w}}else{z+=w+w}};z+='<br />';};q.innerHTML
=z;window.setTimeout(b,1000-new Date().getMilliseconds());};function c(){window.
setTimeout(b,0);q.innerHTML=w+q.innerHTML.substring (22);q.setAttribute('style',
``````.asciiclock { margin: 3em 0px 0px 0px;padding: 2px 4px 2px 3px; font-size: .5em;
display:inline-block;font-family:mono,monospace,courier;background:rgba(0,0,0,.7
);color: #888;}.asciiclock div{ display:inline-block;font-weight:bold;}.h{color:
#46F;}.m{color:#0F0;}.s{color:#0FF;}.r{color:#000;background:#aaa;}.t{color:#aaa
;}pre{display:inline-block;}``````
``````<head><title>Ascii-clock</title><script type="text/javascript" src="ascii-clock.js"

-

## Python, 259 - 52 = 207

``````from time import*
from math import*
g=[[' ']*61 for _ in[0]*31]
while 1:
t=localtime()
for x in range(60):a=pi*x/30-pi/2;g[15+int(15*sin(a))][30+int(30*cos(a))]='m'if x==t.tm_min else'h'if x==t.tm_hour%12*5 else'-'if x%5 else'#'
for r in g:print''.join(r)
``````

Sample output:

``````                              #
-  -  -     -  -  -
-                       -
-  h                           #  -
-                                       -
-                                           -

m                                               -
#                                                 #
-                                                     -

-                                                       -
-                                                         -

-                                                         -
#                                                           #
-                                                         -

-                                                         -
-                                                       -

-                                                     -
#                                                 #
-                                               -

-                                           -
-                                       -
-  #                           #  -
-                       -
-  -  -     -  -  -
#
``````
-

# Ruby: 230 228 characters - 46 = 182

``````M=Math
P=M::PI
x=->n,m=60,r,c{\$><<"^[[%d;%dH%s\n"%[M.sin(n*P*2/m-P/2)*r+12,M.cos(n*P*2/m-P/2)*r*2+24,c]}
while t=Time.now
\$><<"^[[2J"
1.upto(12){|i|x[i,12,11,i]}
x[t.hour*5+t.min/12,8,?H]
x[t.min,9,?M]
x[t.sec,10,?S]
sleep 0.1
end
``````

(Note: `^[` is a single character.)

Sample run (at 21:19:33):

``````                      12
11                     1

10                                     2

H
9                                           3

M

8                                      4

7   S                 5

6
``````

## “As ugly as you wish” version: 191 181 characters - 36 = 145

(Smaller size, lower precision, no seconds, identical radius, horrible flickering.)

``````x=->n,m=60,c{\$><<"^[[%d;%dH%s\n"%[Math.sin(n*6.3/m-1.6)*8+9,Math.cos(n*6.3/m-1.6)*8+9,c]}
while t=Time.now
\$><<"^[[2J"
1.upto(12){|i|x[i,12,i]}
x[t.hour*5+t.min/12,?H]
x[t.min,?M]
end
``````

Sample run (at 21:19):

``````       12  1
11

2
10

H              3
9

M
8

5
7   6
``````

## Trigonometry-less version: 130 125 characters (no bonus)

(Inspired by Johannes Kuhn's Tcl solution. Not sure how much, as I still not deciphered his code.)

``````while t=Time.now
puts"^[[2J  k l a
j\tb
i\tc
h\td
g f e".tr((t.min/5+96).chr,?M).tr(((t.hour-1)%12+97).chr,?H).tr("a-l",?*)
end
``````

Sample run (at 21:19):

``````  * * *
*       *
H       M
*       *
* * *
``````
-
I added an explanation to my solution. Just ask if something is not clear. – Johannes Kuhn Oct 24 '13 at 20:21
Thank you @JohannesKuhn, I already read it. For me the mystery is not the syntax, but the encoding of those string values. – manatwork Oct 25 '13 at 8:18
On that last one I'm getting syntax errors. – Timtech Nov 27 '13 at 20:55
@Timtech, is it “`tr': can't convert Fixnum into String (TypeError)”? Now that you mentioned the error I dug for a version 1.8.7 and received the above error of that. Works fine on 1.9.2 and 1.9.3. Seems that `?M` was interpreted as Fixnum in older versions and only later was changed to String. – manatwork Nov 28 '13 at 9:50

### Tcl, 288

``````while 1 {scan [clock format [clock seconds] -format %k-%M] %d-%d h m
regsub -all \ +|. "oaosocowoeouooovoioxozom   r    n\n" \ {&} p
lset p [set h [expr \$h%12*2]] h
lset p [set m [expr \$m/5*2]] [expr \$h-\$m?"m":"x"]
puts [string map /\ \$p {rr/nrzmrann xrrr snnimrrrcnn vrrr wnnromrenrru}]}
``````

Ok, here some explaination:

• `while 1 {...}` - Ok, forget the explaination.
• `regsub -all \ +|. "oaosocowoeouooovoioxozom r n\n" \ {&} p` replaces `+|.` with `_{\0}` and stores the result in `p`. `p` is actually a messed up dictionary where the first key is missing (or just a list with an odd number of elements).
• `lset p [set h [expr \$h%12*2]] h` sets the hour in the replacement list
• `lset p [set m [expr \$m/5*2]] [expr \$h-\$m?"m":"x"]` sets the minute. if hour and minute is the same, use `x` instead.
• `string map /\ \$p {rr/nrzmrann xrrr snnimrrrcnn vrrr wnnromrenrru}` `/\ \$p` is equal to `"/ \$p"`, so I add the first key (`/`). After that I replace every occurence of a key in `rr/nrzmrann xrrr snnimrrrcnn vrrr wnnromrenrru` with it's value.

The usual map is

``````/ o a o s o c o w o e o u o o o v o i o x o z o m {   } r {    } n {
}
``````

(Read as "Replace `/` with `o`, replace `a` with `o`... replace `m` with `___` (that should be spaces))

I repace an `o` with `h` and an other with `m`, `m`, `r` and `n` are just to shoren the output string (I replaced several spaces with one of them, also `\n` with `n`). I add the first element later so I can use h*2 instead h*2+1 for the index that I replace. (saves 2 chars)

Some notes:

• A list in Tcl uses whitespace as delimiter, if an element contains whilespace, you have to enclose it with `{}`. Ok, it's a little bit more complex e.g. you could escape the whitespace with a `\`, but such details are documented somewhere else.
• A dict in Tcl is just a list with an even number of elements: `key1 value1 key2 value2`
• You can treat a list as string or a string as list. Will work if the string is a valid list. Free serialization!
-

# HTML & JS: `397 - 20% = 317.6 characters`

My first iteration. I'm not very pleased with it, but it does work and it does show the time in a very clear way.

``````<canvas id=c width=198 height=198></canvas><script>c=document.getElementById("c")
.getContext("2d");c.r=c.rotate;c.c=c.clearRect;c.translate(99,99);for(i=0;i<60;i++)
{c.fillRect(89,-1,i%5?3:9,5);c.r(p=Math.PI/30);}setInterval(function(){n=new Date();
h=n.getHours()*5*p;c.beginPath();c.arc(0,0,86,0,7);c.fill();c.r(m=n.getMinutes()*p);
c.c(-2,-3,4,-80);c.r(h-m);c.c(-2,-3,4,-50);c.r(-h);},5);</script>
``````
-
Cute, but not exactly what we call ascii-art. – manatwork Dec 3 '13 at 8:03

## Ti-Basic 84, 587 - 20% = 469.6

``````:Xmax/2→Xmax:Ymax/2→Ymax:-Xmax→Xmin:-Ymax→Ymin:Degree:15→H:20→M:18→S::Circle(0,0,30):For(X,1,12)::Text(28-int(cos(X*30)*25),46+int(sin(30*X)*25),X):End:{0,0,0}→LANG:While getKey=0::getTime→LTIME::If LTIME(3)≠LANG(3)/6:Line(0,0,sin(LANG(3))*S,cos(LANG(3))*S,0)::If LTIME(2)≠LANG(2)/6:Then:::Line(0,0,sin(LANG(2))*M,cos(LANG(2))*M,0):::Line(0,0,sin(LANG(1))*H,cos(LANG(1))*H,0)::End::"SET ANGS::LTIME(1)*30+LTIME(2)/2→LANG(1)::LTIME(2)*6→LANG(2)::LTIME(3)*6→LANG(3)::Line(0,0,sin(LANG(1))*H,cos(LANG(1))*H::Line(0,0,sin(LANG(2))*M,cos(LANG(2))*M::Line(0,0,sin(LANG(3))*S,cos(LANG(3))*S:End
``````

Its output is very pretty and detailed.

-

C, 554 Bytes, Updates roughly once per second.

``````#include <time.h>
#include <math.h>
int r=25,i,q,c,i,q,b[999];void v(float a,int f,int m){b[(r/2+(int)(sin(a)*f))*r+r/2+(int)(cos(a)*f)]=m;}void main(){float a,p=6.28,z=1.57,h,m,s;for(;;){time_t u=time(0);struct tm*l=localtime(&u);s=l->tm_sec;m=l->tm_min+s/60.;h=l->tm_hour+m/60.;system("@cls||clear");q=r*r;c=r/2;memset(b,32,q*4);for(i=0,a=p;a>0;a-=0.52,i++)v(a,c,i%3?46:i%6?124:45);v(0,0,79);v(p*s/60.-z,c-4,83);v(p*m/60.-z,c-5,77);v(p*h/12.-z,c-6,72);for(i=0;i<q;i++){c=b[i];putchar(c);if(i%r==r-1)putchar(10);}for(c=0;c<2000000;c++)hypot(3,.4);}}
``````

Result:

``````           |
.          .

.
S    .

H

-          O          -

M
.
.

.          .
|
``````
-