The Time Anagram

29

1

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.)

Example:

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

Kevin Cruijssen

Posted 2018-05-09T06:59:45.983

Reputation: 67 575

1Isn't 23:48:16 a valid output for the example? – TFeld – 2018-05-09T07:21:34.310

should I output only one of the earliest / latest time or both? – tsh – 2018-05-09T07:34:27.687

@tsh Just one. Which one is up to you. The two Python answers thus far output the earliest. – Kevin Cruijssen – 2018-05-09T07:35:10.990

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? – Erik the Outgolfer – 2018-05-09T11:45:02.647

@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. – Kevin Cruijssen – 2018-05-09T11:52:40.107

Answers

9

C (gcc), 186 174 bytes

D[7]={0,1,10,100,1e3,1e4,1e5};G(O,L,F,T,I,M,E){if(!F)O=L<24e4&L%10000<6e3&L%100<60?L:1e9;else{for(T=1e9,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;O=T;}}

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.

LambdaBeta

Posted 2018-05-09T06:59:45.983

Reputation: 2 499

2

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). :)

– Kevin Cruijssen – 2018-05-09T15:22:14.333

Funny, on my machine using ...1e3,1e4,1e5} didn't work. Thanks for the suggestion. – LambdaBeta – 2018-05-09T15:27:21.270

You're everywhere on this guy's answers, @ceilingcat, nice golfing by the way. – Zacharý – 2018-11-16T17:40:37.800

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. – LambdaBeta – 2018-11-16T17:50:09.617

130 bytes – ceilingcat – 2019-08-07T18:03:55.710

6

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!

Angs

Posted 2018-05-09T06:59:45.983

Reputation: 4 825

5

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


Alternative:

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


Saved

  • -21 bytes, thanks to ovs

TFeld

Posted 2018-05-09T06:59:45.983

Reputation: 19 246

5

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.


Explanation

                   :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?

Shaggy

Posted 2018-05-09T06:59:45.983

Reputation: 24 623

5

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.

f=(a,t='')=>t<24e4&/..([0-5].){2}/.test(t)?t:a.some((v,i)=>s=f(a.filter(_=>i--),t+v))&&s

Try it online!

Commented

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

Arnauld

Posted 2018-05-09T06:59:45.983

Reputation: 111 334

5

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.

œʒ2ô•3Èñ•2ô‹P}н

Try it online!

Emigna

Posted 2018-05-09T06:59:45.983

Reputation: 50 798

5

Retina, 77 74 69 65 62 bytes

$
:
6+Lv$`(.)(.*):
$%`$2:$1$%'
O`
0L`([01].|2[0-3])([0-5].){2}

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:

$
:
6+Lv$`(.)(.*):
$%`$2:$1$%'

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

O`

Sort the times into order.

0L`([01].|2[0-3])([0-5].){2}

Output the first valid time.

Neil

Posted 2018-05-09T06:59:45.983

Reputation: 95 035

Since you can output newline-separated digits, you can save 5 bytes

– TwiNight – 2018-05-11T14:37:07.537

You can even remove the : in the grep stage since it must match 6 characters and the first must be 0, 1, or 2 – TwiNight – 2018-05-11T15:07:56.177

@TwiNight Oh, if Grep is shorter than I can save 4 more bytes anyway. – Neil – 2018-05-11T15:11:23.433

Oh yeah you can just L0 – TwiNight – 2018-05-11T15:12:32.627

@TwiNight 0G actually. – Neil – 2018-05-11T15:36:31.693

If you use 0L instead of 0G you can save 3 more by not having to remove the : manually. After the second stage, each line will be in the form :\d{6}, and 1) having the : does not affect sorting, and 2) the final regex matches exactly 6 characters, none of which can be newline and the first can't be : so it must match a string of 6 digits forming a valid time.

– TwiNight – 2018-05-11T16:38:45.110

@TwiNight Bah, I forgot I could do that, even in Retina 0.8.2... – Neil – 2018-05-11T19:18:45.430

(by which I mean, 1!`([01].|2[0-3])([0-5].){2} would be an approximate Retina 0.8.2 translation) – Neil – 2018-05-11T19:20:42.110

4

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.

Explanation:

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 
        ]
    ]
]

Galen Ivanov

Posted 2018-05-09T06:59:45.983

Reputation: 13 815

3Is 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." – Kevin Cruijssen – 2018-05-09T10:33:50.747

@Kevin Cruijssen - No, it's not necessary in this case. I'll update the solution to work with sorted input. Thank you! – Galen Ivanov – 2018-05-09T10:56:07.543

3

Ruby, 68 67 62 56 55 bytes

->*b{b.permutation.find{|a,b,c,d,e|c<6&&e<6&&a*9+b<22}}

Try it online!

Input: Sorted array of digits (as integers).

Output: Array of digits or nil if no solution found

G B

Posted 2018-05-09T06:59:45.983

Reputation: 11 099

You can drop the space at eval " I think. – Kevin Cruijssen – 2018-05-09T07:35:57.497

Yes, it works, thanks. – G B – 2018-05-09T07:47:12.843

I think you can do a*9+b<22 for one byte. – JayCe – 2018-06-12T20:24:24.023

3

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.

Nit

Posted 2018-05-09T06:59:45.983

Reputation: 2 667

25 bytes – Shaggy – 2018-05-09T10:28:00.967

@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. – Nit – 2018-05-09T11:17:33.967

3

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.

Lynn

Posted 2018-05-09T06:59:45.983

Reputation: 55 648

2Could you use 62**3 instead of 240000? – Arnauld – 2018-05-09T11:22:59.477

3

Jelly, 15 bytes

Œ!s€2Ḍf«¥“ç;;‘Ṃ

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.

Erik the Outgolfer

Posted 2018-05-09T06:59:45.983

Reputation: 38 134

2

Wolfram Language (Mathematica), 63 bytes

FirstCase[Permutations@#,{a:0|1|2,b_,c_,_,d_,_}/;a*b-4<6>d>=c]&

Try it online!

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

Explanation

Permutations@#

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

{a:0|1|2,b_,c_,_,d_,_}

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.

JungHwan Min

Posted 2018-05-09T06:59:45.983

Reputation: 13 290

2

Jelly, 17 bytes

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

Œ!s2Ḍ<ẠʋÐṀ“ð<<‘ṢḢ

Try it online!

Jonathan Allan

Posted 2018-05-09T06:59:45.983

Reputation: 67 804

You're correct, this is not the shortest approach. However, public humiliation isn't nice, so I won't comment on the improvements yet. :) – Erik the Outgolfer – 2018-05-09T12:08:37.560

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! – Jonathan Allan – 2018-05-09T12:54:00.783

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? – Erik the Outgolfer – 2018-05-09T13:02:12.583

Go ahead and post. Health is fine, I'm at work so can't spend time golfing!! – Jonathan Allan – 2018-05-09T13:11:33.487

Posted. Now you can see why I was referring to the "humiliation". :P – Erik the Outgolfer – 2018-05-09T13:22:52.067

2

Perl 5 with -palF, 73 bytes

$"=",";($_)=grep@F~~[sort/./g]&/([01]\d|2[0-3])([0-5]\d){2}/,glob"{@F}"x6

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!

Dom Hastings

Posted 2018-05-09T06:59:45.983

Reputation: 16 415

2

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;"

00:00:00
00:00:01
...
23:59:59

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

Test

%./timecomb 1 2 3 4 6 8
12:36:48
%./timecomb 2 5 5 5 5 5
%./timecomb 0 0 0 1 1 1
00:01:11
%./timecomb 1 1 2 2 3 3
11:22:33
%./timecomb 9 9 9 9 9 9
%./timecomb 2 3 5 5 9 9
23:59:59
%./timecomb 1 2 3 4 5 6
12:34:56
%./timecomb 0 0 0 0 0 0
00:00:00
%./timecomb 1 5 5 8 8 8
18:58:58
%./timecomb 1 5 5 5 8 8
15:58:58
%./timecomb 1 1 1 8 8 8
18:18:18

Try It Online !

zeppelin

Posted 2018-05-09T06:59:45.983

Reputation: 7 884

2

Pyth, 37 bytes

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

Test suite

Explanation:
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

hakr14

Posted 2018-05-09T06:59:45.983

Reputation: 1 295

2

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]
l=l||(e&&t[p]<o[p])
e=e&&t[p]==o[p]}
if(t[0]<24&&t[1]<60&&t[2]<60&&l)for(p in 0..2)o[p]=t[p]}
else
for(p in 0..5)if(f[p]){f[p]=0>1
s[i]=d[p]
r(i+1)
f[p]=1>0}}
r(0)
if(o[0]>23)0
else "${o[0]}:${o[1]}:${o[2]}"}()

Try it online!

JohnWells

Posted 2018-05-09T06:59:45.983

Reputation: 611

2I 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. – Kevin Cruijssen – 2018-06-19T13:42:12.497

@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. – JohnWells – 2018-06-28T12:53:15.957

12 more bytes to golf in your latest version: "0" can be just 0 – Kevin Cruijssen – 2018-06-28T13:06:58.117

@Kevin that won't be a String type and I'd have to add :Any to allow both String and Int. – JohnWells – 2018-06-28T13:31:15.460

1Hmm 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. – Kevin Cruijssen – 2018-06-28T13:45:20.753

@Kevin I'm guessing the {}() pattern is smarter than the = if () 0 else "" as you get an error in the second case of mismatched types, but you're right the first works fine. I guess I must hunt down why... – JohnWells – 2018-06-29T11:15:32.900

2

MATL, 31 30 bytes

Y@3Xy[X1]X*!Y*t[4XX]6*<!AY)1Y)

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.)

sundar - Reinstate Monica

Posted 2018-05-09T06:59:45.983

Reputation: 5 296

I think you can replace 2&A by !A, because the binary matrix will never be a row vector – Luis Mendo – 2018-07-20T23:42:17.283

1

Perl 6, 43 bytes

*.permutations.first:{24e4>.join&&6>.[2&4]}

Try it online!

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

nwellnhof

Posted 2018-05-09T06:59:45.983

Reputation: 10 037

1

Stax, 15 bytes

╝a╣=→aá≈#8(⌂≈58

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"

recursive

Posted 2018-05-09T06:59:45.983

Reputation: 8 616

1

Retina, 58 47 bytes

+,V^2`[0-5][6-9]{2}
G`([01].|2[0-3])([0-5].){2}

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

Explanation

Algorithm

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.


Program

+,V^2`[0-5][6-9]{2}

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.

G`([01].|2[0-3])[0-5].[0-5].

Only keeps the string if it is a valid time

TwiNight

Posted 2018-05-09T06:59:45.983

Reputation: 4 187