Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find if the second hand of a clock lies in the larger area or smaller one [closed]

Tags:

algorithm

I have been given the time in the format: hh:mm:ss

I have to find if for a given time, the second hand lies in the larger or smaller area formed by the hour and minute hands?

I know that the hour hand moves at the rate of 0.5 degrees per minute, the minute hand moves at the rate of of 6 degrees per minute and the second hand completes 360 degrees per minute.

But I am unable to find out in which area the second hand lies. So how can I do this?

Second hand within angle between hour and minute hands:
10:15:00
04:40:30

Second hand in reflex angle:
12:01:30
like image 725
poorvank Avatar asked Dec 14 '15 13:12

poorvank


2 Answers

The problem intrigued me so I went ahead and wrote a test project in C#. As far as I can tell it works, you will have to test it to make sure though.

This is the code:

string strTime = "10:15:00";

DateTime dt = DateTime.ParseExact(strTime, "HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);

int nHourDegrees = (360 / 12) * dt.Hour;
int nMinuteDegrees = (360 / 60) * dt.Minute;
int nSecondDegrees = (360 / 60) * dt.Second;

if (nHourDegrees > nMinuteDegrees)
{
    int nArea1 = nHourDegrees - nMinuteDegrees;
    int nArea2 = 360 - nArea1;

    bool bArea1IsBigger = (nArea1 >= nArea2);
    if (nSecondDegrees <= nHourDegrees && nSecondDegrees >= nMinuteDegrees)
    {
        //Second hand lies in area1
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the larger area");
        }
        else
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
    }
    else
    {
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
        else
        {
            Console.WriteLine("Second hand is in the larger area");
        }
    }
}
else if (nMinuteDegrees > nHourDegrees)
{
    int nArea1 = nMinuteDegrees - nHourDegrees;
    int nArea2 = 360 - nArea1;

    bool bArea1IsBigger = (nArea1 >= nArea2);
    if (nSecondDegrees <= nMinuteDegrees && nSecondDegrees >= nHourDegrees)
    {
        //Second hand lies in area1
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the larger area");
        }
        else
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
    }
    else
    {
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
        else
        {
            Console.WriteLine("Second hand is in the larger area");
        }
    }
}
else
{
    if (nSecondDegrees == nHourDegrees)
    {
        Console.WriteLine("Second hand is on both of the other hands");
    }
    else
    {
        Console.WriteLine("Second hand is in the ONLY area");
    }
}

The idea is that we find the areas between the Hour and Minute hands. Then check to see if the second hand is inside this area. We also compare this area to the other one and then we can easily deduce if the second hand is in the smaller or larger of the two.

Note: Some improvements can be made to the code:

  1. It can be significantly shorter - I haven't done this because it was mainly a test/proof of how this can be done
  2. If the hours overrun (i.e. 24 hour clock not 12) an alteration will have to be made. i.e. minus 12
  3. If the times go to 12/60/60 and not back to 0, this will have to be done manually
  4. Constants can be added in to remove the need for magic numbers
  5. Similar to the above but common calculations like 360 / 12 can be moved to constants
  6. It can be broken out into separate methods to improve readability
  7. Can be moved into a helper method i.e. bool IsInLargerArea(string timeString)
  8. Need to add the case for when the areas are the same size, at the moment I just assume Area1 to be bigger if they are equal i.e. >= (greater than or equal to)
  9. Add checks to make sure there are only 3 parts to the straTimes array
  10. And possibly some more things that I have not thought of
like image 123
TheLethalCoder Avatar answered Nov 16 '22 02:11

TheLethalCoder


I would go with method which look like this. You have to identify, if the smaller area goes through 0 degree or not and then based on that you can say the solution.

int minDegree;
int maxDegree;
bool over360;

if (Math.abs(hourHandDegree - minuteHandDegree) < 180){
   minDegree = Math.min(hourHandDegree, minuteHandDegree);
   maxDegree = Math.max(hourHandDegree, minuteHandDegree);
   over360 = false;
} else {
   minDegree = Math.min(hourHandDegree, minuteHandDegree);
   maxDegree = Math.max(hourHandDegree, minuteHandDegree);
   over360 = true;
}

if (over360){
    if ((secondHandDegree < minDegree) && (secondHandDegree > maxDegree)){
        return true;
    } else {
        return false;
    }
} else {
    if ((secondHandDegree > minDegree) && (secondHandDegree < maxDegree)){
        return true;
    } else {
        return false;
    }
}
like image 43
libik Avatar answered Nov 16 '22 02:11

libik