15
\$\begingroup\$

Let's begin with a thought experiment. You have a clock and a timer, in which you start the timer when the clock shows exactly hh:mm.00.

  • Clock: The clock employs 24-hour time. So the range of hh is 0<=h<23. (Because 23 inputs are unsolvable, you aren't required to handle that)
  • Timer: It starts exactly on 00.00. The number to the right of . isn't milliseconds; it's seconds.

What you need to do is to find out when the two numbers represented by clock time (hh:mm) is respectively equal to the timer time (mm.ss); e.g. 13:24 is "respectively equal" to 13.24. There can potentially be more than one time.

An example

Say the input is 1:59.

Clock: 1:59
Timer: 0.00   (The timer just started)

...
Clock: 1:59
Timer: 0.59   (59 seconds later...)

...

Clock: 2:00
Timer: 1.00   (As the timer's second section rounds up to the minute section, the clock time gets incremented by a minute. And the 59 minutes in the clock section gets rounded up to the hour section, hence the 2:00.)

...
Clock: 2:00
Timer: 1.59 (59 seconds later...)

...
Clock: 2:01
Timer: 2.00 (The timer minute gets rounded up, as the clock time increments by a minute)

...
Clock: 2:01
Timer: 2.01 (Now the clock time is "respectively equal" to the timer time)

Therefore you need to output 2:01 for the 1:59 input.

Examples

Here is a sample program I use to check my test cases.

0:59 -> 0:59 (or 1:00, if your answer supports that)
1:30 -> 1:31
2:59 -> 3:02
1:59 -> 2:01
3:58 -> 4:02
22:01->22:23

Specifications

  • Although in the test cases, the input is taken as hh:mm, you can nevertheless take input in a list, e.g. [hh,mm], or any format suitable for your answer.
  • You can output the time in the format [mm,ss].
  • You could start two physical timers, but you need to optimize their speed somehow. Your code running all of the test cases must terminate in 60 seconds.
  • You are allowed to take input/output as base 60.
  • You don't need to handle unsolvable inputs. I.e. The hour section in the clock will never be 23.
  • If you find more than one time for a specific test case, you can output any of them.
\$\endgroup\$
5
  • \$\begingroup\$ Is 1:00 also a valid output for 0:59? \$\endgroup\$
    – Nitrodon
    Commented Jul 17, 2020 at 14:19
  • \$\begingroup\$ @Nitrodon Yes it is. Edited to reflect that. \$\endgroup\$
    – user92069
    Commented Jul 17, 2020 at 14:22
  • \$\begingroup\$ Why would hh == 23 be unsolvable? from 23:00 to 23:36 there are valid solutions. \$\endgroup\$
    – kriegaex
    Commented Jul 19, 2020 at 3:17
  • \$\begingroup\$ Nice follow-up questions would be: How many start times with more than one solution like 0:59 exist? List them. What is the maximum number of solutions for any given start time? \$\endgroup\$
    – kriegaex
    Commented Jul 19, 2020 at 3:38
  • \$\begingroup\$ No, there are 23 cases like that: 0:59, 1:58, 2:57, ..., 22:37. And as for what I said before, there are 23:00 → 23:23 up to 23:36 → 23:59. \$\endgroup\$
    – kriegaex
    Commented Jul 19, 2020 at 7:33

10 Answers 10

15
\$\begingroup\$

Raku, 14 12 11 bytes

0+|*/.98334

Try it online!

Since we know the bounds of the input, we can substitute a constant operation and a floor on the input in base 60. That number by the way is around 1358/1381, which is the maximum the input differs from the output in base 60. There may be a smaller constant, or at least a smaller way to represent it. For reference, the shortest constant you can multiply by, rather than divide, is 1.01694.

\$\endgroup\$
3
  • \$\begingroup\$ Lovely. Looks like you can also leave-out the 0 for 11 bytes. \$\endgroup\$ Commented Jul 17, 2020 at 11:27
  • \$\begingroup\$ @DominicvanEssen a couple of minutes too late ;) \$\endgroup\$
    – Jo King
    Commented Jul 17, 2020 at 11:31
  • 3
    \$\begingroup\$ The constant .98334 is just a smidgen bigger than 59/60. While 59/60 exactly doesn't work, any very tiny increase from it does. It just needs to be not too large so as to mess up in the range of test case. Conversely, for 1.01694, anything a tiny bit below 60/59 would work. It seems like this would be hard to express shorter than you have with it written out though. \$\endgroup\$
    – xnor
    Commented Jul 17, 2020 at 11:57
9
\$\begingroup\$

Python 3.8, 40 36 bytes

lambda h,m:(d:=h+(h+m)//60,(d+m)%60)

Try it online!

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

MathGolf, 11 9 bytes

+α_╙╟/+╟%

Port of the approach used in @ovs' Python answer.

Input as two loose integers. Output as a pair.

Try it online.

Explanation:

+         # Add the two (implicit) inputs together: h+m
 α        # Wrap two items in a list, which will use the (implicit) first input: [h,h+m]
  _╙      # Duplicate it, and pop and push the maximum: h+m
    ╟/    # Integer-divide it by 60: (h+m)//60
      +   # Add it to both values in the list: [h+(h+m)//60,h+m+(h+m)//60]
       ╟% # Take modulo-60 on both: [(h+(h+m)//60)%60,(h+m+(h+m)//60)%60]
          # (after which the entire stack joined together is output implicitly as result)
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 13 10 bytes

ηO¤60÷+60%

Port of the approach used in @ovs' Python answer.

I/O as a pair of integers.

Try it online or verify all test cases.

Explanation:

η          # Get the prefixes of the (implicit) input-pair: [h,m] → [[h],[h,m]]
 O         # Take the sum of each inner list: [h,h+m]
  ¤        # Push the last item (without popping): h+m
   60÷     # Integer-divide it by 60: (h+m)//60
      +    # Add it to both values: [h+(h+m)//60,(h+m)+(h+m)//60]
       60% # Take modulo-60 on both: [(h+(h+m)//60)%60,((h+m)+(h+m)//60)%60]
           # (after which the result is output implicitly)
\$\endgroup\$
4
\$\begingroup\$

R, 42 bytes

function(h,m)c(t<-(h*60+m)/59,60*t%%1)%/%1

Try it online!

Version 2: -3 bytes thanks to clarification that we don't need to output the first match when the timer & clock show the same numbers.
So this version outputs the second match for an input of 0:59 (in other words, 1:00instead of the first match at 0:59), and similarly for all other outputs that can end with :59 or :00.

R, Version 1: 49 45 bytes

function(h,m)c(t<-(h+m/60)*6/5.9,60*t%%1)%/%1

Try it online!

Outputs the first timer-clock match (so, always a match ending 0:59 instead of a subsequent match ending :00).

This exploits the floating-point rounding of *6/5.9 to slightly less than *60/59, but using the same number of characters. This effectively gives us a floor-like result that rounds-down exact integers in the output (the desired behaviour). Using *60/59 gives an exact floating-point result and so doesn't do this.

(Frustratingly, though, it still isn't as short as simply porting ovs's approach for 43 bytes). Version 2 (above) is shorter.

\$\endgroup\$
2
  • \$\begingroup\$ Don‘t wont to cause any frustration, but my approach can be 41 bytes :P. \$\endgroup\$
    – ovs
    Commented Jul 19, 2020 at 14:05
  • \$\begingroup\$ @ovs Ha ha! Well done! I will struggle some more, then! \$\endgroup\$ Commented Jul 19, 2020 at 14:53
3
\$\begingroup\$

Retina 0.8.2, 69 bytes

\d+
$*
^
$'
+`:1{60}
1:
(1*):1*:
$.1:$1
:(1{60})?(1{10})*(1*)
:$#2$.3

Try it online! Link includes test cases. Uses @ovs' formula. Explanation:

\d+
$*

Convert to unary.

^
$'

Duplicate the input, which effectively sums the two values together.

+`:1{60}
1:

Add a sixtieth of the sum to the first value.

(1*):1*:
$.1:$1

Delete the remainder of the sum, convert the first value to decimal, and also add it to the second value (still in unary).

:(1{60})?(1{10})*(1*)
:$#2$.3

Convert the second value modulo sixty to two decimal digits.

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

Japt, 11 (10?) bytes

Port of Jo's Raku solution

ì60'*1.0#©4

Try it

This might work for 10 but I haven't fully tested it:

ì60'*6/5.9

Try it

ì60'*1.0#©4     :Implicit input of integer array
ì60             :Convert from base-60
   '*           :Multiply by
     1.0#©4     :  1.01694
                :Implicitly convert back to base-60 and output
\$\endgroup\$
2
\$\begingroup\$

Javascript, 43 42 bytes

h=>m=>[~~(h+(i=h+m)/60)%60,~~(61*i/60)%60]

Port of the approach used in @ovs' Python answer.

Input: two integers, output: List of [mm,ss]

Try it online.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Save a byte by currying the parameters. \$\endgroup\$
    – Shaggy
    Commented Jul 18, 2020 at 11:04
2
\$\begingroup\$

JavaScript (V8), 28 26 bytes

h=>m=>[h+=h+m>59,(h+m)%60]

Based off of SomoKRoceS' JavaScript answer

Input: two integers, output: List of [mm,ss]

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You don't need the parentheses after the +=. \$\endgroup\$
    – Shaggy
    Commented Jul 23, 2020 at 22:40
  • \$\begingroup\$ Thanks @Shaggy, didn't see that anymore. They were a leftover from a previous iteration where they were needed. \$\endgroup\$
    – Thomas
    Commented Jul 24, 2020 at 6:52
1
\$\begingroup\$

J, 23 bytes

Based on Jo King's Raku answer. Input and output is in the form of 2-vectors.

<.@(1.01694&*)&.(60&#.)

Explanation:

              &.(60&#.) NB. Under base 60,
   (1.01694&*)          NB. multiply by the magic number,
<.@                     NB. then floor the result.

Try it online!

\$\endgroup\$

Your Answer

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