Welcome with another puzzle to solve! Today’s problem will deal with clocks and clock hands: our main goal will be calculating the angle between them!
As always, the problem is provided by the wonderful newsletter
Enough talking: let’s see the problem, which was initially asked by Microsoft during an interview.
Given a clock time in
hh:mm
format, determine, to the nearest degree, the angle between the hour and the minute hands.Bonus: When, during the course of a day, will the angle be zero?
The problem is pretty simple: we are given a clock time and we are asked to determine which is the angle between the two hands. We are also asked to calculate when this angle will be zero during the day. We’ll see some math first and then build the actual code to calculate this, which will be pretty short. We’ll be using Python this time, but feel free to port the problem in other languages and share your results!
Before jumping to the discussion of the math, we need to start off with two disclaimers:
The problem states that we are given a clock time in hh:mm
format: even if it’s not explicit, we can deduce we are given a string. We won’t bother converting from a string to integers in this article, since converting a string is a trivial operation in many programming languages. Therefore, we will imagine that clock times are already given as integers;
The problem asks us to calculate the angle between the clock hands, but it does not specify what between means. There are always two angles forming with two clock hands, as shown below.
The inside and outside angles formed by two clock hands
Therefore, we must choose what between means in this context. For this reason, we will always consider the smallest of the two angles as the angle in between.
The math used to solve this problem is pretty simple but it’s always worth a look. First off, we must calculate the angle formed by each clock hand. We are calculating the angles with the 0° angle on the number 12 on the clock as a reference, but moving the 0° around the clock won’t produce any difference if you are willing to experiment.
Let’s start with the minute’s hand: this one rotates entirely around the clock in 60 minutes. Therefore, since the total degrees of a complete circle around the clock is 360°, each minute equals a movement of 6° on the clock. This means that we can calculate the angle of the minutes hand by:
For the hours hand we can apply the same idea, but with some modification. The hours hand moves on each hour change: since there are 12 hours in a full circle around the clock, each hour will increase the angle by 30°. Therefore we can calculate the angle of the hours hand by:
That’s not all, though. The hours hand moves at a constant rate with the minutes change, thus we must also consider this movement. For example, if it’s 2.30, the hours hand will be standing between the numbers 2 and 3 on the clock: we must take the half turn on the hand into consideration. Since the movement of the hours hand is constant, the relation between minutes and hours hands will be linear.
Thus we can build a simple proportion:
and adjust the formula above accordingly:
The difference between the angle of the minutes hand and the hours hand will be our angle:
Let’s write some code then.
For simplicity, we create a class ClockPosition
, which will store the position of the hands in its attributes self.hh
and self.mm
. We also calculate the degree of the hands in self.mmdegree
and self.hhdegree
, using the formulae seen above. One simple thing to notice: while calculating self.hhdegree
we used self.hh % 12
as initial hour setting. This is because it won’t make any sense to multiply hours after 12, we would get an angle degree greater than 360°! With the modulo operand we can simply wrap around the 12 and go back to 1 while hitting 13, to 2 on 14 and so on. If you are not familiar with this operator,
After that we create a method called calculateInternalAngle
which will solve our problem. This one calculates the difference between self.mmdegree
and self.hhdegree
and stores it as angleOne
. If it’s negative, we get the absolute value by multiplying by -1. Then we calculate the other angle, angleTwo
, as 360-angleOne
. Finally, we simply return the smaller one.
After that we dump our results to a file, printing the clock hands position and the resulting degree. It’s not really useful to calculate hours from 00:00 to 23:59 (since angles repeat once passed 12:00), but for the sake of completion we will leave it there.
To answer the bonus question, we can simply check which positions give out a 0° angle, which are respectively midday and midnight.
As always, we take a look at the time complexity of the problem, which in this case is particularly easy. The are no loops or repeated calculations, so the time taken by the angle calculation is constant. This leaves us with a constant time complexity of O(1). Obviously then, to calculate each time setting and print them out, the complexity raises up since we must check each minute setting 12 times (00.05, 01.05, 02.05, …, 10.05, 11.05). But settings are finite: we have 1440 possible settings (24 * 60) and so even in this case the time complexity holds constant.
That’s it! I hope you enjoyed the article and I really hope my math was right! If you found it interesting, please leave a clap or two and share it with others: that would really make my day! Even more, if you want to contribute to this kind of articles I have a
If you didn’t like the article: whoops! Thanks for reading until the end feel free to advance any piece of advice you are willing to share!
As always, thanks for reading.
Nicola
Also published here.