# Build an analog clock [closed]

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.

## closed as too broad by totallyhuman, Laikoni, caird coinheringaahing, Sriotchilism O'Zaic, mbomb007Oct 13 '17 at 1:20

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

• 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

## 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... – Math chiller 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... – Math chiller Oct 21 '13 at 19:33

## 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

## 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 read -t$((60-${SleepS#0})) foo 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 read -t$((60-${SleepS#0})) foo 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 readonly TIMER_LIST_OFFSET TIMER_LIST_SKIP 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}
read -t $slp foo } 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:
${#q}-9}];read -t .${p:1} M;};else c(){ local H;read -d\  H < $W/upti*;H=$[200
-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 • @manatwork There is now a more golfed version, (not shorter: from 2529bytes, this version is now 2702 bytes, but has new features) – F. Hauri Jan 4 '16 at 23:07 # 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 ### 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.
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

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

.          .
|
`