samcarter
> This is part of the Summer of Code 2022 series, see https://topanswers.xyz/tex?q=2059 for more information

Imagine an analogue 12h clock. Calculate for a given time hh:mm the angle between the two clock hands (the smaller of the two angles).

Test cases:


12:00 -> 0°
2:20 -> 50°
10:16 -> 148°


(this puzzle was inspired by https://en.wikipedia.org/wiki/Clock_angle_problem)

![SoC.png](/image?hash=f4d30dc7d04f45f0fe50b2c0195a87013bef2f08ac673f37e7099b28b7c7e0a0)
Phelype Oleinik
what have spoilers ever done for us?

Hm... SoC means SHands¹ of Clock then?


{\endlinechar                          -1^^5clet
~^^5ccatcode~}                      0~!1~'13~
?2~{6}gdef'{1!~                     {113}gdef?~
,10 ,~     9'||                    !}endcsname?']
]{1] !              }csname{1|     ?'++!p    t?'##
{1{2-!{           1{2?'__{1!]e   xpanda
fter]{1}the     }dimexpr?~413  ]globa
l]]let]4}fi    '[[{1{2!}fi_'3  60+-?'
{1;!]if   dim]{    1>180  +,[4'{
1;?'@@  {1;!]    ifdim   ]{1<0+    ,#4\${
1;?'""    {1:{2;  !_@({1+*60-{2+    *11)/2;?'--{1.
{2;!{1}ifnum{2=0  ,}else.{2}fi?]     edef]"!}gdef]
unexpanded]!'?{    {1]string]p]       string]t]str
ing];?"!-{1;°      ?}gdef}SoC           {1!"{1;??

% ---

\documentclass{article}
\begin{document}
\SoC{12:00}

\SoC{2:20}

\SoC{10:17}


¹SHands™ ought to be pronounced with a hiss followed by the word “hands” as usual, and NOT as you'd pronounce “shard” or as “S-hands”.

---

A less nicely formatted version shows that the code follows a rather straightforward step-by-step.  The main macro \SoC uses \split to separate the input on the : in hours and minutes:

\def\SoC#1{\split#1;}
\def\split#1:#2;{%
\expandafter\checkminus\the\dimexpr(#1pt*60-#2pt*11)/2;}

\split then computes the angle between the hands using (_H_&times;60&minus;_M_&times;11)/2 using a dimension expression.  The result is then passed to \checkminus, that checks if the angle is negative, in which case it calls \remminus to remove the leading -:

\def\checkminus#1;{\ifdim#1<0pt \remminus\fi\checkbig#1;}
\def\remminus#1#2-{#1#2}

then \checkbig is called to check if the angle computed is the largest between the SHands, and if it is, subtract that from 360°:

\def\checkbig#1;{\ifdim#1>180pt \makesmall\fi\format#1;}
\def\makesmall#1#2{#1\expandafter\format\the\dimexpr360pt-}

then, after all that is done, the final result is passed to \format, which removes a decimal zero, and adds a ° to the output:

\edef~{\def\noexpand\format##1\detokenize{pt};}~{\trimzero#1;°}
\def\trimzero#1.#2;{#1\ifnum#2=0 \else.#2\fi}


Skillmon
Schrödinger's cat knows/knew the answer:

The following uses integer arithmetic for the calculation and argument grabbing logic instead of TeX \ifs where possible (does anybody know an argument grabbing logic to check for a value bigger than 1800 that's faster than \ifnum?).

The final division by 10 is eased by the fact that the last digit must be a 0 or 5, for which we branch (via argument grabbing logic of course).

In the input the hh and the :mm part are both optional and default to 0.


\documentclass[varwidth,border=3.14]{standalone}

\usepackage{ducksay}

\makeatletter
\def\clockangle#1{\ca@split#1:\ca@mark#1\ca@mark:\ca@mark\ca@stop}
\def\ca@split#1:#2\ca@mark#3:#4\ca@mark#5\ca@stop
{\expandafter\ca@rmminus\the\numexpr300*0#1-55*0#4\relax\ca@stop}
\def\ca@rmminus#1\ca@stop{\ca@rmminus@#1\ca@mark-#1\ca@mark\ca@stop}
\def\ca@rmminus@#1-#2\ca@mark#3\ca@stop
{%
\ifnum#2>1800 \expandafter\ca@divten\the\numexpr3600-\ca@rmdivten\fi
\ca@divten#2;\ca@divten@zero0;\ca@divten@five
}
\def\ca@rmdivten\fi\ca@divten{\fi}
\def\ca@divten#10;#2{#2#1}
% the \number0s in the next two macros ensure that the integer part of the
% result is never empty
\def\ca@divten@zero#10;\ca@divten@five{\number0#1 }
\def\ca@divten@five#15;\ca@divten@zero{\number0#1.5}
\makeatother

\newcommand\demo[1]{#1 & \clockangle{#1}\\}
\newcommand\solveSoC
{%
{%
\demo{12:00}%
\demo{2:20}%
\demo{10:16}%
}%
}

\begin{document}
\solveSoC

\bigskip
A few hard'' ones:\par
\texttt
{%
\begin{tabular}[t]{l@{ -> }r@{°}}
\demo{10:17}
\demo{2:11}
\demo{9:49}
\demo{}
\demo{10}
\demo{:10}
\end{tabular}%
}
\end{document}


![soc11-clockangles-1.png](/image?hash=ce6bc3c5a5af57bf1364a6357fb66efeda0436b675c5f8f3806a087efd5f0ece)`