g | x | w | all
Bytes Lang Time Link
009Japt h250630T202056ZShaggy
107Swift 6240403T005935ZmacOSist
022Haskell + hgl240402T212103ZWheat Wi
037Curry KiCS2 + set +first220629T021442Zalephalp
044Raku220914T034429ZSean
064Prolog SWI220914T023242ZJo King
099Regex .NET + x flag220628T203753ZDeadcode
120Python 3.8 prerelease220628T145653ZJitse
082JavaScript ES6220628T150321ZArnauld
006Brachylog220628T113638ZFatalize
010Husk220629T093502ZDominic
00605AB1E220629T073301ZKevin Cr
051JavaScript Node.js220629T072425Ztsh
071JavaScript Node.js220629T041628Ztsh
028Charcoal220628T204845ZNeil
062Haskell220628T172211Zlynn
094Python 3.8 prerelease220628T162349Zloopy wa
009Jelly220628T161341ZUnrelate
013Pyth220628T152108Zmath jun
nanRust220628T145053Zmousetai
066R220628T144702ZDominic
071Julia220628T144127ZMarcMush
037J220628T143920ZJonah
142Python3220628T132521ZAjax1234
008Vyxal220628T113405Zlyxal

Japt -h, 9 bytes

Horribly inefficient!

õ ã fȬ¥U

Try it

õ ã fȬ¥U     :Implicit input of integer U
õ             :Range [1,U]
  ã           :Sub-arrays
    f         :Filter by
     È        :Passing each through the following array
      ¬       :  Join
       ¥U     :  Is loosely equal to U
              :Implicit output of last element

Swift 6, 143 134 110 107 bytes

{s in[]+(1...).lazy.map{i in(1...(s+"").count).map{i..<i+$0}}.joined().first{s==$0.map{"\($0)"}.joined()}!}

Try it on SwiftFiddle!

There are definitely some more optimizations that can be done here (using flatMap(_:), for instance), but this is already dangerously close to reaching the limits of the type checker, so I think I'll leave it for now.

Haskell + hgl, 22 bytes

glk$my ν@~(mF eq1<δ)

Attempt This Online!

Explanation

Reflection

I spend so many bytes here determining if a list is a sequence of ascending positive integers. Here are all the ways I've found to do this in 9 bytes:

mF eq1<δ
no nq1<δ
lq<ixm sb

(note that δ is two bytes not one)

I'd like to have a version of this which isn't so brute-force-y. This basically takes every partition of the input and then checks for consecutive sequences. This is totally unnecessary, once you choose the first number of your partition the rest is set in stone.

Curry (KiCS2) + :set +first, 37 bytes

f(x#y)=[x..y]
x#y|y-x>0=[x..y]>>=show

Attempt This Online!

A port of Fatalize's Brachylog answer.

This does not work on PAKCS.

Raku, 44 bytes

{+«m/^(\d+?)+<?{1==all $0[1..*]Z-$0}>$/[0]}

Try it online!

The regex match m/.../ does the heavy lifting here.

Finally, [0] extracts the first matching group--which is a list, since the group was followed by a quantifier--and converts those match objects to numbers.

Prolog (SWI), 68 64 bytes

-4 bytes thanks to Steffan pointing out a golf I somehow missed

A+B:-nth1(X,_,_),between(1,X,Y),numlist(Y,X,B),concat_atom(B,A).

Try it online!

Pretty straightforward.

Explanation:

A+B:-                 % A predicate with an atom A and a list of numbers B
     nth1(X,_,_),       % Find a positive number X
     between(1,X,Y),    % And a number Y between 1 and X
     numlist(Y,X,B),    % Generate the range [Y,X] into B
     concat_atom(B,A).  % The concatenated list should be the same atom as A

Regex (.NET) + x flag, 418 209 204 199 132 115 99 bytes

-209 bytes (418 → 209) thanks to Neil

(\5$|(.*(?=(0.*1|1.*2|2.*3|3.*4|4.*5|5.*6|6.*7|7.*8|8.*9)(?<=(.)))|(?=9+(?<4>1))).9*(?=(\2\4 0*)))*

Returns its result as the list of captures on the Balancing Group 1 stack.

Try it online!

# Main loop - Iterates once for each matched number in the squashed sequence.
# There is no need to anchor, because the input is guaranteed to be valid.
(                       # \1 = push matched number onto the Group 1 stack
    \5$                 # Stop immediately if the previous iteration identified
                        # this as being next, and there is nothing following it.
|
    # Using greedy quantifiers, the following, up to and including "9*",
    # matches the number with as many digits as possible that is followed by
    # the next consecutive number.
    (                   # \2 = the prefix portion of the number that won't
                        #      change when incremented
        .*
        (?=
            # Depending on this next digit, capture its incremented form in \4.
            # Only digits that do not carry when incremented are handled here.
            (
                0.*1 |
                1.*2 |
                2.*3 |
                3.*4 |
                4.*5 |
                5.*6 |
                6.*7 |
                7.*8 |
                8.*9
            )
            (?<=(.))    # \4
        )
    |
        # Treat a prefix of all 9s as a special case, because when incremented
        # it will be one digit longer, e.g. 999 -> 1000. In this case, \2 will
        # be empty.
        (?=
            9+
            (?<4>1)     # \4 - Technically this should capture "10", but since
                        #      our input is guaranteed to be valid, we can
                        #      assume that the "0*" below will match the
                        #      correct number of zeroes.
        )
    )
    .                   # Skip over the first digit that will be different when
                        # incremented.
    9*                  # Skip over the portion that will become all 0s when
                        # incremented.
    
    # Match the next consecutive number. This constraint is what tells the
    # above how many digits to match.
    (?=
        (               # \5 = Capture the next number. This allows the last
                        #      number in the sequence to be matched as a whole
                        #      unambiguously, in case its digits form their own
                        #      "nested" squashed sequence.
            \2
            \4          # Note that since this is followed by a "0", to get
                        # this to parse correctly we could either concatenate
                        # them as "\4[0]*", or enable the /x flag (ignore
                        # whitespace) and use "\4 0*".
            0*          # Technically this should match the same number of 0s
                        # however many 9s were matched by "9*" above, but since
                        # our input is guaranteed to be valid, we can assume it
                        # will do this without being forced, since none of the
                        # numbers in the sequence will have leading zeroes.
        )
    )
)*                      # Iterate as many times as possible, with minimum zero.

Solving this problem is a bit verbose in pure regex, since it has no concept of alphanumeric/ASCII order or sorting. So each digit needs to be handled as a separate case.

Rejecting invalid input takes 138 bytes: ^(\6$|(?!0)(.*(?=(0.*1|1.*2|2.*3|3.*4|4.*5|5.*6|6.*7|7.*8|8.*9)(?<=(.)))|(?=9+(?<4>10))).(9)*(?=(?(7)\7))(?=(\2\4(?<-5>0)*(?(5)^))(.*)))*$

Regex (PCRE) + x flag, 107 bytes

(\4$|(?|(.*)(?=(?:0.*1|1.*2|2.*3|3.*4|4.*5|5.*6|6.*7|7.*8|8.*9)(?<=(.)))|()(?=9+(1))).9*(?=(\2\3 0*))(?C))*

Returns its result using a (?C) callout to report each split point (the number of split points will be one less than the number of consecutive integers).

Try it online! - PCRE1
Try it online! - PCRE2 v10.33
Attempt This Online! - PCRE2 v10.40+

This is a straightforward port of the .NET version.

# Main loop - Iterates once for each matched number in the squashed sequence.
# There is no need to anchor, because the input is guaranteed to be valid.
(
    \4$                 # Stop immediately if the previous iteration identified
                        # this as being next, and there is nothing following it.
|
    # Using greedy quantifiers, the following, up to and including "9*",
    # matches the number with as many digits as possible that is followed by
    # the next consecutive number.
    (?|
        (.*)            # \2 = the prefix portion of the number that won't
                        #      change when incremented
        (?=
            # Depending on this next digit, capture its incremented form in \3.
            # Only digits that do not carry when incremented are handled here.
            (?:
                0.*1 |
                1.*2 |
                2.*3 |
                3.*4 |
                4.*5 |
                5.*6 |
                6.*7 |
                7.*8 |
                8.*9
            )
            (?<=(.))    # \3
        )
    |
        # Treat a prefix of all 9s as a special case, because when incremented
        # it will be one digit longer, e.g. 999 -> 1000. In this case, \2 will
        # be empty.
        ()              # \2 = empty prefix
        (?=
            9+
            (1)         # \3 - Technically this should capture "10", but since
                        #      our input is guaranteed to be valid, we can
                        #      assume that the "0*" below will match the
                        #      correct number of zeroes.
        )
    )
    .                   # Skip over the first digit that will be different when
                        # incremented.
    9*                  # Skip over the portion that will become all 0s when
                        # incremented.
    (?=
        (               # \4 = Capture the next number. This allows the last
                        #      number in the sequence to be matched as a whole
                        #      unambiguously, in case its digits form their own
                        #      "nested" squashed sequence.
            \2
            \3          # Note that since this is followed by a "0", to get
                        # this to parse correctly we could either concatenate
                        # them as "\3[0]*", or enable the /x flag (ignore
                        # whitespace) and use "\3 0*".
            0*          # Technically this should match the same number of 0s
                        # however many 9s were matched by "9*" above, but since
                        # our input is guaranteed to be valid, we can assume it
                        # will do this without being forced, since none of the
                        # numbers in the sequence will have leading zeroes.
        )
    )
    (?C)                # PCRE callout - report each split point to the caller
)*

Rejecting invalid input is not so straightforward to port from the .NET version, and takes 175 bytes: ^(?>\7$((9(?=9*\4\5(\3?+0)))*(?=(?(6)\6))\4\5\3?+)?|(?|(?!0)(.*)(?=(?:0.*1|1.*2|2.*3|3.*4|4.*5|5.*6|6.*7|7.*8|8.*9)(?<=(.)))|()(?=9+(10))).(?=(?1)(.*))9*(?=(\4\5 0*)\6)(?C))*$

Regex (PCRE2) + x flag, 166 bytes

(?=(.*))(?:^(?3)|((?<=(?=^((?|(.*)(?=(?:0.*1|1.*2|2.*3|3.*4|4.*5|5.*6|6.*7|7.*8|8.*9)(?<=(.)))|()(?=9+(1))).9*(?=(\4\5 0*)))*(?=\1$)(?>\6$|)(?(?=$)^)|(?2)).))(?3)|.+)

Returns its result as the list of individual matches.

Attempt This Online!

A lot of overhead is added to achieve this output method. Captures are not preserved from one individual match to the next, thus to avoid incorrectly splitting the last number, the regex must look all the way back to the start, then parse forward from there, for each individual match. There's no variable-length lookbehind in PCRE2, so it is emulated using recursion.

Python 3.8 (pre-release), 120 bytes

lambda s:g(s)[1]
g=lambda s:s and[j+[k]for i in range(-len(s),0)for j in g(s[:i])if{*j[-1:]}<={~-(k:=int(s[i:]))}]or[[]]

Try it online!

JavaScript (ES6), 82 bytes

f=(S,i=s='')=>(k=s+=S[i++],g=q=>q==S?o:S.match(q)?g(q+k,o.push(k++)):f(S,i))(o=[])

Try it online!

Commented

f = (                 // f is a recursive function taking:
  S,                  //   S = input string
  i =                 //   i = pointer in S
  s = ''              //   s = current prefix extracted from S
) => (                //
  k = s += S[i++],    // append the next character from S to s,
                      // copy the prefix in k and increment i
  g = q =>            // g is a recursive function taking a string q
    q == S ?          //   if q is equal to S:
      o               //     success: return o[]
    :                 //   else:
      S.match(q) ?    //     if q is found in S (*):
        g(            //       do a recursive call:
          q + k,      //         append k to q (q is coerced to a
                      //         string if it's not already)
          o.push(k++) //         append k to o[] (and increment k)
        )             //       end of recursive call
      :               //     else:
        f(S, i)       //       try again with an additional character
)(o = [])             // initial call to g with s = o = []

(*) This doesn't mean that q is correct so far because it can be found in the middle of the string. The purpose of this test is rather to know when to give up.

Brachylog, 8 6 bytes

Ṁ∧⟦₂?c

Try it online!

Thanks to @UnrelatedString for -2 bytes.

Takes an integer as the output variable, and unifies the answer with the input variable (so the opposite of what is usually done).

Atrociously slow, as concatenation on integers computes constraints on the digits with powers of 10, instead of being "string" concatenation.

Explanation

Ṁ         The answer has 2 or more elements
 ∧        And
   ⟦₂?    The answer is a range between 2 integers
     ?c   The given input is the concatenation of this range

Husk, 10 bytes

ḟo=⁰ṁsṁṫḣN

Try it online!

      ṁ  N  # map across all integers N & concatenate:
        ḣ   #  range 1..N
       ṫ    #  suffix series: 1..N, 2..N, 3..N, ...
ḟo          # now return the first series 
  =⁰        #  for which the input equals    
    ṁs      #  mapped & concatenated string representations

05AB1E, 6 bytes

.œ.Δ¥P

Try it online or verify all test cases.

Explanation:

.œ      # Get all partitions of the (implicit) input (the partition-list is ordered from
        # longest (all single digits) to shortest (single original integer)) 
  .Δ    # Find the first which is truthy for:
    ¥   #  Pop and push the deltas / forward differences
     P  #  Take the product of that
        #  (only 1 is truthy in 05AB1E)
        # (after which the result is output implicitly)

JavaScript (Node.js), 51 bytes

n=>(g=s=>s.match(n.join`,?`)||g(s+[,++i]))(i='')[0]

Try it online!

Input an array of characters. Output comma separated numbers as a single string.

It passes all testcases listed here. But I still have no idea if this answer is correct or not. Failed testcases are welcomed and I will try to fix it some how.

JavaScript (Node.js), 71 bytes

f=(s,i,p='',...a)=>p==s?a:s.match(p)&&f(s,-~i,p+i,...a,i)||!p&&f(s,-~i)

Try it online!

Charcoal, 28 bytes

FIEθ…θ⊕κFLθ⊞υI…ι⁺⊕ι⊕κΦυ⁼θ⪫ιω

Try it online! Link is to verbose version of code. Explanation:

FIEθ…θ⊕κ

Loop over all of the nontrivial prefixes of the input.

FLθ⊞υI…ι⁺⊕ι⊕κ

Create ranges of length 2 up to the length of the input starting at each prefix.

Φυ⁼θ⪫ιω

Find any ranges whose concatenation equals the original input.

Haskell, 62 bytes

f s=[[a..b]|a<-[1..],b<-[a..a+length s],([a..b]>>=show)==s]!!0

Try it online!

Python 3.8 (pre-release), 94 bytes

f=lambda a,d=2,c=1:(r:=(*range(x:=int(a[:c]),x+d),))*(d*"%d"%r==a)or f(a,d:=d%len(a)+1,c+1//d)

Try it online!

Nothing too fancy here.

Jelly, 9 bytes

ŒṖḌIİƑ$ƇḢ

Try it online!

ŒṖ           Find every partition of the input's digits,
  Ḍ          and convert each slice in each partition back to an integer.
       Ƈ     Filter to only those which
   I         have forward differences
    İƑ$      which are all their own inverses (i.e. 1).
        Ḣ    Yield the first remaining partition (nontrivial).

Pyth, 13 bytes

ef!-.+T1sMM./

Try it online!

Accepts a string as input.

ef!-.+T1sMM./
           ./  String partitions of the input
        sMM    Convert elements to integers
 f    T        Filter for paritions T such that:
    .+           The list of deltas between elements of T...
  !-   1         ...becomes empty when 1s are removed
e              Keep the last remaining partition

Rust, 242 235 bytes

|t:Vec<u64>|(0..).map(|v|{let mut y=vec![];y.extend(t.iter().scan((v,0),|(a,b),c|Some(if *b*10+c==*a+1{*a=c+*b*10;*b=0;Some(*a)}else{*b=*b*10+c;None})));y.last().unwrap().and(Some(y.into_iter().flatten()))}).flatten().next().unwrap();

Tries every initial number till it finds one that completes the sequence. Playground

Saved 7 bytes by using let mut y=vec![];y.extend(X) unstead of let y:Vec<Option<u64>>=X.collect()

R, 66 bytes

\(n)repeat for(i in 1:(T=T+1))if(n==Reduce(paste0,i:T))return(i:T)

Attempt This Online!

Julia, 71 bytes

! =length
*(s,a=1,b=a,j=join(a:b))=!j<!s ? s*a*-~b : j!=s ? s*-~a : a:b

Attempt This Online!

Takes a string as input and returns a range (2:5 == [2,3,4,5]).

A brute-force approach that's actually not that bad. a is the starting number and b the last number. We increment b until the list is too long and start over for a=a+1

J, 37 bytes

0{<((=<@;\"1)#&,<\"1@])".\<@":@+/i.@#

Try it online!

Not much in the way of golfiness (and it could surely be golfed more), but it executes decently fast, solving the test cases effectively instantly.

Python3, 142 bytes:

f=lambda x,l=[]:l if''==x else max(w,key=len)if(w:=[f(x[k+1:],l+[int(x[:k+1])])for k,_ in enumerate(x)if l==[]or int(x[:k+1])==l[-1]+1])else w

Try it online!

Vyxal, 10 8 bytes

øṖ⌊'ḣtṡ⁼

Try it Online!

Incredibly slow for some inputs, reasonable for others.

Explained

øṖ⌊'ḣtṡ⁼
øṖ⌊      # All sublists of the input, as numbers
   '     # Keep only those where:
    ḣtṡ  #   The range between the first and last item
       ⁼ #   Exactly equals the original item