Problem of the Day
A new programming or logic puzzle every Mon-Fri

Clock Hands

Write a program to find the minimum angle between two hands on a 24 hour clock. For instance, the angle at 6:00 is 90 degrees and the angle at 18:00 is also 90 degrees. At 6:17 the degree is 3.5 7.75 and at 18:17 it's 176.5 172.25 (hooray for supplementary angles).

For fun, program this one up in a language you've never used before. Here is a list of esoteric languages to help you decide. There are some truly interesting languages on that list. Feel free to use a "standard" language as well if there's one out there that you've been looking to learn.

Permalink: http://problemotd.com/problem/clock-hands/

Comments:

  • Moliugas - 10 years, 9 months ago

    What type of clock is this? Shouldn't the angle at 6 be 180 degrees? Hour hand at 6 hour and minute hand at 12?

    reply permalink

  • Steve Mostovoy - 10 years, 9 months ago

    I have a solution, however it gives 7.75 for 6:17 and 172.25 for 18:17. Is the question correct? I've double checked my math and it seems to be accurate for a 24 hour clock.

    My solution in C#: float AngleBetweenHands(string time) { string[] split = time.Split(':');

        int hour = int.Parse(split[0]);
        int minute = int.Parse(split[1]);
    
        float hourPercentage = minute / 60f;
        float hourHandAngle = ((hour + hourPercentage) / 24f) * 360;
    
        float minuteHandAngle = hourPercentage * 360;
    
        float difference = Math.Abs(hourHandAngle - minuteHandAngle);
        if (difference > 180) {
            return 360 - difference;
        }
        return difference;
    }
    

    reply permalink

  • Steve Mostovoy - 10 years, 9 months ago

    My apologies, the first two lines weren't in the code block.

    float AngleBetweenHands(string time) {
        string[] split = time.Split(':');
    

    reply permalink

  • Tim - 10 years, 9 months ago

    Could someone please explain this to me?

    For instance, the angle at 6:00 is 90 degrees and the angle at 18:00 is also 90 degrees.

    Isn't this 180 degrees?

    At 6:17 the degree is 3.5 and at 18:17 it's 176.5 (hooray for supplementary angles).

    Why aren't these the same? Shouldn't they roughly be 90 degrees?

    I don't understand!

    reply permalink

  • Tim - 10 years, 9 months ago

    Oh I get it now. Duh. It's a clock which displays all 24 hours in 360 degrees. So instead of a normal clock which shows 12 hours, this one runs half as slow and shows all 24 hours. So noon (12:00) is at the 12hr clock's 6 o'clock position. 6am is at the 12hr clocks 3'oclock position, 6pm is at the 12hr clock's 9'oclock position.

    reply permalink

  • Tim - 10 years, 9 months ago

    Same issue: 7.75 172.25

    public double convertToDegrees(double hour, double minutes) {
    
        double degreesPerHour = 360/24;
        double degreesPerMinute = 360/60;
        double minutesAsHour = minutes/60;
    
        double additionalHourDegrees = minutesAsHour * degreesPerHour;
    
        double degrees = (((hour*degreesPerHour)+additionalHourDegrees) - (minutes*degreesPerMinute));
    
        if (degrees<0)
            degrees = degrees * -1;
    
        if (degrees > 180) { 
            degrees -= 180;
        }
    
        return degrees;
    }
    

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    Yea my math must have been off when I was working on this. The math seems to check out for 7.75 and 172.25. Thanks for the submission!

    reply permalink

  • Tim - 10 years, 9 months ago

    Thanks for setting these problems Max, they're good fun.

    reply permalink

  • Bruno A - 10 years, 9 months ago

    @Moliugas it's a 24 hour clock (so the hours dial goes from 0/24 to 23, I'm guessing) I'm having a little problem - I think I have the code nailed down, but my angles for 6:17 and 18:17 are 7.75 and 172.75 respectively. Don't know what I'm doing wrong.

    #!/usr/bin/env ruby
    
    time = ARGV.first
    
    begin
     hours, minutes = time.split(':')
    
     hours    = Integer(hours)
     minutes  = Integer(minutes)
    
    rescue ArgumentError
      abort('please use proper times, like 6:17 or 18:17')
    end
    
    minutes_hand_deg  = minutes * 6
    hours_hand_deg    = (hours + ( minutes / 60.0 ).to_f ) * 15
    
    diff = (hours_hand_deg - minutes_hand_deg).abs
    
    diff -= 180 if diff > 180
    
    puts "angle is #{diff}"
    

    Thanks for the challenge!

    reply permalink

  • Carlos - 10 years, 9 months ago

    I have the same results, Curious! My method is pretty uch the same except i did in java first, i wonder if we are wrong or HE is wrong :P

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    It's definitely possible I was wrong. I'm doing the math now and what you both are saying seems correct. The minute hand moves 360/60 = 6 degrees per minutes and the hour had moves 360/24 = 15 degrees per hour. So 617-(615+17*15/60)=7.75. I'm curious where I came up with 3.5.

    reply permalink

  • dave - 10 years, 9 months ago

    you can use modulo instead of diff-=180 if diff > 180

    reply permalink

  • SpaceRacer - 10 years, 9 months ago

    short ruby solution (learning ruby)

    # time is of format <0-23>:<0-59>
    def min_angle(time)
        h, m = time[0..-4].to_i, time[-2..-1].to_i
        ((h*60+m)/4.0 - m*6).abs % 180
    end
    

    reply permalink

  • Pearce Keesling - 10 years, 9 months ago

    I kept forgetting that the hour hand moves in between hours haha. Great problems, keep it up.

    #include <iostream>
    #include <sstream>
    #include <cmath>
    using namespace std;
    int main(int argc, char *argv[])
    {
        string buff(argv[1]);
        string hour("");
        string min("");
        string *target = &hour;
        for(string::iterator it = buff.begin();it<buff.end();it++)
        {
            if(*it==':' || *it=='h')
            {
                it++;
                target = &min;
                }
                *target += *it;
        }
        float h,m;
        stringstream(hour) >> h;
        stringstream(min) >> m;
        float answer = fabs(((h+m/60)/24 - m/60) * 360);
        if(answer > 180) answer = 360 - answer;
        cout << answer << endl;
        return 0;
    }
    

    reply permalink

  • Flavio - 10 years, 9 months ago

    A C++ version not using pows and logs only plain integer operators:

    using namespace std;
    
    int main()
    {
        long long l,m,r;
    
        for (;;) {
            cout << "0 to finish" << endl;
            cin >> r;
            if (!r) break;
            l=0;
            if (r > 9) do {
                l = l * 10 + r % 10;
                r /= 10;
            } while (l < r);
            cout << (l && l == r || r && l / 10 == r || !l ? "" : "not ") << "Palindromic" << endl;
        }
        return 0;
    }
    

    reply permalink

  • Flavio - 10 years, 9 months ago

    Weird placed solution for yesterday's problem here...

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    If you had the problem open on the home page before midnight and then posted it, it would go to whatever the current problem is. I just fixed this so it shouldn't happen again.

    reply permalink

  • Anonymous - 10 years, 9 months ago

    Another one in J.

    clockhands=: 3 : 0
      'h m'=. y
      mquot=. m % 60
      hquot=. (mquot % 24) + h % 24
      360&- ` ] @. (<&180) 360 * | hquot - mquot
    )
    
    echo clockhands 6 17   NB. => 7.75
    echo clockhands 18 17  NB. => 172.25
    

    reply permalink

  • Anonymous - 10 years, 9 months ago

    After reading the other solutions I see that we can make this a little more 'esoteric' ...

    clockhands=: 3 : 0
      'h m'=. y
      360&- ` ] @. (<&180) | (6 * m) -~ 15 * (m % 60) + h
    )
    

    reply permalink

  • Ethan - 10 years, 9 months ago

    I don't get where the answers are coming from. 6:17 is 3.5 degrees? If you look at a 24 hour clock it should be around 30 degrees. I got 39.

    reply permalink

  • Anonymous - 10 years, 9 months ago

    On a 24-h clock, the 6 is where the 3 is on a normal 12-h clock. East on a compass.

    And 17 min is just a few degrees past that.

    reply permalink

  • tehmagik - 10 years, 9 months ago

    Some simple python <code> def CalculateAngle(time): hour, minute = (float(x) for x in time.split(':')) angle = ((hour+minute/60)/24 - minute/60)*360 print('Angle for %s is: %.2f' % (time,abs(angle) if abs(angle) <= 180 else 360-abs(angle))) </code>

    reply permalink

  • anon - 10 years, 9 months ago

    def CalculateAngle(time):
        hour, minute = (float(x) for x in time.split(':'))
        angle = ((hour+minute/60)/24 - minute/60)*360
        print('Angle for %s is: %.2f' % (time,abs(angle) if     abs(angle) <= 180 else 360-abs(angle)))
    

    reply permalink

  • John - 10 years, 9 months ago

    Went with Javascript again... Wanted to mess with currying, so mine works on a 24 hour clock, as well as a 12 hour, or even a 2 hour with 77 minutes per hour.

    function degreesBetweenHands(hourInterval,minuteInterval){
      return function(time){
        var timeArr = time.split(':');
        var hour = parseInt(timeArr[0]);
        var minute = parseInt(timeArr[1]);
        var hourDeg = degreesFromNumber(Number(hourInterval))(hour+minute/60);
        var minuteDeg = degreesFromNumber(Number(minuteInterval))(minute);
        var diff = Math.abs(hourDeg-minuteDeg);
        return Math.min(diff,360-diff);
      }
      function degreesFromNumber(num){
        var full = 360;
        var numNum = Number(num);
        return function(interval){
          var timeNum = Number(interval);
          return timeNum/numNum*full;
        }
      }
    }
    

    reply permalink

  • John - 10 years, 9 months ago

    usage:

    degreesBetweenHands(24,60)('6:17');
    

    reply permalink

  • Chris - 10 years, 9 months ago

    I'm so lost here, does the minute hand not rotate around the entire clock per hour? Or does it move in tiny increments within the current clock hour?

    It's been a while since I did geometry so I must be missing something, why is everyone dividing minutes by 60? I got 5.72.

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    The minutes hand does indeed go around the clock every hour. Post your code and let's see if we can figure it out.

    reply permalink

  • Paprika - 10 years, 9 months ago

    Here is a solution in Ruby: def angle(hour, minute) dph = 360.0/24 dpm = 360.0/60 deg = ((dph * hour + minute/60.0*dph) - dpm * minute) % 360 return deg > 180.0 ? 360.0 - deg : deg end

    reply permalink

  • Paprika - 10 years, 9 months ago

    Woops, I can swear that I indented the code with four spaces!

    reply permalink

Content curated by @MaxBurstein