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)
Top Answer
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_×60−_M_×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}
```
Answer #2
Skillmon
Schrödinger's cat knows/knew the answer:
The following uses integer arithmetic for the calculation and argument grabbing logic instead of TeX `\if`s 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 `\number0`s 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
{%
\ducksay[schroedinger,vpad=1,col=@{}l@{ -> }r@{°}]
{%
\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)