21
\$\begingroup\$

Given an integer between 0 and 141 (inclusive), list all 24-hour times whose hour, minute, and second units add to that integer.

Rules of addition

Numbers are added by their time units, not by single digits.

For example, take 17:43:59

17+43+59=119

Remember, that is an example of digits being added. In reality, you would enter 119, and 17:43:59 would be one of the results. Output should be given as HH:MM:SS or H:MM:SS.

Also keep in mind the highest number possible is 141, being 23:59:59. This is code golf, so the lowest amount wins. Trial and error is permitted, but there may be a better way to go about this.

Edit: Please specify where in your code the input value is.

\$\endgroup\$
  • 3
    \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! If by plugged in you mean made part of the source code, that's usually disallowed. In general, it's a good idea to stick to those defaults. Do we have to display the results as strings? If so, what formats are allowed? \$\endgroup\$ – Dennis Dec 31 '16 at 3:14
  • \$\begingroup\$ Is the input number guaranteed to be positive? Will there be at least one solution? \$\endgroup\$ – xnor Dec 31 '16 at 3:19
  • \$\begingroup\$ I've edited the question a bit to clarify/answer some things. If your intent was different than my changes, feel free to edit it to match that. \$\endgroup\$ – Geobits Dec 31 '16 at 3:27
  • 1
    \$\begingroup\$ I only did that because it's the usual way I see times given (in the real world). Nobody ever says it's 13:4:7, but 5:10:30 is almost always acceptable. I don't have an issue with it being changed. \$\endgroup\$ – Geobits Dec 31 '16 at 3:28
  • 3
    \$\begingroup\$ "Please specify where in your code the input value is." - The convention on PPCG for taking input is using arguments, as well as a few other options. See Default for Code Golf: Input/Output methods on Meta. \$\endgroup\$ – user2428118 Dec 31 '16 at 9:52

21 Answers 21

8
\$\begingroup\$

Jelly, 16 30 29 20 bytes

Now with the correct output format! Many thanks to Dennis for his help in debugging this answer. Golfing suggestions welcome. Try it online!

Edit: +14 bytes from using the correct output format. -1 byte from removing an extra space. -3 from changing from 24,60,60 to “ð<<‘. -6 bytes from changing +100DḊ€€ to d⁵.

“ð<<‘Œp’S=¥Ðfd⁵j€”:Y

Explanation

“ð<<‘Œp’S=¥Ðfd⁵j€”:Y  Main link. Argument: n

“ð<<‘                 Jelly ord() the string `ð<<` to get [24, 60, 60]. Call this list z.
     Œp               Cartesian product of z's items. 
                        Since each item of z is a literal,
                        Jelly takes the range [1 ... item] for each item.
       ’              Decrements every number in the Cartesian product 
                        to get lowered ranges [0 ... item-1].
        S=¥           Create a dyadic link of `sum is equal to (implicit n)`.
           Ðf         Filter the Cartesian product for items with sum equal to n.
             d⁵       By taking divmod 10 of every number in each item,
                        we get zero padding for single-digit numbers
                        and every double-digit number just turns into a list of its digits.
               j€”:   Join every number with a ':'.
                   Y  Join all of the times with linefeeds for easier reading.
\$\endgroup\$
8
\$\begingroup\$

Bash, 71

  • 8 bytes saved thanks to @hvd
for t in {0..23}+{00..59}+{00..59};{((${t//+0/+}-$1))||echo ${t//+/:};}

Try it online.

\$\endgroup\$
  • 1
    \$\begingroup\$ printf is costly here. By getting t closer to the right format, and fixing it up to make ((t-$1)) work, you can get it down to 71: for t in {0..23}+{00..59}+{00..59};{((${t//+0/+}-$1))||echo ${t//+/:};} \$\endgroup\$ – hvd Dec 31 '16 at 12:12
  • \$\begingroup\$ @hvd Good golfing - thanks! \$\endgroup\$ – Digital Trauma Dec 31 '16 at 20:27
6
\$\begingroup\$

Perl 6, 62 56 bytes

{map *.fmt('%02d',':'),grep $_==*.sum,(^24 X ^60 X ^60)}

Just checks all possible combinations in the cross product of all hours, minutes, and seconds.

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

Python 3, 91 bytes

def f(n):
 for k in range(86400):t=k//3600,k//60%60,k%60;sum(t)==n!=print('%d:%02d:%02d'%t)

There are shorter solutions using exec (Python 2) or recursion (Python 3), but both require an unreasonable amount of memory.

Try it online!

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

PowerShell, 87 77 bytes

Saved 10 bytes thanks to John L. Bevan

$d=date;0..86399|%{$d+=1e7l;"$d".Split()[1]}|?{("{0:H+m+s}"-f$d|iex)-in$args}

Try it online! (this will time out, it's very slow)

Explanation

Pretty simple, starting with the current [datetime], add 1 second 86,399 times, format as a string, then keep only the ones where sum adds up.

\$\endgroup\$
  • \$\begingroup\$ FYI: You can replace 10000000 with 1e7l to save 4 bytes... or even 1e7 for an extra byte (I think; I had to include the L for the benefit of the parameter; but suspect your approach avoids that need. \$\endgroup\$ – JohnLBevan Dec 31 '16 at 20:52
  • 1
    \$\begingroup\$ @JohnLBevan thanks! I struggled with 1e7 for at least 30 minutes, and it was the L postfix I missed; I forgot about it and couldn't figure out a way to get it to int that was shorter than the constant. Who decided that that a [timespan] interprets an [int] as ticks and a [double] as days anyway?? The iex bit is pretty brilliant, though it makes this whole thing inordinately slower. \$\endgroup\$ – briantist Dec 31 '16 at 21:04
  • 1
    \$\begingroup\$ No worries; I had some help on that one too ;) : stackoverflow.com/q/41408902/361842 \$\endgroup\$ – JohnLBevan Dec 31 '16 at 21:06
  • 1
    \$\begingroup\$ @JohnLBevan I literally just saw this question before the comment where you linked it! Nice. \$\endgroup\$ – briantist Dec 31 '16 at 21:08
  • 1
    \$\begingroup\$ Also the iex trick was adapted from a tip here: codegolf.stackexchange.com/a/746/6776 \$\endgroup\$ – JohnLBevan Dec 31 '16 at 21:08
3
\$\begingroup\$

Haskell, 77 bytes

f x=[tail$(':':).tail.show.(+100)=<<t|t<-mapM(\x->[0..x])[23,59,59],sum t==x]
\$\endgroup\$
2
\$\begingroup\$

Haskell, 90 bytes

p x=['0'|x<10]++show x
i=[0..59]
f x=[p h++':':p m++':':p s|h<-[0..23],m<-i,s<-i,h+m+s==x]

Returns a list of HH:MM:SS strings, e.g. f 140 -> ["22:59:59","23:58:59","23:59:58"].

It's three simple loops through the hours, minutes and seconds. Keep and format all values where the sum is the input number x.

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

Pyth - 30 bytes

Takes all possible times then filters.

mj\:%L"%02d"dfqsTQsM*U24*KU60K

Test Suite.

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

Julia 0.5, 69 bytes

!n=[h+m+s==n&&@printf("%d:%02d:%02d
",h,m,s)for s=0:59,m=0:59,h=0:23]

Try it online!

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

Batch, 168 bytes

@for /l %%t in (0,1,86399)do @call:c %1 %%t
@exit/b
:c
@set/ah=%2/3600,m=%2/60%%60,s=%2%%60,n=%1-h-m-s
@set m=0%m%
@set s=0%s%
@if %n%==0 echo %h%:%m:~-2%:%s:~-2%

Outputs single-digit hours.

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

Mathematica, 79 bytes

Cases[Tuples@{(r=Range)@24-1,x=r@60-1,x},t_/;Tr@t==#:>DateString@TimeObject@t]&
\$\endgroup\$
1
\$\begingroup\$

Octave, 83 , 87 bytes

@(a){[H,M,S]=ndgrid(0:23,s=0:59,s);printf("%d:%02d:%02d\n",[H(x=H+M+S==a),M(x),S(x)]')}

Try it Online!

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

QBIC, 82 72 bytes

:[0,23|[0,59|[0,59|~b+c+d=a|?!b$+@:`+right$(@0`+!c$,2)+A+right$(B+!d$,2)

This hits an unfortunate spot in QBasic, with casting to number, trimming and prepending a 0 when necessary is really costly.

Sample output:

Command line: 119
1:59:59
2:58:59
2:59:58
3:57:59
[... SNIP 270 lines ...]
23:58:38
23:59:37

Explanation I wrote a novel about it:

:           Get N, call it 'a'
[0,23|      Loop through the hours; this FOR loop is initialised with 2 parameters
            using a comma to separate FROM and TO, and a '|' to delimit the argument list
[0,59|      Same for the minutes
[0,59|      And the seconds
            QBIC automatically creates variables to use as loop-counters: 
            b, c, d (a was already taken by ':')
~b+c+d=a    IF a == b+c+d
|           THEN
 ?          PRINT
  !         CAST
   b        'b'
    $       To String; casting num to str in QBasic adds a space, this is trimmed in QBIC
+@:`        Create string A$, containing ":"
+right$      This is a QBasic function, but since it's all lowercase (and '$' is 
            not a function in QBIC) it remains unaltered in the resulting QBasic.
(@0`+!c$,2) Pad the minutes by prepending a 0, then taking the rightmost 2 characters.
+A          Remember that semicolon in A$? Add it again
+right$     Same for the seconds
(B+!d$,2)   Reusing the 0-string saves 2 bytes :-)
\$\endgroup\$
  • \$\begingroup\$ QBIC looks interesting. Did you create it just for #code-golf!? :) \$\endgroup\$ – wasatchwizard Jan 1 '17 at 2:15
  • \$\begingroup\$ @wasatchwizard Yup :-) \$\endgroup\$ – steenbergh Jan 1 '17 at 6:01
1
\$\begingroup\$

PowerShell, 67 79 Bytes (nasty version)

Since the rules say nothing about completing in a certain time (or at all), and nothing about no duplicates, here's a horrific solution:

for(){if(("{0:H+m+s}"-f($d=date)|iex)-in$args){"{0:H:mm:ss}"-f$d}}
\$\endgroup\$
  • 1
    \$\begingroup\$ I can't find the relevant meta post, but i'm pretty sure a submission have to halt to be valid, unless specified by the challenge \$\endgroup\$ – Sefa Jan 3 '17 at 10:24
  • \$\begingroup\$ Thanks @Sefa... if that's the case I can't find a nice way to get my nasty version to work in less characters than Briantist's clean version... Tempted to delete this answer, but I'm kind of proud of how bad it is ;) \$\endgroup\$ – JohnLBevan Jan 3 '17 at 12:18
0
\$\begingroup\$

Racket 39 bytes

(for*/sum((h 24)(m 60)(s 60))(+ h m s))

Ungolfed:

(for*/sum      ; loop for all combinations; return sum of values for each loop
   ((h 24)     ; h from 0 to 23
    (m 60)     ; m from 0 to 59
    (s 60))    ; s from 0 to 59
  (+ h m s))   ; sum of all 3 variables
\$\endgroup\$
0
\$\begingroup\$

MATL, 29 bytes

24:q60:qt&Z*t!si=Y)'%i:'8:)&V

Try it online!

Explanation

24:q     % Push [0 1 ... 23]
60:q     % Push [0 1 ... 59]
t        % Duplicate
&Z*      % Cartesian product of the three arrays. This gives a matrix with each
         % on a different row Cartesian tuple
t!       % Push a transposed copy
s        % Sum of each column
i=       % Logical mask of values that equal the input
Y)       % Select rows based on that mask
'%i:'    % Push this string
8:)      % Index (modularly) with [1 2 ... 8]: gives string '%i:%i:%i'
&V       % Convert to string with that format specification. Implicitly display
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 122 120 bytes

Takes one additional empty string as input, which I presume doesn't count towards the size. Updated bytecount (including historical) to add two bytes for the string's initialization.

console.log((
//Submission starts at the next line
i=>o=>{for(h=24;h--;)for(m=60;m--;)for(s=60;s--;)if(h+m+s==i)o+=`${h}:0${m}:0${s} `;return o.replace(/0\d{2}/g,d=>+d)}
//End submission
)(prompt("Number:",""))(""))

\$\endgroup\$
  • \$\begingroup\$ If you need to initialize a string to empty, the initialization must be counted \$\endgroup\$ – edc65 Jan 1 '17 at 10:50
  • \$\begingroup\$ @edc65 Done.··· \$\endgroup\$ – user2428118 Jan 1 '17 at 11:04
0
\$\begingroup\$

JavaScript (ES6), 110

v=>eval("o=[];z=x=>':'+`0${x}`.slice(-2);for(m=60;m--;)for(s=60;s--;h>=0&h<24&&o.push(h+z(m)+z(s)))h=v-m-s;o")

Less golfed

v=>{
  o=[];
  z=x=>':' + `0${x}`.slice(-2);
  for(m = 60; m--;)
    for(s = 60; s--; )
      h = v - m - s,
      h >= 0 & h < 24 && o.push(h + z(m) + z(s))
  return o
}

Test

F=
v=>eval("o=[];z=x=>':'+`0${x}`.slice(-2);for(m=60;m--;)for(s=60;s--;h>=0&h<24&&o.push(h+z(m)+z(s)))h=v-m-s;o")

function update() {
  O.textContent=F(+I.value).join`\n`
}

update()
<input id='I' value=119 type=number min=0 max=141 oninput='update()'><pre id=O></pre>

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

JavaScript, 96 bytes

v=>{for (i=86399;i;[a,b,c]=[i/3600|0,i%3600/60|0,i--%60]){v-a-b-c?0:console.log(a+":"+b+":"+c)}}

Expanded view:

v => {
    for (i = 86399; i;
        [a, b, c] = [i / 3600 | 0, i % 3600 / 60 | 0, i-- % 60]) {
        v - a - b - c ? 0 : console.log(a + ":" + b + ":" + c)
    }
}

Loop through all possible times by looping 86399 to 1,

  • convert the integer to time by dividing by 3600 to get the first digit
  • the 2nd digit by taking the integer mod 3600 and then dividing by 60
  • and the last digit is the integer mod 60

Subtract all 3 numbers from the input value to return a falsey value if the three numbers add up to the input value. If the value is falsey, output the value.

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

bash, 78 bytes (using a BSD utility) or 79 bytes (non-BSD also)

This is a little longer than @DigitalTrauma and @hvd's nice 71-byte bash solution, but I kind of liked the idea here of using numbers in base 60; I'm curious if anybody can golf this down a little more.

With the BSD-standard jot utility:

jot '-wx=`dc<<<60do3^%d+n`;((`dc<<<$x++'$1'-n`))||tr \  :<<<${x:3}' 86400 0|sh

With the more universally available seq utility:

seq '-fx=`dc<<<60do3^%.f+n`;((`dc<<<$x++'$1'-n`))||tr \  :<<<${x:3}' 0 86399|sh

The idea is to generate the numbers from 0 to 83699 and use dc to convert them into base 60. The "digits" in dc's base-60 output are 2-digit numbers from 00 to 59, with spaces separating the "digits", so this lists all the desired times from 00 00 00 to 23 59 59 in almost the format needed.

If you literally carry that out, though, numbers below 60^2 aren't 3-digit numbers in base 60, so the initial 00 or 00 00 is missing. For that reason, I'm actually generating the numbers from 60^3 to 60^3+83699; this ensures that all the numbers generated are exactly 4 digits long in base 60. This is OK as long as I eventually throw away the extra first digit (01) that isn't needed.

So, once the desired times are generated, I just take each quadruple from 01 00 00 00 to 01 23 59 59, add the last three numbers and subtract the argument $1. If that's 0, I then take everything in the quadruple from the 3rd character on (throwing away the "01 "), use tr to convert spaces to colons, and print the result.

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

PowerShell, 91 97 bytes (including input)

param($x)1..864e3|%{($d=date($_*1e7l))}|?{("{0:H+m+s}"-f$_|iex)-eq$x}|%{"{0:H:mm:ss}"-f$_}

param($x)0..23|%{$h=$_;0..59|%{$m=$_;0..59|?{$h+$m+$_-eq$x}|%{"{0:0}:{1:00}:{2:00}"-f$h,$m,$_}}}

or

param($x)0..23|%{$h=$_;0..59|?{($s=$x-$h-$_)-le59-and$s-ge0}|%{"{0:0}:{1:00}:{2:00}"-f$h,$_,$s}} <\s>

Expanded & commented

param($x)
#loop through the hours
0..23 | %{
    $h=$_
    #loop through the minutes
    0..59 | %{
        $m=$_
        #loop through the seconds
        0..59 | ?{ #filter for those where the sum matches the target
            $h + $m + $_ -eq $x
        } | %{
            #format the result
            "{0:#0}:{1:00}:{2:00}" -f $h, $m, $_
        }
    }
}

NB: Surpassed by @Briantist's version: https://codegolf.stackexchange.com/a/105163/6776

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