14
\$\begingroup\$

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]
\$\endgroup\$
  • 1
    \$\begingroup\$ I'd go for whatever is most flexible. This includes decimal hour numbers, as long as the result numbers fall between two ringing times. \$\endgroup\$ – Adám Jan 5 '18 at 10:09
  • \$\begingroup\$ @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). \$\endgroup\$ – Kevin Cruijssen Jan 5 '18 at 10:18
  • 1
    \$\begingroup\$ Maybe mention that the time pairs may be returned in any order? \$\endgroup\$ – Adám Jan 5 '18 at 11:13
  • \$\begingroup\$ 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 ? \$\endgroup\$ – RosLuP Jan 7 '18 at 14:59
  • \$\begingroup\$ @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. \$\endgroup\$ – Kevin Cruijssen Jan 7 '18 at 18:03
3
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ What is the time interval represented by .1 in the output? Also, nice answer. \$\endgroup\$ – Erik the Outgolfer Jan 7 '18 at 18:26
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ – Erik the Outgolfer Jan 7 '18 at 18:28
  • \$\begingroup\$ @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. \$\endgroup\$ – ngn Jan 7 '18 at 18:45
  • \$\begingroup\$ 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 ;) \$\endgroup\$ – Erik the Outgolfer Jan 7 '18 at 18:45
  • \$\begingroup\$ @EriktheOutgolfer "SBCS" added, thanks; .1×60 minutes is 6 minutes \$\endgroup\$ – ngn Jan 7 '18 at 18:56
5
\$\begingroup\$

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
\$\endgroup\$
4
\$\begingroup\$

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)

\$\endgroup\$
  • \$\begingroup\$ 0.1 0.5 can become .1 .5 \$\endgroup\$ – Cows quack Jan 5 '18 at 11:11
  • \$\begingroup\$ @Cowsquack Yeah, I noticed too. Thanks, though. \$\endgroup\$ – Adám Jan 5 '18 at 11:12
3
\$\begingroup\$

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.

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

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.

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

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 
\$\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.