Originally posted (and deleted) by @Tlink, which was most likely inspired from this StackOverflow question.
Since it was a shame it got deleted, because it seemed like a good challenge in general, I figured I'd repost it with proper formatting and rules. (I've tried contacting @Tlink and get his/her permission to post it, but (s)he doesn't respond any more, which is why I decided to post it myself now.)

Input: Six digits.

Output: Either the first or last valid time in the 24-hour format (00:00:00 through 23:59:59). (You can choose yourself whether you output the first or last valid time.)


When the inputs are 1,8,3,2,6,4, the following times can be created:

12:36:48    12:38:46    12:46:38    12:48:36
13:26:48    13:28:46    13:46:28    13:48:26
14:26:38    14:28:36    14:36:28    14:38:26
16:23:48    16:24:38    16:28:34    16:28:43
16:32:48    16:34:28    16:38:24    16:38:42
16:42:38    16:43:28    16:48:23    16:48:32
18:23:46    18:24:36    18:26:34    18:26:43
18:32:46    18:34:26    18:36:24    18:36:42
18:42:36    18:43:26    18:46:23    18:46:32
21:36:48    21:38:46    21:46:38    21:48:36
23:16:48    23:48:16

So we'll output either 12:36:48 or 23:48:16 in this case, being the first / last respectively.

Challenge rules:

  • State whether you output the first or last valid time in your answer.
  • I/O is flexible. Input can be six separated integers; a string containing the six digits; an integer list/array; a single (possibly octal) number; etc. Output can be a correctly ordered list/array of digits; a String in the format HH:mm:ss/HHmmss/HH mm ss; every digit printed with new-line delimiter; etc. Your call.
  • You are allowed to take the digits in any order you'd like, so they can already be sorted from lowest to highest or vice-versa.
  • If no valid time can be created with the given digits (i.e. 2,5,5,5,5,5), make so clear in any way you'd like. Can return null/false; "Not possible"; crash with an error; etc. (You cannot output an invalid time like 55:55:52, or another valid time like 00:00:00.) Please state how it handles inputs for which no valid time can be created.
  • You are not allowed to output all possible valid times. Only the earliest/latest should be outputted/returned.
  • 24 for hours (i.e. 24:00:00), or 60 for minutes/seconds (i.e. 00:60:60) are not valid. The ranges are [00-23] for hours and [00-59] for minutes and seconds.

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:

Input:          Earliest output:     Latest output:

1,2,3,4,6,8     12:36:48             23:48:16
2,5,5,5,5,5     None possible        None possible
0,0,0,1,1,1     00:01:11             11:10:00
1,1,2,2,3,3     11:22:33             23:32:11
9,9,9,9,9,9     None possible        None possible
2,3,5,5,9,9     23:59:59             23:59:59
1,2,3,4,5,6     12:34:56             23:56:41
0,0,0,0,0,0     00:00:00             00:00:00
1,5,5,8,8,8     18:58:58             18:58:58
1,5,5,5,8,8     15:58:58             18:58:55
1,1,1,8,8,8     18:18:18             18:18:18
  • 1
    \$\begingroup\$ Isn't 23:48:16 a valid output for the example? \$\endgroup\$
    – TFeld
    May 9, 2018 at 7:21
  • \$\begingroup\$ should I output only one of the earliest / latest time or both? \$\endgroup\$
    – tsh
    May 9, 2018 at 7:34
  • \$\begingroup\$ @tsh Just one. Which one is up to you. The two Python answers thus far output the earliest. \$\endgroup\$ May 9, 2018 at 7:35
  • \$\begingroup\$ Does a "valid time" not account for any leap seconds? For example, would 06:08:60 be valid, given that there has been a leap second during that minute? \$\endgroup\$ May 9, 2018 at 11:45
  • \$\begingroup\$ @EriktheOutgolfer No, 60 for minutes and seconds is not valid. Ranges are [00-23], [00-59], and [00-59]. Will clarify this in the challenge. \$\endgroup\$ May 9, 2018 at 11:52

22 Answers 22


C (gcc), 186 174 bytes


Try it online!

-12 bytes thanks to Kevin Cruijssen

Probably not optimal, but it works. Oddly enough for some reason with 7 arguments the gcc implementation on TIO requires that you actually supply them or it segfaults. On my machine that is unnecessary however.

Format: G(X,0,6) -> Y where X is the 6-digit number whose digits are to be used and Y is the 6 digit number which when taken as a time (by inserting : appropriately) is minimal.

  • 2
    \$\begingroup\$ I think you can golf {0,1,10,100,1000,10000,100000} to {0,1,10,100,1e3,1e4,1e5}. Also, you can golf for(I=0;I<F;++I){E=O%10;M=G(O/10,L*10+E,F-1);T=T>M?M:T;O=(O/10)+E*D[F];} to for(I=0;I++<F;M=G(O/10,L*10+E,F-1),T=T>M?M:T,O=(O/10)+E*D[F])E=O%10;, and remove the brackets around the if. Try it online 174 bytes. Also, I like the G(O,L,F,T,I,M,E). :) \$\endgroup\$ May 9, 2018 at 15:22
  • \$\begingroup\$ Funny, on my machine using ...1e3,1e4,1e5} didn't work. Thanks for the suggestion. \$\endgroup\$
    – LambdaBeta
    May 9, 2018 at 15:27
  • \$\begingroup\$ You're everywhere on this guy's answers, @ceilingcat, nice golfing by the way. \$\endgroup\$
    – Adalynn
    Nov 16, 2018 at 17:40
  • \$\begingroup\$ I appreciate the insight. It's always nice to see that people actually read the answers and find ways to improve them. :) You're everywhere on them too now. \$\endgroup\$
    – LambdaBeta
    Nov 16, 2018 at 17:50
  • \$\begingroup\$ 125 bytes \$\endgroup\$
    – ceilingcat
    Jul 9, 2020 at 22:14

Haskell, 114 96 86 bytes

import Data.List
f l=minimum[x|x@[a,b,c,d,e,f]<-permutations l,a:[b]<"24",c<'6',e<'6']

Now with less strict output. Takes input as a string of digits and compares permutations against limits with list comparison. With minutes and seconds only the first digit is checked. Crashes and burns if no permutation is a valid time.

Try it online!


Python 2, 131 115 112 109 105 88 bytes

lambda s:min(d for d in permutations(s)if(2,4)>d[:2]>d[4]<6>d[2])
from itertools import*

Try it online!

I/O are lists of integers

Throws an error if no times are possible


Python 2, 88 bytes

lambda s:max(d*((2,4)>d[:2]>d[4]<6>d[2])for d in permutations(s))
from itertools import*

Try it online!

Returns the latest time

Returns an empty tuple for invalid times


  • -21 bytes, thanks to ovs

05AB1E, 20 15 bytes

Input as sorted string.
Output is the smallest time as a string.
In case of no solution, an empty list is the output.


Try it online!


JavaScript (ES6), 93 89 88 bytes

Expects an array of 6 digits, sorted from lowest to highest. Returns either the 6-digit string of the first valid time, or false if no solution exists.


Try it online!


We recursively try all permutations of the input until we find one that passes a hybrid test using both arithmetic and a regular expression.

f = (                       // f = recursive function taking
  a, t = ''                 // a[] = input array and t = current time
) =>                        //
  t < 24e4 &                // if t is less than 240000
  /..([0-5].){2}/.test(t) ? // and it matches "hhMmSs" with M and S in [0-5]:
    t                       //   return t
  :                         // else:
    a.some((v, i) =>        //   for each digit v at position i in a[]:
      s = f(                //     save in s the result of a recursive call with:
        a.filter(_ => i--), //       a copy of a[] with the current digit removed
        t + v               //       the current digit appended to t
      )                     //     end of recursive call
    ) && s                  //   end of some(); if truthy, return s

Japt, 17 bytes

Takes input as a string of digits and outputs the first valid time; loops infinitely if there's no valid time.

@øXr':}a@ÐX ¤¯8

Try it

Warning: Extremely slow - add *1000 after the second X to speed it up somewhat. And don't forget that an invalid input will create an infinite loop and may crash your browser.


                   :Implicit input of string U
á                  :Get all permutations of U
\n                 :Reassign that array to U
      }a           :Loop until true and then return the argument that was passed
        @          :By default that argument is an integer X which increments on each loop so first we'll pass X through a function
         ÐX        :  new Date(X)
            ¤      :  Get the time
             ¯8    :  Slice to the 8th character to get rid of the timezone info
@                  :The function that tests for truthiness
  Xr':             :  Remove all colons in X
 ø                 :  Does U contain the resulting string?

Retina, 77 74 69 65 62 bytes


Try it online! Outputs the earliest time, or the empty string if no time can be found. Edit: Saved 5 8 bytes thanks to @TwiNight. Explanation:


Generate all the permutations. The : works its way though the string as the permutations are generated, ending up at the start.


Sort the times into order.


Output the first valid time.

  • \$\begingroup\$ Since you can output newline-separated digits, you can save 5 bytes \$\endgroup\$
    – TwiNight
    May 11, 2018 at 14:37
  • \$\begingroup\$ You can even remove the : in the grep stage since it must match 6 characters and the first must be 0, 1, or 2 \$\endgroup\$
    – TwiNight
    May 11, 2018 at 15:07
  • \$\begingroup\$ @TwiNight Oh, if Grep is shorter than I can save 4 more bytes anyway. \$\endgroup\$
    – Neil
    May 11, 2018 at 15:11
  • \$\begingroup\$ Oh yeah you can just L0 \$\endgroup\$
    – TwiNight
    May 11, 2018 at 15:12
  • \$\begingroup\$ @TwiNight 0G actually. \$\endgroup\$
    – Neil
    May 11, 2018 at 15:36

Red, 157 124 bytes

Thanks to Kevin Cruijssen for reminding me to read the descritions more carefully!

func[s][a: 0:0:0 loop 86400[b: to-string a a: a + 1 if b/1 =#"0"[insert b"0"]if s = sort replace/all copy b":"""[return b]]]

Try it online!

Takes a sorted string as input. Returns none if it's not possible to make time.


f: func[s][                                    ; the argument is a sorted string of digits
    a: 0:0:0                                   ; time object, set to 00:00:00 h 
    loop 86400 [                               ; loop through all seconds in 24 h
        b: to-string a                         ; convert the time to string 
        a: a + 1                               ; add 1 second to the current time   
        if b/1 = #"0" [                        ; prepend "0" if necessary
            insert b "0"                       ; (Red omits the leading 0)
        if s = sort replace/all copy b ":" ""[ ; compare the input with the sorted time
            return b                           ; return it if they are equal 
  • 3
    \$\begingroup\$ Is the sort at the start necessary? In the challenge I state: "You are allowed to take the digits in any order you'd like, so they can already be sorted from lowest to highest or vice-versa." \$\endgroup\$ May 9, 2018 at 10:33
  • \$\begingroup\$ @Kevin Cruijssen - No, it's not necessary in this case. I'll update the solution to work with sorted input. Thank you! \$\endgroup\$ May 9, 2018 at 10:56

Python 2, 78 bytes

lambda s:min(x for x in range(62**3)if x%100<60>x/100%100<s==sorted('%06d'%x))

Try it online!

Arnauld saved a byte. Thanks!

Expects a list like ['1','2','3','4','6','8'] in sorted order:

You are allowed to take the digits in any order you'd like, so they can already be sorted from lowest to highest or vice-versa.

Outputs an integer like 123648 for 12:36:48. I hope that's acceptable.

  • 2
    \$\begingroup\$ Could you use 62**3 instead of 240000? \$\endgroup\$
    – Arnauld
    May 9, 2018 at 11:22

Jelly, 15 bytes


Try it online!

Posted after a request. The approach is the same as the one of the other answer, however this answer was developed independently.


Japt, 39 23 bytes

Pretty sure there's a shorter way to do this, but I wanted to try using Date objects in Japt.

á ®¬ò q':Ãf@T<ÐXiSiKÅ

á                     // Get all permutations of the input array.
  ®¬ò q':à            // [1,2,3,4,5,6] -> "12:34:56"
          f@          // Filter the results, keeping those that
            T<        // are valid dates
              ÐXiSiKÅ // when made into a date object.
Ì                     // Return the last remaining item, if any.

Takes input as a sorted array of numbers, returns the latest valid time or empty output if none exists.
Lost 10 pounds bytes thanks to Shaggy.

Try it here.

  • \$\begingroup\$ 25 bytes \$\endgroup\$
    – Shaggy
    May 9, 2018 at 10:28
  • \$\begingroup\$ @Shaggy Thanks, really neat. Up until right now I didn't know Japt had a separate section in the method docs for dates, which feels quite silly of me, I sorta just tried to work around not having them. \$\endgroup\$
    – Etheryte
    May 9, 2018 at 11:17

Ruby, 68 67 62 56 55 bytes


Try it online!

Input: Sorted array of digits (as integers).

Output: Array of digits or nil if no solution found

  • \$\begingroup\$ You can drop the space at eval " I think. \$\endgroup\$ May 9, 2018 at 7:35
  • \$\begingroup\$ Yes, it works, thanks. \$\endgroup\$
    – G B
    May 9, 2018 at 7:47
  • \$\begingroup\$ I think you can do a*9+b<22 for one byte. \$\endgroup\$
    – JayCe
    Jun 12, 2018 at 20:24

Jelly, 17 bytes

I'm almost certain this is not the shortest approach... will look at this again later :)


Try it online!

  • \$\begingroup\$ You're correct, this is not the shortest approach. However, public humiliation isn't nice, so I won't comment on the improvements yet. :) \$\endgroup\$ May 9, 2018 at 12:08
  • \$\begingroup\$ The fact that the input may be assumed to be sorted saves some. It is not humiliating to see better after only spending 2 minutes on a golf! \$\endgroup\$ May 9, 2018 at 12:54
  • \$\begingroup\$ To be more precise, you can do it in 15 bytes; to save one byte, you must do something trivial; to save the other, it's not so trivial. Mind you, I was going to post that 15-byte version, but it uses your approach. By the way, is your health OK? \$\endgroup\$ May 9, 2018 at 13:02
  • \$\begingroup\$ Go ahead and post. Health is fine, I'm at work so can't spend time golfing!! \$\endgroup\$ May 9, 2018 at 13:11
  • \$\begingroup\$ Posted. Now you can see why I was referring to the "humiliation". :P \$\endgroup\$ May 9, 2018 at 13:22

Wolfram Language (Mathematica), 63 bytes


Try it online!

Takes a sorted list of digits as input. Returns Missing[NotFound] for invalid inputs.



Find all of the permutations of the input. Since the input is sorted, it is guaranteed that all valid times are in increasing order.

FirstCase[ ... ]

Find the first list that matches...


The first element, labeled a, is 0, 1, or 2, and label the second, third, and fifth elements b, c, and d respectively...

... /;a*b-4<6>d>=c

... such that a*b is less than 10, and d and c are less than 6, with d >= c.

The trick is that for all numbers 00 to 24, the product of the two digits is at most 9, and the possible invalid numbers 25 to 29 (since we force the first digit to be 0, 1, or 2) have the product of least 10.


Pyth, 37 bytes

j\:hf&&<shT24<s@T1 60<seT60mcs`Md2S.p

Test suite

j\:hf&&<shT24<s@T1 60<seT60mcs`Md2S.pQ # Code with implicit variables
   h                                   # The first element of
                                   .pQ # The list of all permutations of the input list
                                  S    # Sorted
                           mcs`Md2     # Mapped to three two digit long strings
    f                                  # Filtered on whether
       <shT24                          #  The first number is less than 24
      &      <s@T1 60                  #  AND the second number is less than 60
     &               <seT60            #  AND the third number is less than 60
j\:                                    # Joined by a colon

Perl 5 with -palF, 73 bytes


Try it online!

Outputs like HHmmss and outputs a blank line for invalid entries.

Every answer I've made recently has used globing for permutations... Weird!


Bash + GNU sed, 83, 72, 69 bytes

  • Accepts input as 6 separate arguments;
  • Returns the earliest time (if found);
  • Returns nothing (empty output) if no valid combination exist.

seq 0 86399|sed "s/^/date +%T -ud@/e;h;`printf s/%d//\; $@`/\w/d;x;q"

How it works

Pre-generate all the possible time strings, for the timestamps in range 0 to 86399, using GNU-sed e(xecute) command + date.

%seq 0 86399|sed "s/^/date +%T -ud@/e;h;"


Generate sed script with 6 sequential substitution commands, for an each input digit.

%echo sed `printf s/%d//\; $@`

sed s/1//;s/2//;s/3//;s/4//;s/6//;s/8//;

Then, apply substitutions, remove any input lines which have at least one digit left, print the first matching line (original time string is extracted from the hold space with x).

%echo 23:45:12|sed 's/1//;s/2//;s/3//;s/4//;s/6//;s/8//;'
:5:2 //non-matching, delete

%echo 12:36:48|sed 's/1//;s/2//;s/3//;s/4//;s/6//;s/8//;'
:: //matching, print and stop


%./timecomb 1 2 3 4 6 8
%./timecomb 2 5 5 5 5 5
%./timecomb 0 0 0 1 1 1
%./timecomb 1 1 2 2 3 3
%./timecomb 9 9 9 9 9 9
%./timecomb 2 3 5 5 9 9
%./timecomb 1 2 3 4 5 6
%./timecomb 0 0 0 0 0 0
%./timecomb 1 5 5 8 8 8
%./timecomb 1 5 5 5 8 8
%./timecomb 1 1 1 8 8 8

Try It Online !


Kotlin, 396 391 389 bytes

No clue how to make this smaller. I'm thinking it is double of what's possible. Produces earliest time. Thanks to Kevin for 7 bytes!

fun p(d:Array<Int>)={val s=Array(6,{0})
val f=Array(6,{1>0})
val t=Array(3,{0})
val o=Array(3,{60})
fun r(i:Int){if(i>5){var l=0>1
var e=!l
for(p in 0..2){t[p]=s[p*2]*10+s[p*2+1]
if(t[0]<24&&t[1]<60&&t[2]<60&&l)for(p in 0..2)o[p]=t[p]}
for(p in 0..5)if(f[p]){f[p]=0>1
else "${o[0]}:${o[1]}:${o[2]}"}()

Try it online!

  • 2
    \$\begingroup\$ I don't know Kotlin, but do you really need both var l=0>1 and var e=1>0? Also, why are the l=l and e=e necessary? Two things that seem to work to golf are var e=1>0 to var e=!l and removing the space before "None". Also, any falsey-output is fine, so "None" can also be just 0. \$\endgroup\$ Jun 19, 2018 at 13:42
  • \$\begingroup\$ @Kevin thank you for the 5 bytes. Shocked I missed one of them. Since I'm not aborting the loop, I can't see anyway to avoid knowing whether the two times have stayed equal so that I can decide the new one is less. I coded a bunch of ways and this ended up shortest. However, the overall code is much bigger than I like. \$\endgroup\$
    – JohnWells
    Jun 28, 2018 at 12:53
  • 1
    \$\begingroup\$ 2 more bytes to golf in your latest version: "0" can be just 0 \$\endgroup\$ Jun 28, 2018 at 13:06
  • \$\begingroup\$ @Kevin that won't be a String type and I'd have to add :Any to allow both String and Int. \$\endgroup\$
    – JohnWells
    Jun 28, 2018 at 13:31
  • 1
    \$\begingroup\$ Hmm ok. It does work in TIO though, and still prints the 0 without errors.. And your current function doesn't specify a return-type as far as I could tell, so won't it implicitly return as an object anyway? PS: I don't know Kotlin at all, just tried it without the quotes and the results were the same. ;) Maybe something else isn't working because of it, which I'm not aware of. \$\endgroup\$ Jun 28, 2018 at 13:45

MATL, 31 30 bytes


Try it online!

Input is 6 integers, output is the minimum hour, minutes, and seconds in an array. Crashes for inputs where no such time is possible.

(-1 byte thanks to @Luis Mendo.)

  • \$\begingroup\$ I think you can replace 2&A by !A, because the binary matrix will never be a row vector \$\endgroup\$
    – Luis Mendo
    Jul 20, 2018 at 23:42

Perl 6, 43 bytes


Try it online!

Expects a sorted input array. Returns Nil for invalid input.


Stax, 15 bytes


Run and debug it

It takes a string of sorted digits for input. It returns the first permutation that satisfies a few criteria.

  • lexicographically less than "24"
  • all three pairs of characters are lexicographically less than "6"

Retina, 58 47 bytes


Try it online!

Input is 6 digits in sorted order. Output is 6 digits representing earliest valid time, or empty string if no valid time exists.

EDIT: I was an idiot, -9 bytes



For brevity, let's define a low digit as 0-5, and a high digit as 6-9.

First, rearrange the digits so that "low-ness" or "high-ness" of each position is correct. The correct arrangement, for each number of high digits in the input:

# of highs  arrangment
0           LLLLLL
1           LLLLLH
2           LLLHLH
3           LHLHLH
4+          Not possible

Since the any rearrangement would fail the final check in the input has 4+ high digits, we can ignore that case completely.

Then, sort the lows and the highs individually. Combine with the rearrangement, this gives the lowest value that satisfies the minute and second constraints. So this gives the earliest valid time, if one exists.

Finally, check if that we have valid time. If not, discard the string.



Matches LHH and swaps the first two digits in that (becomes HLH), and repeat that until no more LHH exists. This gives the correct arrangement.

Actually, I lied. No sorting is needed because 1) swapping only happens between adjacent digits and only between a low and a high; and 2) the input is sorted. So the lows and the highs individually are already in sorted order.


Only keeps the string if it is a valid time


Your Answer

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

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