Today's algorithm is the Angle Between the Hands of a Clock Problem:
Given two numbers,
hour
andminutes
. Return the smaller angle (in degrees) formed between the hour and the minute hand.
Let's say you were given the time 3:00. By looking at a clock, you can see how the smaller angle between the hour and minute hand forms 90 degrees:
But if you were given a time like 8:15, you can't immediately tell that the angle is 157.5 degrees:
This problem is one of those that is less programming-based and more logic-based. Because of that, in this post I'll spend longer on the "approach" section, and then will go into an explanation for how to code the solution.
Approaching the Problem
Let's start by looking at a blank clock. A clock, which is a circle, is 360 degrees. Since there are 12 hours, each slice between the hour is is 360 / 12
, or 30 degrees.
Since there are 60 minutes in an hour, each move of a minute hand is 360 / 60
, or 6 degrees.
Calculating the angle of the minute hand, therefore, just means you multiply the number of minutes by 6. If we were given the time 11:20, we know the minute hand is at 6 * 20
, or 120 degrees. By that, I mean that the angle between the 12 (which is 0/360 degrees), and the minute hand is 120 degrees.
Calculating the angle of the hour hand is a bit trickier. When it's 8:15, the hour hand is not directly on the 8. Instead, it's a bit after the 8. We need to know exactly how much that "bit" is. Since there are 60 minutes in an hour, and the hour hand moves 30 degrees every 60 minutes, that means that the hour hand moves 30 / 60
, or 0.5 degrees every minute. Therefore, the angle of the hour hand can be calculated by multiplying the hour by 30, multiplying the minutes by 0.5, and adding those two results. If we were given the time 8:15, we'd know the hour hand is a bit past the 8. When it's at the 8, the hour hand is 8 * 30
, or 240 degrees past the 12. The fifteen minutes are another 15 * 0.5
, or 7.5 degrees, more. In total, therefore, at 8:15, the hour hand is at an angle of 247.5 degrees.
Now we know the angle of the minute hand, and the angle of the hour hand. So, we'll want to find the difference between these numbers. We don't know, however, which hand has the bigger angle. For example, if we were given the time 3:30, our clock would look like this:
The hour hand is at an angle of 105 degrees, whereas the minute hand is at an angle of 180 degrees. If we did hour hand minus minute hand, we'd get -75 degrees--whereas we actually want 75 degrees. Therefore, we can just do the absolute value of whatever the difference between the hour and minute hand are. "Absolute value" is the non-negative version of a number. If a number is already positive, it doesn't change with absolute value. If a number is negative, doing absolute value on that number essentially multiplies the number by -1. We can do absolute value in JavaScript with Math.abs()
, which you can learn more about here.
The last thing we have to think about in terms of the approach is that we want the smaller angle between the hour and minute hand. For example, let's say the time given was 12:30. Because of the way we're calculating the angle of the hour hand, it would be at (hour * 30) + (minutes * 0.5)
, or (12 * 30) + (30 * 0.5)
, or 375 degrees. The minute hand would be at an angle of 15 degrees. The absolute value of the difference between hour hand and minute hand is Math.abs(375 - 180)
, or 195, but 195 degrees is the larger angle between the hands. What we want is the smaller angle between the hands, which we can find by doing 360 - 195
, or 165.
Therefore, we want to return whichever number is smaller: the angle, or 360 minus the angle. To find which number is smaller, we can use Math.min()
, passing in both numbers. You can learn more about Math.min()
here.
Coding the Solution
We're ready to code the solution! Now that we've spent so long on the approach, the coding won't take long.
We'll start by initializing a few variables. minuteAngle
can be calculated by multiplying minutes
by 6. hourAngle
can be calculated by multiplying hour
by 30, minutes
by 0.5, and summing those numbers.
function angleClock(hour, minutes) {
const minuteAngle = minutes * 6;
const hourAngle = (hour * 30) + (minutes * 0.5);
//...
}
We want to find the angle between the hour and minute hands. We'll initialize a new variable called angle
, which will be the difference between hourAngle
and minuteAngle
. We'll pass this difference into Math.abs()
, so that we have the positive version of the answer.
function angleClock(hour, minutes) {
const minuteAngle = minutes * 6;
const hourAngle = (hour * 30) + (minutes * 0.5);
const angle = Math.abs(hourAngle - minuteAngle);
//...
}
Finally, we want to return either angle
, or 360 - angle
--whichever is smaller. We can pass these two values into Math.min()
.
function angleClock(hour, minutes) {
const minuteAngle = minutes * 6;
const hourAngle = (hour * 30) + (minutes * 0.5);
const angle = Math.abs(hourAngle - minuteAngle);
return Math.min(angle, 360 - angle);
}
Let me know in the comments if you have any questions or alternate ways of solving this problem!
Top comments (1)
Very useful, I first panicked when I read the problem title as I had no clue how to approach it, everything was clear after the logic explanation.