Angle Between Hands of a Clock – Java

It is Tuesday November 03, 2020 and it is Election Day. As it is customary my wife and I got up at 06:00 AM. I prepared our usual breakfast (yogurt, mixed fruits, homemade granola and bananas). We have been preparing the same breakfast for a decade or so.

After breakfast, we both got ready and headed to our designated polling location. There were two lines. Both were moving at a reasonable rate. Once we got our ballots we filled them and inserted in the counting machine. We were at the site for about 15 minutes. All went as expected.

Later in the day we spoke with our two sons. One voted via ballots delivered by the USPS. The other stopped by his assigned polling place around 08:30 AM. Apparently there were more voters at that site.

Yesterday I had the opportunity to meet on-line a couple people from a company that develops medical products. It was a very nice conversation. It seems that organizations are more and more concerned about security. I remember when security was an afterthought. Today engineers are dealing with security as one more requirement in their initial offerings.

I decided to tackle LeetCode 1344 Angle Between Hands of a Clock. If interested take a look at the requirements in the LeetCode web site. The problem is very well described by the title. The only addition is that the expected answer should be the smallest angle.

Given two numbers, hour and minutes. 
Return the smaller angle (in degrees) formed between the hour and the minute hand.

Constraints:

o 1 <= hour <= 12
o 0 <= minutes <= 59
o Answers within 10^-5 of the actual value will be accepted as correct.

As mentioned, the returned angle should be the smallest between the two hands in the clock. For example, at 03:00 the two angles formed by the hands are 90 and 270 degrees apart. We need to return 90 (not 270).

class Solution {
    public double angleClock(int hour, int minutes) {
        
    }
}

The function takes the current time as two integers and it should return the smallest angle as a double.

12,30
main <<<   hour: 12
main <<< minute: 30
angleClock <<< h: 15.0
angleClock <<< m: 180.0
angleClock <<< a: 165.0
main <<< output: 165.0


3,30
main <<<   hour: 3
main <<< minute: 30
angleClock <<< h: 105.0
angleClock <<< m: 180.0
angleClock <<< a: 75.0
main <<< output: 75.0


3,15
main <<<   hour: 3
main <<< minute: 15
angleClock <<< h: 97.5
angleClock <<< m: 90.0
angleClock <<< a: 7.5
main <<< output: 7.5


4,50
main <<<   hour: 4
main <<< minute: 50
angleClock <<< h: 145.0
angleClock <<< m: 300.0
angleClock <<< a: 155.0
main <<< output: 155.0


2,50
main <<<   hour: 2
main <<< minute: 50
angleClock <<< h: 85.0
angleClock <<< m: 300.0
angleClock <<< a: 215.0
main <<< output: 145.0

LeetCode provides four examples. The first four examples in my test cases represent them. I just added a fifth test.

It seems that we read the provided hour and minute values. We display them for sanity reasons. We then call the function at hand and display, what seems to be the hour hand angle, the minute hand angle and the angle between the hands.

    /**
     * Test scaffolding.
     * 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {

        // **** open reader ****
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 

        // **** read the next line and split it ****
        String[] data = reader.readLine().split(",");

        // **** close reader ****
        reader.close();

        // **** convert data to integer ****
        int hour = Integer.parseInt(data[0]);
        int minute = Integer.parseInt(data[1]);

        // ???? ????
        System.out.println("main <<<   hour: " + hour);
        System.out.println("main <<< minute: " + minute);
 
        // **** process and display angle ****
        System.out.println("main <<< output: " + angleClock(hour, minute));
    }

I decided to solve the problem using Java, on a Windows 10 computer and the VSCode IDE. Of course you should be able to develop your solution on-line or on your computer of choice using your preferred IDE for your language. If you use Java the code should work as is. Given that I like to develop the code using my Windows 10 machine at home, I had to develop a simple testing scaffold.

We start by opening a buffered reader. We read the line containing the string with the hour and minute separated by a ‘,’. We split the data into two entries in a String array. We then close the buffered reader. As usual, it is a good idea to release resources as soon as you are done with them. That said, the resources would be released when the program exits.

We then generate the binary values for the hour and minute. To check all is well so far, we display the values. In all cases things seem to be fine so far.

The final and most important part is to call the function we are implementing and display the results. Please note that this code is NOT PART OF THE SOLUTION. LeetCode will call our implementation of the angleClock() function with their own testing scaffold.

    /**
     * Return the smaller angle (in degrees) formed between the hour and the minute
     * hand.
     * 
     * Runtime: 0 ms, faster than 100.00% of Java online submissions.
     * Memory Usage: 35.9 MB, less than 5.82% of Java online submissions.
     */
    static double angleClock(int hour, int minutes) {

        // **** compute hour hand angle ****
        // double h = hour * (360.0 / 12.0);
        double h = hour * 30.0;

        // **** adjust it by the number of minutes ****
        // h += minutes * (30.0 / 60.0);
        h += minutes * 0.5;

        // **** ****
        if (h > 360.0)
            h -= 360.0;

        // ???? ????
        System.out.println("angleClock <<< h: " + h);

        // **** compute minute hand angle ****
        // double m = minutes * (360.0 / 60);
        double m = minutes * 6.0;

        // ???? ????
        System.out.println("angleClock <<< m: " + m);

        // **** compute difference in angles ****
        double a = Math.abs(h - m);

        // ???? ????
        System.out.println("angleClock <<< a: " + a);

        // **** return the smallest angle ****
        return a <= 180.0 ? a : 360.0 - a;
    }

The solution should not contain the println() calls. They are only used for debugging and didactical purposes. As a matter of fact, most debugging is typically done with an IDE so println() is seldom used. What most organizations do is to log some data with the hopes to help debugging when an issue is detected with the code.

The approach is to compute the initial position of the clock hand based on the hour. For example, at 03:00 the clock had will be at 90 degrees. But if the time is slighter different, e.g., 03:30, then we need to compensate the angle by adding a component that represents the 30 minutes.

We then compute the position of the minute hand. That can be done directly without modifications to take into account.

Finally we compute the difference between the angles of the clock hands.

The initial angle of the clock hand is based on 12 hours and 360 degrees. The clock hand then needs to de update by the fraction of the next hour expressed in minutes. Note that the clock hand moves at most 30 degrees per 60 minutes. Finally the minute hand moves at a rate of 360 degrees per hour (or 60 minutes).

When all is set and done the function makes sure we always return the smaller angle between the hands. Both angles add to 360 degrees, so we need to return the smallest angle.

My solution was approved by LeetCode. The execution time and memory usage are in the comment of the angleClock() function.

Hope you enjoyed solving this problem as much as I did. The entire code for this project can be found in my GitHub repository.

If you have comments or questions regarding this, or any other post in this blog, or if you would like for me to help out with any phase in the SDLC (Software Development Life Cycle) of a project associated with a product or service, please do not hesitate and leave me a note below. If you prefer, send me a private e-mail message. I will reply as soon as possible.

Keep on reading and experimenting. It is the best way to learn, become proficient, refresh your knowledge and enhance your developer toolset!

One last thing, many thanks to all 3,662 subscribers to this blog!!!

Keep safe during the COVID-19 pandemic and help restart the world economy.

John

E-mail:  john.canessa@gmail.com

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.