27
\$\begingroup\$

An analog clock has 2 hands*: Hour and minute.
These hands circle the clock's face as time goes by. Each full rotation of the minute hand results in 1/12th of a rotation of the hour hand. 2 full rotations of the hour hand signifies a full day.

As these hands are fixed to the same central point, and rotate around that point, you can always calculate the angle between the hands. In fact there are 2 angles at any given time; A larger one, and a smaller one (sometimes they will both equal 180, but that's not important)

*Our hypothetical clocks don't have second hands

Task

Given a time in 24 hour format, output the smaller angle between the hands, in degrees. If the hands are directly opposite eachother (such as at 6:00, 18:00 etc) output 180

Rules

Input may be taken as: - A delimiter separated string: 6:32, 14.26 - 2 separate values, strings or ints: 6, 32, 14, 26 - An array of 2 values, strings or ints: [6, 32], [14, 26]

You may also optionally specify that your answer requires inputs be padded to 2 digits (assuming you take strings), ie: 06:32, 06, 32, [06, 32]

You may also optionally reverse the order of the inputs, taking minute then hour, ie: 32:6, 32, 6, [26, 14]

Hour will be an integer value between 0 and 23 (inclusive) Minute will be an integer value between 0 and 59 (inclusive)

You can assume that the minute hand snaps to increments of 6 degrees along the face (one evenly-spaced position for each minute value)
You can assume that the hour hand snaps to increments of 0.5 degrees along the face (one evenly-spaced position for each minute value per hour value)

Output must be given in degrees, not radians. You may include a trailing .0 for whole numbers

Scoring

This is so fewest bytes in each language wins!

Testcases

Input: 06:32
Output: 4
Input: 06:30
Output: 15
Input: 18:32
Output: 4
Input: 06:01
Output: 174.5
Input: 00:00
Output: 0
Input: 00:01
Output: 5.5
Input: 12:30
Output: 165
Input: 6:00
Output: 180
Input: 23:59
Output: 5.5
asked Jun 21, 2019 at 17:05
\$\endgroup\$
7
  • \$\begingroup\$ Sandbox post \$\endgroup\$ Commented Jun 21, 2019 at 17:06
  • 2
    \$\begingroup\$ @FryAmTheEggman "Output must be given in degrees, not radians", so I would guess not \$\endgroup\$ Commented Jun 21, 2019 at 17:27
  • 1
    \$\begingroup\$ forgot that at 5:59 hour hand is almost at 6 \$\endgroup\$ Commented Jun 21, 2019 at 17:32
  • 4
    \$\begingroup\$ Suggested test case: 00:59 -> 35.5 (a small value of \$h\$ with a large value of \$m\$ is likely to make some implementations fail). \$\endgroup\$ Commented Jun 22, 2019 at 12:37
  • 1
    \$\begingroup\$ Thanks, @Arnauld, you just cost me a byte! :p \$\endgroup\$ Commented Jun 22, 2019 at 23:25

20 Answers 20

14
\$\begingroup\$

JavaScript (ES6), (削除) 41 40 (削除ここまで) 39 bytes

Takes inputs as (h)(m).

h=>m=>((x=4+h/3-m*.55/9)&2?12-x:x)%4*90

Try it online!

How?

Instead of working directly in the range \$[0..360]\$, we define a temporary variable \$x\$ in the range \$[0..4]\$:

$$x=\left|\frac{4h}{12}+\frac{4m}{60\times12}-\frac{4m}{60}\right|\bmod 4$$ $$x=\left|\frac{4h}{12}-\frac{44m}{60\times12}\right|\bmod 4$$ $$x=\left|\frac{h}{3}-\frac{11m}{180}\right|\bmod 4$$

The angle in degrees is given by:

$$\min(4-x,x)\times90$$

However, the formula is implemented a bit differently in the JS code, as we definitely want to avoid using the lengthy Math.abs() and Math.min().

Instead of computing the absolute value, we force a positive value in \$[0..12]\$ by computing:

$$x'=4+\frac{h}{3}-\frac{11m}{180}$$

And instead of computing the minimum, we determine in which case we are by simply doing a bitwise AND with \2ドル\$ -- and this is why we chose an interval bounded by a power of \2ドル\$ in the first place.

answered Jun 21, 2019 at 17:31
\$\endgroup\$
5
\$\begingroup\$

Jelly, (削除) 14 (削除ここまで) 12 bytes

×ばつ"<¿‘Iæ%ذAH

Try it online!

A monadic link which takes the time as a list of two integers: hour, minute.

Thanks to @JonathanAllan for saving 2 bytes!

Explanation

×ばつ"<¿‘ | Multiply hour by by 60 and minute by 11
 I | Find difference
 æ%ذ | Symmetric mod 360 [equivalent to (x + 360) mod 720 - 360]
 A | Absolute
 H | Half
answered Jun 21, 2019 at 18:14
\$\endgroup\$
5
  • \$\begingroup\$ Symmetric mod? How's that work? \$\endgroup\$ Commented Jun 21, 2019 at 22:21
  • \$\begingroup\$ @Shaggy Very conveniently, it returns the value in interval (-180, 180] that's equivalent (mod 360). Those builtins... \$\endgroup\$ Commented Jun 21, 2019 at 23:19
  • 2
    \$\begingroup\$ Save two bytes by working in half degrees, with the use of ذ for 360 and "<¿‘ for 60,11. Like so ×"<¿‘Iæ%ذAH TIO \$\endgroup\$ Commented Jun 22, 2019 at 17:17
  • \$\begingroup\$ I was going to say 12 characters, but it turns out Windows-1252 (and a few other encodings) can actually encode this in 12 bytes. Between the various non-ASCII characters, I didn't think a single non-Unicode encoding would cover them all, but, apparently, I'm very wrong there. \$\endgroup\$ Commented Jun 24, 2019 at 3:48
  • \$\begingroup\$ @Thanatos Some languages specialized in code-golfing have their own code-pages for the 256 characters they encode in 1 byte each. Jelly is one of them, with this custom code-page. 05AB1E, Charcoal, MathGolf, Stax, etc. are other languages with custom code-pages. Most are indeed based on Windows-1252, though. :) \$\endgroup\$ Commented Jun 24, 2019 at 7:35
4
\$\begingroup\$

Wolfram Language (Mathematica), (削除) 30 (削除ここまで) (削除) 29 (削除ここまで) 28 bytes

5Abs@Mod[#.{6,-1.1},72,-36]&

Try it online!

ungolfed version:

Abs[Mod[#.{30,-5.5}, 360, -180]] &

The argument of the function is # = {h,m} containing the hour and the minute. This length-two list is interpreted as a vector and the dot-product with {30,-5.5} is calculated: #.{30,-5.5} = 30*h-5.5*m. Then we calculate the symmetric modulus of 360 with Mod[#.{30,-5.5}, 360, -180] giving an angle in the interval -180..+180. Abs takes the absolute value thereof.

As all involved operators are linear, we can multiply and divide all appearing numbers however they are most convenient. By pulling a factor of 5 out of the expression and dividing all numbers in the expression by 5, the byte-count is minimized.

answered Jun 22, 2019 at 9:58
\$\endgroup\$
4
\$\begingroup\$

MATL, 18 bytes

30*i5.5*-t360-|hX<

Accepts two inputs of hours followed by minutes. Uses the same method as this answer

Try it at MATL Online

Explanation

 % Implicitly grab first input (hours)
30* % Multiply by 30
i % Explicitly grab second input (minutes)
5.5* % Multiply by 5.5
- % Take the difference
t % Duplicate the result
360- % Subtract 360
| % Take the absolute value
h % Horizontally concatenate
X< % Determine the minimum value
 % Implicitly display the result
answered Jun 21, 2019 at 20:22
\$\endgroup\$
1
  • \$\begingroup\$ Won't this fail for midnight, outputting 180 instead of 0? \$\endgroup\$ Commented Jun 21, 2019 at 22:24
3
\$\begingroup\$

Alchemist, 134 bytes

_->In_h+In_m+720d+360a+f
h->60d
m+11d->
0m+d+a+0r->b
0a+0x->r
d+b+r->r+a
r+0b->
b+0d+0h+0y->5y
b+0d+5y->x
0b+0d+f->Out_x+Out_"."+Out_y

Try it online!

Explanation

_->In_h+In_m+720d+360a+f

Initial setup. Inputs hours and minutes into h and m, sets current angle d to 360 degrees (720 half-degrees), sets up a to compute the principal angle, and sets the output flag.

h->60d
m+11d->

Each hour adds 30 degrees, and each minute subtracts 5.5 degrees.

0m+d+a+0r->b
0a+0x->r

While the r (reverse) flag is not set, each d atom should move one a atom to b. This occurs after the minutes are all used up, to avoid a "race condition". When there are no a atoms remaining, set r to reverse this flow.

Note that this second rule can trigger multiple times, and can even trigger before the initial setup rule. This does not harm anything, so there's no need to prevent this. The 0x condition handles an edge case: when the input is 6:00, there are no a atoms when the program terminates, but there are x atoms if the final result is at least 1 degree.

d+b+r->r+a
r+0b->

The reverse: when the signed angle is greater than 180 degrees, move b atoms to a to decrease the angle to output. Stop reversing when the angle reaches "360".

b+0d+0h+0y->5y
b+0d+5y->x

When all of the degree atoms are used up, divide by 2 to get the angle to output.

0b+0d+f->Out_x+Out_"."+Out_y

After this is done, output exactly once using the f flag from the initial setup.

answered Jun 21, 2019 at 18:31
\$\endgroup\$
3
\$\begingroup\$

Python 3.8 (pre-release), (削除) 45 (削除ここまで) 43 bytes

-2 bytes thanks to Erik.

lambda h,m:min(x:=abs(h%12*30-m*5.5),360-x)

Try it online!

h%12 - hour in 12-hour format
h%12*30 - angle of hour hand at the full hour
m/2 - angle the hour hand moved in m minutes
h%12*30+m/2 - current position of the hour hand as an angle
m*6 - angle of the minute hand (360°/60 = 6°)

answered Jun 21, 2019 at 20:21
\$\endgroup\$
0
3
\$\begingroup\$

Stax, 15 bytes

Ç╢e╛╦¡uøßmì♪║└├

Run and debug it

  • m = number of minutes since midnight
  • d = 5.5 * m
  • The result is min(d % 360, -d % 360).
answered Jun 22, 2019 at 3:46
\$\endgroup\$
3
\$\begingroup\$

C# (Visual C# Interactive Compiler), (削除) 47 (削除ここまで) 45 bytes

h=>m=>(h=(360+h%12*30-m*5.5)%360)<180?h:360-h

Try it online!

answered Jun 22, 2019 at 3:23
\$\endgroup\$
0
2
\$\begingroup\$

Charcoal, 22 bytes

×ばつ5·5N360

Try it online! Link is to verbose version of code. Takes input as two integers. Explanation:

 N First input
 +6 Plus literal 6
 ×ばつ30 Multiplied by literal 30
 − Minus
 N Second input
 ×ばつ5·5 Multiplied by literal 5.5
 % 360 Modulo literal 360
 −180 Subtracted from literal 180
 ↔ Absolute value
I Cast to string
 Implicitly print
answered Jun 21, 2019 at 23:16
\$\endgroup\$
2
\$\begingroup\$

Perl 6, 28 bytes

((*/3-*/9*.55+2)%4-2).abs*90

Try it online!

Uses a few tricks stolen from other answers and calculates

r = abs((h/3 - m/9*0.55 + 2) % 4 - 2) * 90
 = abs((h*30 - m*5.5 + 180) % 360 - 180)
answered Jun 22, 2019 at 9:38
\$\endgroup\$
2
\$\begingroup\$

Python 3, 40 bytes

lambda h,m:180-abs(180-(h*30-m*5.5)%360)

Try it online!

h*30 - angle between noon and the hour h when the minute is 0; if the hour is equal or greater than 12, this angle can be equal or greater than 360°
m*6 - angle between noon and the minute hand
m*.5 - angle the hour hand moved forward from the full hour after m minutes (e.g: if it's 4:24, the hour hand moved forward 12 degrees from the position it was in at 4 o'clock)
h*30-m*5.5 - one of the two angles between the hour hand and the minute hand; the coefficient for m is 5.5 because m*6-m*.5=m*5.5; this is still not the answer because it can be a value greater than 360° (e.g: if h,m=13,0) or less than 0° (e.g: if h,m=12,30)
(h*30-m*5.5)%360 - this modulo takes into account the cases where the computed value above is not between 0 and 360°; this is still not the answer because it could be the ampler of the two angles, while we want the most narrow
180-abs(180-(h*30-m*5.5)%360) - this is the final result; the general rule is that x-abs(x-y) is equivalent to min(y,x-y), which would give the correct result

answered Jun 24, 2019 at 14:25
\$\endgroup\$
2
\$\begingroup\$

Tcl, (削除) 71 (削除ここまで) (削除) 74 (削除ここまで) (削除) 59 (削除ここまで) 54 bytes

{{h m {x (60*$h-$m*11)%720}} {expr min($x,720-$x)/2.}}

Try it online!

saved 5 bytes by using a lambda expression

answered Jun 23, 2019 at 13:48
\$\endgroup\$
1
  • \$\begingroup\$ Shouldn't set f \ be part of main code and account itself for the byte count? \$\endgroup\$ Commented May 8 at 9:03
1
\$\begingroup\$

Python 3, (削除) 58 (削除ここまで) 57 Bytes

-1/-2 Thanks to @Shaggy

h,m=eval(input())
x=(30*h-5.5*m)
print(abs(min(x,360-x)))

Naive implementation, takes input in the form of [6,32]. Some bytes can probably be shaved off the last line especially.

Python 2, (削除) 52 (削除ここまで) 50 Bytes

h,m=input()
x=(30*h-5.5*m)
print abs(min(x,360-x))
answered Jun 21, 2019 at 17:22
\$\endgroup\$
5
  • \$\begingroup\$ 30*h-5.5*m should save you a couple of bytes. \$\endgroup\$ Commented Jun 21, 2019 at 17:48
  • 1
    \$\begingroup\$ A def-style function should save some bytes as well. \$\endgroup\$ Commented Jun 21, 2019 at 17:58
  • \$\begingroup\$ @negativeseven from the challenge wording it seemed like it should be using stdin/stdout \$\endgroup\$ Commented Jun 21, 2019 at 18:13
  • \$\begingroup\$ You can drop the parentheses on the 2nd line. \$\endgroup\$ Commented Jun 21, 2019 at 18:27
  • \$\begingroup\$ The solutions actually need a few modifications (Python 2) to work correctly. The result should be less than or equal to 180, and greater than or equal to 0. \$\endgroup\$ Commented Jun 21, 2019 at 19:33
1
\$\begingroup\$

Perl 5 -MList::Util=min -p, 37 bytes

$_=abs<>*5.5-$_%12*30;$_=min$_,360-$_

Try it online!

Takes input as hours followed by minutes on a separate line because it saved a few bytes.

answered Jun 21, 2019 at 21:17
\$\endgroup\$
1
  • \$\begingroup\$ OK. Fixed that. \$\endgroup\$ Commented Jun 22, 2019 at 18:34
1
\$\begingroup\$

05AB1E, 16 bytes

60*+5.5*D(‚360%ß

Takes hours as first input, minutes as second.

Try it online or verify all test cases.

Explanation:

Basically implements the following formula:

$$t = (60h+m)×ばつ5.5$$ $$r = min(t\bmod360,-t\bmod360)$$

60* # Multiply the (implicit) hours-input by 60
 + # Add it to the (implicit) minutes-input
 5.5* # Multiply it by 5.5
 D(‚ # Pair it with it's negative
 360% # Take modulo-360 on both
 ß # And then pop and push the minimum of the two
 # (which is output implicitly as result)
answered Jun 25, 2019 at 6:39
\$\endgroup\$
1
\$\begingroup\$

[R] , 45 bytes

 function(h,m)min(t=(60*h+m)*5.5%%360,-t%%360)
answered Jun 25, 2019 at 8:16
\$\endgroup\$
1
\$\begingroup\$

Japt, 16 bytes

*FÑ aV*51⁄2
mUa360

Try it

*FÑ aV*51⁄2 :Implicit input of integers U=h and V=m
*F :Multiply U by 15
 Ñ :Multiply by 2
 a :Absolute difference with
 V*51⁄2 :V multiplied by 5.5
mUa360 :Reassign to U
m :Minimum of U and
 Ua360 :Absolute difference of U and 360
answered Jun 21, 2019 at 17:39
\$\endgroup\$
1
\$\begingroup\$

Uiua SBCS , 29 bytes

×ばつ6_30

Try it here!

Expects an array, minutes first.

answered Jul 28, 2024 at 14:50
\$\endgroup\$
0
\$\begingroup\$

><>, 17 bytes

b*6ドルa**-:0)12,-*n

Try it online! (6:32)

Takes input as h, m on the stack.

Explanation

b*6ドルa**-:0)12,-*n
b* Multiplies m by 11
 $ Swaps m & h
 6a** Multiplies h by 60
 - Subtracts m & h (v)
 :0) Checks if v > 0 (b=0/1)
 12,- Subtracts .5 from b (-.5/.5)
 * Multiplies v by b (halve & abs)
 n Outputs result
b* Errors
answered Jun 22, 2019 at 23:23
\$\endgroup\$
0
\$\begingroup\$

Pyret, 59 bytes

{(h,m):x=(30 * h) - (m * 5.5)
num-abs(num-min(x,360 - x))}
answered Jul 9, 2019 at 12:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.