18
\$\begingroup\$

Your task is to make a program or function that takes a nonnegative integer (or a different convenient format to represent it) that represents an angle measure in degrees from 0 to 180 (inclusive) as input and outputs every possible time (in hours and minutes; no seconds) on an analog clock where the measure of the smaller angle between the hour hand and minute hand is equal to the inputted angle measure.

Rules

  • Output can be a list of times, a string of the times with separators, or multiple outputs of times.
  • The times can be formatted in any way that can be identifiable as clock times by humans, such as hh:mm or a list of the hours and minutes.
  • The times should be from 12:00 to 11:59 (e.g. 0:00 and 22:00 are invalid outputs).
  • Standard loopholes apply.
  • This is , so the shortest code in bytes in each language wins.

Test cases

Input    | Output
---------|------------
0        | 12:00
90       | 3:00, 9:00
180      | 6:00
45       | 4:30, 7:30
30       | 1:00, 11:00
60       | 2:00, 10:00
120      | 4:00, 8:00
15       | 5:30, 6:30
135      | 1:30, 10:30
1        | 4:22, 7:38
42       | 3:24, 8:36
79       | 3:02, 8:58
168      | 1:36, 10:24
179      | 1:38, 10:22
115      | 1:50, 10:10

Interestingly, there are only two possible times in hours and minutes (except for 0 and 180 degrees) for every integer (or number with a fractional part of 0.5) degree input and on an analog clock the times represent horizontally flipped images of each other.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Suggest the watch photographers preferred times of 10:10/10:09 as testcases! :D \$\endgroup\$
    – Noodle9
    Apr 18 at 15:02
  • 3
    \$\begingroup\$ Just to clarify: there are 11 or 22 possible times for each angle, but only 1 or 2 of those have a whole number of minutes. \$\endgroup\$
    – Nitrodon
    Apr 18 at 15:44
  • \$\begingroup\$ @Nitrodon Yes. Seconds are not dealt with for this challenge. \$\endgroup\$
    – Yousername
    Apr 18 at 15:51
  • \$\begingroup\$ When there are two times, does the order matter? I guess not? \$\endgroup\$
    – Steffan
    Apr 18 at 19:52
  • \$\begingroup\$ @Steffan It does not matter. \$\endgroup\$
    – Yousername
    Apr 18 at 20:24

17 Answers 17

7
\$\begingroup\$

Jelly, 22 bytes

60Ḷ12pד<¿‘Hạ/eʋƇØ°_,Ɗ

A monadic Link that accepts a non-negative integer in \$[0,180]\$ and yields a list of pairs of [hour, minute] of a twelve-hour analogue clock.

Try it online! Or see the test-suite.

How?

If we label straight up (12:00) as \$0\$ degrees, then at a given exact minute of \$h\$ hours and \$m\$ minutes, the minute hand is at \$\frac{360 m}{60}\$, while the hour hand is at \$\frac{360 h}{12}+\frac{360m}{60 \times 12}\$ degrees. A clockwise angle between the hour hand and minute hand is, therefore:

$$A=\frac{360 h}{12}+\frac{360m}{60 \times 12}-\frac{360 m}{60}$$ $$A=30h+\frac{m}{2}-6m$$ $$A=30h-\frac{11m}{2}$$

The code makes all of the times as [h, m] pairs and filters them for when the absolute value of the above angle \$A\$ is either equal to the input or \$360\$ minus the input.

60Ḷ12pד<¿‘Hạ/eʋƇØ°_,Ɗ - Link: integer, A in [0,180]
60                     - sixty
  Ḷ                    - lowered range -> [0..59]
   12                  - twelve
     p                 - Cartesian product -> Times = [[1,0],...,[1,59],...,[12,59]]
                     Ɗ - last three links as a monad - f(A):
                 Ø°    -   360
                   _   -   minus A
                    ,  -   paired with A -> Angles=[360-A,A]
                Ƈ      - filter keep those Times for which:
               ʋ       -   last four links as a dyad - f(Time,Angles):
       “<¿‘            -     code-page indices      = [60,11]
      ×                -     Time times [60,11]    -> [60h,11m]
          H            -     halve                 -> [30h,11m/2]
             /         -     reduce by:
            ạ          -       absolute difference -> abs(30h-11m/2)
              e        -     exists in Angles?
\$\endgroup\$
2
  • \$\begingroup\$ As stated in the rules, the times should be from 12:00 to 11:59, so the hour number can not be 0. This also only outputs one possible time for inputs 90, 30, 60, etc. \$\endgroup\$
    – Yousername
    Apr 18 at 16:03
  • \$\begingroup\$ @Yousername I realised about the bug while writing up a test suite for my previous answer, that's fixed and so is the \$12\$ vs \$0\$ hour output formatting issue. \$\endgroup\$ Apr 18 at 16:42
4
\$\begingroup\$

Wolfram Language (Mathematica), 44 bytes

-2 bytes thanks to @Steffan.

{}⋃Mod[458{#,-#},720,60]~IntegerDigits~60&

Try it online!

\$\endgroup\$
1
4
\$\begingroup\$

PARI/GP, 44 bytes

a->Set([[(b\60-1)%12+1,b%60]|b<-458*[a,-a]])

Attempt This Online!

The %12 trick is stolen from G B's Ruby answer.

\$\endgroup\$
2
  • \$\begingroup\$ Any reason why you chose 458 and not 262? \$\endgroup\$
    – Neil
    Apr 19 at 7:42
  • \$\begingroup\$ @Neil No reason. \$\endgroup\$
    – alephalpha
    Apr 19 at 7:44
3
\$\begingroup\$

Ruby, 82 79 55 47 bytes

->d{[k=262*d,-k].map{|c|[c/60%-12+12,c%60]}|[]}

Try it online!

Stolen from various other answers: the angle between the two hands is increased by 1 degree after 4h22m.

\$\endgroup\$
3
\$\begingroup\$

R, 61 60 55 bytes

\(a,b=458*c(a,-a))unique(cbind((b%/%60-1)%%12+1,b%%60))

Attempt This Online!

Port of @alephalpha's answer.

Outputs as a matrix with hours in the first column and minutes in the second.


R, 84 72 bytes

Edit: -9 bytes thanks to @Kirill L..

\(a)t(which(outer(1:12,0:59,\(x,y)abs(30*x-5.5*y)%in%c(a,360-a)),T))-0:1

Attempt This Online!

Outputs as a matrix with hours in the first row and minutes in the second.

The formula looks exactly like in Jonathan Allan's answer.

\$\endgroup\$
3
  • \$\begingroup\$ I think you can replace your abs argument with x%*%c(30,-5.5) to save a few. \$\endgroup\$
    – Kirill L.
    Apr 18 at 19:46
  • \$\begingroup\$ Or rather use outer for 75 bytes \$\endgroup\$
    – Kirill L.
    Apr 18 at 20:31
  • \$\begingroup\$ @KirillL. that's a nice idea - thanks! \$\endgroup\$
    – pajonk
    Apr 19 at 4:26
2
\$\begingroup\$

JavaScript (ES6), 79 78 bytes

Only works in locales with UTC that use the 12 hour clock.

f=
n=>(n%180?[262,458]:[262]).map(m=>new Date(m*n*6e4).toTimeString().slice(0,5))
<input type=number min=0 max=180 oninput=o.textContent=f(this.value|0)><pre id=o>

Longer version that works everywhere, except on days with DST transitions:

f=
n=>(n%180?[262,458]:[262]).map(m=>new Date(0,0,0,0,m*n).toLocaleString('en-US',{timeStyle:'short'}).slice(0,5))
<input type=number min=0 max=180 oninput=o.textContent=f(this.value|0)><pre id=o>

Longest version that always works everywhere:

f=
n=>(n%180?[262,458]:[262]).map(m=>new Date(m*n*6e4).toLocaleString('en-US',{timeStyle:'short',timeZone:'utc'}).slice(0,5))
<input type=number min=0 max=180 oninput=o.textContent=f(this.value|0)><pre id=o>

Explanation: The angle between the hands is at 04:22 and its reflection, which correspond to 262 and 458 minutes past midnight. Any larger angle can be obtained by simply multiplying the desired angle by those two numbers of minutes.

Edit: Saved 1 byte thanks to @MatthewJensen.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ It doesn't work for 0 as input, though I personally think that banning 00:00 is totally arbitrary. Anyway I would love an explanation of the algorithm. What's going on with those dates? \$\endgroup\$
    – anotherOne
    Apr 18 at 18:39
  • \$\begingroup\$ @anotherOne Whoops, I forgot that function was 24-hour. I've changed it to use a different function now. \$\endgroup\$
    – Neil
    Apr 18 at 21:08
  • \$\begingroup\$ (n%180?[262,458]:[262]) is shorter than using slice() \$\endgroup\$ Apr 18 at 22:08
  • \$\begingroup\$ You could also use [262,458].slice(~n%180) \$\endgroup\$ Apr 18 at 22:31
  • \$\begingroup\$ I would have never thought about just multiplying the minutes of . Nice one. \$\endgroup\$
    – anotherOne
    Apr 18 at 23:41
2
\$\begingroup\$

Haskell, 65 64 bytes

f a=[[h,m]|h<-[1..12],m<-[0..59],elem(abs(h*30-5.5*m))[a,360-a]]

Try it online!

Ironically, I wrote this to try some taste of Curry, but it failed with some errors I struggle to understand. Worked in Haskell though...

Thanks to pajonk for -1.

\$\endgroup\$
5
  • \$\begingroup\$ tio link is broke \$\endgroup\$
    – Steffan
    Apr 18 at 19:33
  • \$\begingroup\$ Sorry, fixed now \$\endgroup\$
    – Kirill L.
    Apr 18 at 19:34
  • \$\begingroup\$ Float is not an instance of Enum in Curry. \$\endgroup\$
    – alephalpha
    Apr 19 at 0:03
  • \$\begingroup\$ Shouldn't 11/2 -> 5.5 work for -1 byte? Try it online! \$\endgroup\$
    – pajonk
    Apr 19 at 5:18
  • \$\begingroup\$ @pajonk, Hehe, apparently I managed to notice the same when playing with your R answer, but not in my own :) \$\endgroup\$
    – Kirill L.
    Apr 19 at 7:16
2
\$\begingroup\$

Charcoal, 45 bytes

NθEΦ³⁶⁰№﹪×¹¹⟦±ιι⟧³⁶⁰θ⪫E⟦∨÷ι³⁰¦¹²⊗﹪ι³⁰⟧﹪%02dλ:

Try it online! Link is to verbose version of code. Explanation: The angle between the hands increases by 11° every two minutes.

Nθ

Input the angle.

EΦ³⁶⁰

Loop over all times from 12:00 to 11:58 in multiples of 2 minutes.

№﹪×¹¹⟦±ιι⟧³⁶⁰θ

Keep only those times where the angle between the hands or its negation equals the input.

⪫E⟦∨÷ι³⁰¦¹²⊗﹪ι³⁰⟧﹪%02dλ:

Format the doubled number of minutes as a time.

If outputting 12:00 or 06:00 twice for inputs of 0 and 180 respectively had been legal, then for 41 39 bytes:

NθE×⟦²⁶²¦⁴⁵⁸⟧θ⪫E⟦⊕﹪⊖÷ι⁶⁰¦¹²﹪ι⁶⁰⟧﹪%02dλ:

Try it online! Link is to verbose version of code. Explanation: The number of minutes is given by the angle multiplied by 262 or 458 (effectively modulo 720, but this is calculated by taking the hour modulo 12, with a zero result becoming 12).

\$\endgroup\$
2
\$\begingroup\$

JavaScript (V8), 77 72 bytes

-5 bytes thanks to Arnauld!

a=>new Set([a*262,a*458].map(m=>(m/60%12|0||12)+(m%60>9?':':':0')+m%60))

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 72 bytes if you return a Set. \$\endgroup\$
    – Arnauld
    Apr 19 at 9:03
2
\$\begingroup\$

Vyxal M, 22 bytes

6d59Ẋ'30₀›½"*÷εkR⁰-⁰"c

Try it Online!

You can also run all the test cases but be prepared to wait at least a minute.

How?

6d59Ẋ'30₀›½"*÷εkR⁰-⁰"c
6d                     # Push 6 doubled, which is 12 (this is to avoid having to put a space after it)
  59                   # Push 59
    Ẋ                  # Cartesian product of these two numbers, which are implicitly cast to inclusive zero ranges
     '                 # Filter this list for:
      30               #  Push 30
        ₀›             #  Push 10 + 1, which is 11. This is to avoid having to put a space before it
          ½            #  Halve to make 5.5
           "           #  Pair these two values to [30, 5.5]
            *          #  Multiply both by the current item
             ÷         #  Push both values of the multiplied pair to the sstack
              ε        #  Absolute difference of the two
               kR⁰-    #  Push 360 minus the input
                   ⁰"  #  Pair with the input
                     c #  Does this list contain the absolute difference pushed earlier?
\$\endgroup\$
1
\$\begingroup\$

Zsh, 81 bytes

>{-,}{$[x=$1*2],$[720-x]}
eval h={1..12}\;m={0..59}';<$[h%12*60-m*11]&&<<<$h:$m;'

Attempt This Online!

Damn floating point errors!

\$\endgroup\$
1
\$\begingroup\$

Retina 0.8.2, 89 bytes

.+
$*_¶$&$*_
\G_
262$*
_
458$*
1{720}

D`
G`.
%`^(.{60})*(.*)
$#1:0$.2
%`^0
12
:0(..)
:$1

Try it online! Outputs times on separate lines but link is to test suite that joins with comma for convenience. Explanation:

.+
$*_¶$&$*_

Convert to unary twice.

\G_
262$*
_
458$*

Multiply the first copy by 262 and the second by 458.

1{720}

D`
G`.

Reduce modulo 720 and deduplicate.

%`^(.{60})*(.*)
$#1:0$.2
%`^0
12
:0(..)
:$1

Format as a time.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 51 bytes

lambda n:{(n*i//60%-12+12,n*i%60)for i in(262,458)}

Try it online!

Ported from various other answers.

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 25 bytes

12L59Ýâʒ30T>;‚*ÆÄU360α‚Xå

Port of @JonathanAllan's Jelly answer, and the output-format is also the same: a (1 or 2-sized) list of pair(s) of \$[h,m]\$.

Try it online or verify all test cases.

Explanation:

12L           # Push a list in the range [1,12]
59Ý           # Push a list in the range [0,59]
   â          # Cartesian product of both lists to create all possible pairs
    ʒ         # Filter these pairs by:
     30       #  Push 30
     T>;      #  Push 5.5 (10 +1 /2)
        ‚     #  Pair them together
         *    #  Multiply the values in the pairs [30h,5.5m]
          Æ   #  Reduce this pair by subtracting
           Ä  #  Convert it to its absolute value
            U #  Pop and store this value in variable `X`
     360α     #  Get the absolute difference of the (implicit) input and 360
         ‚    #  Pair the (implicit) input with this 360-input
          Xå  #  Check if value `X` is in this pair
              # (after which the filtered result is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Excel, 98 bytes

=LET(t,ROW(1:720)/1440,h,HOUR(t),m,MINUTE(t),a,ABS(30*h-11*m/2),FILTER(h&","&m,(a=A1)+(a=360-A1)))

Input is in the cell A1. Output is wherever the formula is and - usually - the cell below it.

Screenshot

The LET() function allows you to define variables for later reference. Here's each piece explained.

  • t,ROW(1:720)/1440 an array of time values from 0.0 to 0.5 (noon) broken into 1 minute long pieces.
  • h,HOUR(t) an array the same length as t but just the hours.
  • m,MINUTE(t) an array the same length as t but just the minutes.
  • a,ABS(30*h-11*m/2) math based on other answers here.
  • h&","&m combines the two arrays into the output format desired.
  • (a=A1)+(a=360-A1) checks if the math matches the input angle.
  • FILTER(~,~) returns just the outputs where the match matched the angle.

I also found this solution that clocks in at 103 bytes and outputs the results into a single cell.

=LET(h,COLUMN(A:L)-1,m,ROW(1:60)-1,a,ABS(30*h-11*m/2),TEXTJOIN("
",1,IF((a=A1)+(a=360-A1),h&","&m,"")))
\$\endgroup\$
1
\$\begingroup\$

Desmos, 66 61 bytes

i=[262,458]
f(n)=(mod(floor(in/60),-12)+12,mod(i,60)n).unique

Try it on Desmos!

-5 bytes thanks to Aiden Chow

\$\endgroup\$
0
\$\begingroup\$

C#, 71 bytes

(int a)=>new[]{458*a,262*a}.Select(x=>((x/60+11)%12+1,x%60)).Distinct()

Try it online!

Based on various other answers. Like Jitse's Python 3 solution, I'm using both magic numbers 262 and 458 to get the answers in minutes, modulo 720 minutes. For the hours, I'm using the trick to add 11, take the remainder of dividing by 12, and then add 1 to get a value from 1 to 12. Since duplicate answers for 0 and 180 aren't allowed, I'm using the Distinct function from Linq.

Community guidelines for C# require a type for lambdas hence the (int a)=>, if untyped lambdas are OK we can make that a=> for a saving of 6 bytes.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.