Match the Striking Clock

14

1

Introduction:

At home we have a clock that strikes the stated amount at each hour, but also strikes once at every half-hour. So from 0:01 to and including 12:00 it strikes in this order:

1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12

Challenge:

Given an integer n, output a list of time-frames in which the total strikes are equal to n. In addition, always start at least 1 minute before this time-frame and end at least 1 minute after this time-frame (and at most 29 minutes).
For example, if the input is n=8, the output could be:

[00:59-03:01, 01:29-03:31, 02:59-04:01, 05:29-06:31, 06:29-07:01, 06:59-07:31, 07:59-08:01]

For which these time-frames have the following sums, all equaling 8:

[1+1+2+1+3, 1+2+1+3+1, 3+1+4, 1+6+1, 1+7, 7+1, 8]

Challenge rules:

  • Output is flexible. You can output as Time (or Date/DateTime) objects, timestamps, strings (with or without leading zeroes), decimals with .29/.31/.59/.01 (i.e. 0.29-3.01 instead of 00:29-03:01), etc. As long as it's clear it's before and after the time-frame.
    In addition, you can choose the amount yourself. In all my examples I use 1 minute, but you can also choose 5 minutes, 15 minutes, etc. This also means you can use .4/.6/.9/.1 (i.e. 0.4-3.1 instead of 00:24-03:06) for example. The list is also flexible. Can be a list/collection, array, delimiter-separated string, printing per line to STDOUT, etc.
    Please state which output choice you've made. Note: You are not allowed to output the sums of the time-frames like above, this is only mentioned as clarification. You must output the time-frames, including slightly before and after it.
  • The strikes do wrap around from 12:00 to 00:30. So if n=14, two of the time-frames are 11:29-00:31 and 11:59-01:01.
  • Input will be in the range 1 <= n <= 90, where 90 is the total sum of all possible strikes.
  • The time-frames you return can be in any order.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, please add an explanation if necessary.

Test cases:

(all using 1 minute before / after the time-frames and leading zeroes)

Input: 8
Ouput:
[00:59-03:01, 01:29-03:31, 02:59-04:01, 05:29-06:31, 06:29-07:01, 06:59-07:31, 07:59-08:01]

Input: 14
Output:
[00:29-04:01, 00:59-04:31, 02:59-05:01, 04:29-06:31, 05:59-07:01, 11:29-00:31, 11:59-01:01]

Input: 90
Output:
[00:29-00:01, 00:59-00:31, 01:29-01:01, 01:59-01:31, 02:29-02:01, 02:59-02:31, 03:29-03:01, 03:59-03:31, 04:29-04:01, 04:59-04:31, 05:29-05:01, 05:59-05:31, 06:29-06:01, 06:59-06:31, 07:29-07:01, 07:59-07:31, 08:29-08:01, 08:59-08:31, 09:29-09:01, 09:59-09:31, 10:29-10:01, 10:59-10:31, 11:29-11:01, 11:59-11:31]

Input: 1
Output:
[00:29-00:31, 00:59-01:01, 01:29-01:31, 02:29-02:31, 03:29-03:31, 04:29-04:31, 05:29-05:31, 06:29-06:31, 07:29-07:31, 08:29-08:31, 09:29-09:31, 10:29-10:31, 11:29-11:31]

Input: 2
Output:
[00:29-01:01, 00:59-01:31, 01:59-02:01]

Kevin Cruijssen

Posted 2018-01-05T08:17:19.900

Reputation: 67 575

1I'd go for whatever is most flexible. This includes decimal hour numbers, as long as the result numbers fall between two ringing times. – Adám – 2018-01-05T10:09:44.660

@Adám Guess you're right. I've edited my answer accordingly. You should have at least 1 minute and at most 29 minutes, so .4/.6/.9/.1 is allowed (being 6 minutes like you've stated: :24/:36/:54/:06). – Kevin Cruijssen – 2018-01-05T10:18:09.053

1Maybe mention that the time pairs may be returned in any order? – Adám – 2018-01-05T11:13:08.950

Ok n is in 0..90, I not find clear what is the time period for calculate the n strikes: It is 12 hours? They are 24 hours? Are 48 hours? Than are allowed return time in the format 0..24:0..60 ? – RosLuP – 2018-01-07T14:59:09.983

@RosLuP The time frame is a regular analog clock, so from 00:01 to 12:00. So instead of 0..24:0..60, it should be 0..12:0..60. How that clears any confusion. – Kevin Cruijssen – 2018-01-07T18:03:34.807

Answers

3

APL (Dyalog Classic), 34 bytesSBCS

∪12|.4 .1∘+¨.5×⍸⎕=⍉∘.-⍨+\,⍪⍨1,⍪⍳12

Try it online!

This solution uses ⎕io←1 (1-based indexing).

From right to left:

⍳12 is 1 2 3...12

turns it into a tall thin 12x1 matrix

1, adds a column of 1s to the left

⍪⍨ concatenates the same matrix vertically, so it's now a 24x2 matrix

, flattens the matrix in row-major order, it becomes a vector of size 48: 1 1 1 2 1 3...1 12 1 1 1 2...1 12

+\ partial sums: 1 2 3 5 6 9...

∘.-⍨ the differences between each pair of elements, a 48x48 matrix

transpose

⎕= a 48x48 boolean matrix with 1s wherever the evaluated input () occurs

the pairs of coordinates of where the 1s are

.5× halve them

.4 .1∘+¨ add 0.4 to the first and 0.1 to the second coordinate in each pair

12| modulo 12

unique

ngn

Posted 2018-01-05T08:17:19.900

Reputation: 11 449

What is the time interval represented by .1 in the output? Also, nice answer. – Erik the Outgolfer – 2018-01-07T18:26:30.390

2

Oh, and this is what makes it possible for this to be 34 bytes, maybe want to link to it or write <sup>SBCS</sup> just like Adám's answer.

– Erik the Outgolfer – 2018-01-07T18:28:06.023

@EriktheOutgolfer the problem explicitly allows .1/.4/.6/.9 instead of :01/:29/:31/:59. I don't need special encoding for this answer, it's in Dyalog Classic which has its own single-byte encoding. – ngn – 2018-01-07T18:45:08.497

isn't in Dyalog Classic. And yes, I do know that's explicitly allowed, I just wanted to know how many minutes is 0.1 in the output ;) – Erik the Outgolfer – 2018-01-07T18:45:54.993

@EriktheOutgolfer "SBCS" added, thanks; .1×60 minutes is 6 minutes – ngn – 2018-01-07T18:56:38.837

@KevinCruijssen done – ngn – 2018-01-16T15:37:05.410

5

JavaScript (ES6), 104 bytes

Prints time intervals in H.MM,H.MM format.

F=(n,f=0,s=n,t=f++)=>t<f+23?F(n,f,s-=t&1||t/2%12+1,++t,s||alert([f/2%12+.01,-~t/2%12+.01])):f<24&&F(n,f)

Try it online!

Uses essentially the same algorithm as the non-recursive version below.


Non-recursive version, 117 bytes

Outputs a space-delimited string of time intervals in H.MM,H.MM format.

n=>[...Array(24)].map((_,f,a)=>a.map(_=>(s-=t++&1||t/2%12+.5)||(r+=[-~f/2%12+.01,-~t/2%12+.01]+' '),s=n,t=f),r='')&&r

Test cases

let f =

n=>[...Array(24)].map((_,f,a)=>a.map(_=>(s-=t++&1||t/2%12+.5)||(r+=[-~f/2%12+.01,-~t/2%12+.01]+' '),s=n,t=f),r='')&&r

console.log(f(8))
console.log(f(14))
console.log(f(90))
console.log(f(1))
console.log(f(2))

Commented

n =>                           // n = input
  [...Array(24)].map((_, f, a) // FOR f = 0 TO 23:
    => a.map(_ =>              //   FOR t = f TO f + 23:
      (                        //     update s
        s -=                   //       by subtracting:
          t++ & 1 ||           //         - 1 if t is odd (half hour)
          t / 2 % 12 + .5      //         - the current hour if t is even
      ) || (                   //     if s is equal to zero:
        r += [                 //       update the result string by appending:
          -~f / 2 % 12 + .01   //         - the formatted 'from' time
          ,                    //         - a comma
          -~t / 2 % 12 + .01   //         - the formatted 'to' time
        ] + ' '                //       and a padding space
      ),                       //     inner map() initialization:
      s = n,                   //     - s = target number of strikes
      t = f                    //     - 'to' time = 'from' time
    ),                         //   end of inner map()
    r = ''                     //   start with r = empty string
  )                            // end of outer map()
  && r                         // return r

Arnauld

Posted 2018-01-05T08:17:19.900

Reputation: 111 334

4

APL (Dyalog Unicode), 62 59 bytesSBCS

Full program body. Prompts for n. Prints list of two-element lists using decimal hours.

∪(⎕=∊l+/¨⊂48⍴∊1,¨⍳12)/(¯.1 .1+⊃,⊢/)¨⊃,/(l←⍳48),/¨⊂.5×48⍴⍳24

Try it online!

⍳24ɩndices 1…24

48⍴ cyclically reshape to length 48, i.e. 1…12,1…12

.5× multiply a half by that

 enclose (to use this entire array as right argument for each left argument)

(),/¨ for each of the following, return all the sub-lists of that length:

⍳48ɩndices 1…48

l← store in l (for lengths)

Now we have all the possible lists of runs of times for each possible run-length.

,/ concatenate (lit. concatenation-reduction) the lists of sub-lists

 disclose (because the reduction reduced the rank from 1 to 0)

( apply the following function to each:

⊢/ the last (lit. right-reduction) element (the end time)

⊃, prepend the first element (the beginning time)

¯.1 .1+ add negative and positive tenths to those

()/ filter those begin-end pairs with:

⍳12ɩndices 1…12

1,¨ prepend a 1 to each

ϵnlist (flatten)

48⍴ cyclically reshape to length 48, i.e. 1,1,1,2…1,11,1,12

 enclose (to use this entire array as right argument for each left argument)

l+/¨ for each of l (1…48) return the sums of all the sub-lists of that length

ϵnlist (flatten)

⎕= compare numeric input to that

 return just the unique elements (begin-end pairs)

Adám

Posted 2018-01-05T08:17:19.900

Reputation: 37 779

0.1 0.5 can become .1 .5 – user41805 – 2018-01-05T11:11:37.323

@Cowsquack Yeah, I noticed too. Thanks, though. – Adám – 2018-01-05T11:12:06.353

3

Python 3, 118 116 bytes

lambda n:[(a/2+.4,b%24/2+.1)for a in range(24)for b in range(48)if sum((sum(zip([1]*12,range(1,13)),())*2)[a:b])==n]

Try it online!

A timeframe is represented as (t1, t2), t1 and t2 being decimals representing hours. The offset is .1 or 6 minutes.

ovs

Posted 2018-01-05T08:17:19.900

Reputation: 21 408

1

Batch, 196 bytes

@for /l %%i in (0,1,23)do @set s=%1&for /l %%j in (0,1,23)do @call:c %%i %%j
:c
@set/at=%2+%1,s-=t%%2*(t/2%%12)+1,h=%1/2,i=%1%%2*30+15,t=-~t%%24/2,u=-~t%%2*30+15
@if %s%==0 echo %h%:%i% %t%:%u%

Explanation: t is the time in half hours, starting at 0 for 00:30. The number of strikes at time t is then 1, 1, 1, 2, 1, 3 etc. Subtracting 1 gives the sequence 0, 0, 0, 1, 0, 2 etc. which is the integers interleaved with zeros. This can then be obtained by termwise multiplication of the sequence 0, 0, 1, 1, 2, 2 etc. with the sequence 0, 1, 0, 1, 0, 1 etc. Both of these sequences are readily calculated using modulo and (integer) division.

It then remains to loop over all 23 possible starting times, then taking all 24 striking times and subtracting the number of strikes from the input, printing the times when the result is zero.

The code falls through after the loop but no harm is done as the input cannot be more than 90.

Neil

Posted 2018-01-05T08:17:19.900

Reputation: 95 035

1

APL NARS, 559 bytes

∇r←l w;t;i;j;c;k;m;p
p←{0=2∣¯1+⍵:.01+2÷⍨¯1+⍵⋄¯0.19+2÷⍨¯1+⍵}
m←{0=2∣¯1+⍵:¯.41+2÷⍨¯1+⍵⋄¯0.21+2÷⍨¯1+⍵}
   r←⍬⋄i←0⋄t←∊(¯1+⍳13),¨13⍴1⋄t←t,2↓t⋄k←⍴t
A: j←i+←1⋄→0×⍳i≥k⋄c←0
B: c+←j⊃t⋄:if(c=w)∧(0≤(m i))∧(24≥(p j))⋄r←r,⊂(m i),(p j)⋄:endif⋄→A×⍳c≥w⋄j+←1⋄→B×⍳j≤k⋄→A
∇
∇r←g w;v;i;k;m
   v←{12≤⌊⍵:⍵-12⋄⍵}
   i←1⋄k←⍴w⋄r←⍬
A: →0×⍳i>k⋄r←r,⊂v¨i⊃w⋄i+←1⋄→A
∇   
h←g∘l

h(n) or l(n) returns all representative intervals in 0-24 hours that has n clock strikes. h(n) has the clock format as 0..11.0..59; instead l(n) has clock format as 0..23.0..59 test

  h 8
    0.59 3.01  1.29 3.31  2.59 4.01  5.29 6.31  6.29 7.01  6.59 7.31  
    7.59 8.01  0.59 3.01  1.29 3.31  2.59 4.01  5.29 6.31  6.29 7.01  
    6.59 7.31  7.59 8.01 
  h 14
    0.29 4.01  0.59 4.31  2.59 5.01  4.29 6.31  5.59 7.01  11.29 0.31  
    11.59 1.01  0.29 4.01  0.59 4.31  2.59 5.01 4.29 6.31  5.59 7.01 
  h 90
    0.29 0.01  0.59 0.31  1.29 1.01  1.59 1.31  2.29 2.01  2.59 2.31  
    3.29 3.01  3.59 3.31  4.29 4.01  4.59 4.31  5.29 5.01  5.59 5.31  
    6.29 6.01  6.59 6.31  7.29 7.01  7.59 7.31  8.29 8.01  8.59 8.31  
    9.29 9.01  9.59 9.31  10.29 10.01  10.59 10.31  11.29 11.01  11.59 11.31    
  h 1
    0.29 0.31  0.59 1.01  1.29 1.31  2.29 2.31  3.29 3.31  4.29 4.31  
    5.29 5.31  6.29 6.31  7.29 7.31  8.29 8.31  9.29 9.31  10.29 10.31  
    11.29 11.31  0.29 0.31  0.59 1.01  1.29 1.31  2.29 2.31  3.29 3.31  
    4.29 4.31  5.29 5.31  6.29 6.31  7.29 7.31  8.29 8.31  9.29 9.31  
    10.29 10.31  11.29 11.31 
  h 2
    0.29 1.01  0.59 1.31  1.59 2.01  0.29 1.01  0.59 1.31  1.59 2.01 
  l 2
    0.29 1.01  0.59 1.31  1.59 2.01  12.29 13.01  12.59 13.31  13.59 14.01 

RosLuP

Posted 2018-01-05T08:17:19.900

Reputation: 3 036