Indentation-based Sort

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
35
down vote

favorite
2












Given an ordered list of same-case letter strings (a-z XOR A-Z) where each string is preceded by 0 or more space ( ) characters, output the same list but with the strings sorted at each level of indentation. Indentation depths under different parents count as distinct lists for sorting purposes.



Example



If your input is:



bdellium
fox
hound
alien
aisle
wasabi
elf
alien
horseradish
xeno
irk
wren
tsunami
djinn
zebra


your output should be



aisle
horseradish
xeno
wasabi
alien
elf
bdellium
alien
fox
hound
djinn
zebra
irk
tsunami
wren


If you like, think of it like a directory listing, and you need to sort the names within each directory.



Minutiae



  • An item may be indented by any number of spaces. If it is indented by the same number of spaces as the previous item it belongs in the same sort hierarchy as the previous item. If it is indented by more spaces it is the start of a new sub-hierarchy.

  • If a line is indented by fewer spaces than the line above it, it links up to the closest sub group above it with the same # or fewer spaces before it (like horseradish in the above example, which links onto the wasabi group above it because wasabi is the first item above it to not have more spaces than horseradish)

  • You must preserve the indenting level of each input item in your output

  • Tabs in the output are disallowed

  • The first line of the input will never be indented

  • Your program must handle at least one of all-uppercase and all-lowercase strings; it doesn't have to handle both.

Scoring



This is a code-golf, so the answer which uses the fewest bytes wins.







share|improve this question


















  • 7




    Nice challenge!
    – Adám
    Aug 21 at 22:22






  • 1




    Btw, for next time, consider using the Sandbox to iron out issues with a challenge before posting it to the main site.
    – Adám
    Aug 21 at 22:34






  • 8




    @Adám No, the recursive string parsing logic required is the reason I wrote this prompt.
    – Techrocket9
    Aug 21 at 22:43






  • 2




    If the input is ['a','..b', '.c', '..d'], what should the output be? ['a','..b', '.c', '..d'] or ['a','.c','..b', '..d'] or some other thing? (I'm using '.' instead of space for visual clarity).
    – Chas Brown
    Aug 22 at 0:03







  • 2




    @streetster strings (a-z XOR A-Z)
    – Adám
    Aug 22 at 21:12














up vote
35
down vote

favorite
2












Given an ordered list of same-case letter strings (a-z XOR A-Z) where each string is preceded by 0 or more space ( ) characters, output the same list but with the strings sorted at each level of indentation. Indentation depths under different parents count as distinct lists for sorting purposes.



Example



If your input is:



bdellium
fox
hound
alien
aisle
wasabi
elf
alien
horseradish
xeno
irk
wren
tsunami
djinn
zebra


your output should be



aisle
horseradish
xeno
wasabi
alien
elf
bdellium
alien
fox
hound
djinn
zebra
irk
tsunami
wren


If you like, think of it like a directory listing, and you need to sort the names within each directory.



Minutiae



  • An item may be indented by any number of spaces. If it is indented by the same number of spaces as the previous item it belongs in the same sort hierarchy as the previous item. If it is indented by more spaces it is the start of a new sub-hierarchy.

  • If a line is indented by fewer spaces than the line above it, it links up to the closest sub group above it with the same # or fewer spaces before it (like horseradish in the above example, which links onto the wasabi group above it because wasabi is the first item above it to not have more spaces than horseradish)

  • You must preserve the indenting level of each input item in your output

  • Tabs in the output are disallowed

  • The first line of the input will never be indented

  • Your program must handle at least one of all-uppercase and all-lowercase strings; it doesn't have to handle both.

Scoring



This is a code-golf, so the answer which uses the fewest bytes wins.







share|improve this question


















  • 7




    Nice challenge!
    – Adám
    Aug 21 at 22:22






  • 1




    Btw, for next time, consider using the Sandbox to iron out issues with a challenge before posting it to the main site.
    – Adám
    Aug 21 at 22:34






  • 8




    @Adám No, the recursive string parsing logic required is the reason I wrote this prompt.
    – Techrocket9
    Aug 21 at 22:43






  • 2




    If the input is ['a','..b', '.c', '..d'], what should the output be? ['a','..b', '.c', '..d'] or ['a','.c','..b', '..d'] or some other thing? (I'm using '.' instead of space for visual clarity).
    – Chas Brown
    Aug 22 at 0:03







  • 2




    @streetster strings (a-z XOR A-Z)
    – Adám
    Aug 22 at 21:12












up vote
35
down vote

favorite
2









up vote
35
down vote

favorite
2






2





Given an ordered list of same-case letter strings (a-z XOR A-Z) where each string is preceded by 0 or more space ( ) characters, output the same list but with the strings sorted at each level of indentation. Indentation depths under different parents count as distinct lists for sorting purposes.



Example



If your input is:



bdellium
fox
hound
alien
aisle
wasabi
elf
alien
horseradish
xeno
irk
wren
tsunami
djinn
zebra


your output should be



aisle
horseradish
xeno
wasabi
alien
elf
bdellium
alien
fox
hound
djinn
zebra
irk
tsunami
wren


If you like, think of it like a directory listing, and you need to sort the names within each directory.



Minutiae



  • An item may be indented by any number of spaces. If it is indented by the same number of spaces as the previous item it belongs in the same sort hierarchy as the previous item. If it is indented by more spaces it is the start of a new sub-hierarchy.

  • If a line is indented by fewer spaces than the line above it, it links up to the closest sub group above it with the same # or fewer spaces before it (like horseradish in the above example, which links onto the wasabi group above it because wasabi is the first item above it to not have more spaces than horseradish)

  • You must preserve the indenting level of each input item in your output

  • Tabs in the output are disallowed

  • The first line of the input will never be indented

  • Your program must handle at least one of all-uppercase and all-lowercase strings; it doesn't have to handle both.

Scoring



This is a code-golf, so the answer which uses the fewest bytes wins.







share|improve this question














Given an ordered list of same-case letter strings (a-z XOR A-Z) where each string is preceded by 0 or more space ( ) characters, output the same list but with the strings sorted at each level of indentation. Indentation depths under different parents count as distinct lists for sorting purposes.



Example



If your input is:



bdellium
fox
hound
alien
aisle
wasabi
elf
alien
horseradish
xeno
irk
wren
tsunami
djinn
zebra


your output should be



aisle
horseradish
xeno
wasabi
alien
elf
bdellium
alien
fox
hound
djinn
zebra
irk
tsunami
wren


If you like, think of it like a directory listing, and you need to sort the names within each directory.



Minutiae



  • An item may be indented by any number of spaces. If it is indented by the same number of spaces as the previous item it belongs in the same sort hierarchy as the previous item. If it is indented by more spaces it is the start of a new sub-hierarchy.

  • If a line is indented by fewer spaces than the line above it, it links up to the closest sub group above it with the same # or fewer spaces before it (like horseradish in the above example, which links onto the wasabi group above it because wasabi is the first item above it to not have more spaces than horseradish)

  • You must preserve the indenting level of each input item in your output

  • Tabs in the output are disallowed

  • The first line of the input will never be indented

  • Your program must handle at least one of all-uppercase and all-lowercase strings; it doesn't have to handle both.

Scoring



This is a code-golf, so the answer which uses the fewest bytes wins.









share|improve this question













share|improve this question




share|improve this question








edited Aug 22 at 2:50

























asked Aug 21 at 21:59









Techrocket9

345211




345211







  • 7




    Nice challenge!
    – Adám
    Aug 21 at 22:22






  • 1




    Btw, for next time, consider using the Sandbox to iron out issues with a challenge before posting it to the main site.
    – Adám
    Aug 21 at 22:34






  • 8




    @Adám No, the recursive string parsing logic required is the reason I wrote this prompt.
    – Techrocket9
    Aug 21 at 22:43






  • 2




    If the input is ['a','..b', '.c', '..d'], what should the output be? ['a','..b', '.c', '..d'] or ['a','.c','..b', '..d'] or some other thing? (I'm using '.' instead of space for visual clarity).
    – Chas Brown
    Aug 22 at 0:03







  • 2




    @streetster strings (a-z XOR A-Z)
    – Adám
    Aug 22 at 21:12












  • 7




    Nice challenge!
    – Adám
    Aug 21 at 22:22






  • 1




    Btw, for next time, consider using the Sandbox to iron out issues with a challenge before posting it to the main site.
    – Adám
    Aug 21 at 22:34






  • 8




    @Adám No, the recursive string parsing logic required is the reason I wrote this prompt.
    – Techrocket9
    Aug 21 at 22:43






  • 2




    If the input is ['a','..b', '.c', '..d'], what should the output be? ['a','..b', '.c', '..d'] or ['a','.c','..b', '..d'] or some other thing? (I'm using '.' instead of space for visual clarity).
    – Chas Brown
    Aug 22 at 0:03







  • 2




    @streetster strings (a-z XOR A-Z)
    – Adám
    Aug 22 at 21:12







7




7




Nice challenge!
– Adám
Aug 21 at 22:22




Nice challenge!
– Adám
Aug 21 at 22:22




1




1




Btw, for next time, consider using the Sandbox to iron out issues with a challenge before posting it to the main site.
– Adám
Aug 21 at 22:34




Btw, for next time, consider using the Sandbox to iron out issues with a challenge before posting it to the main site.
– Adám
Aug 21 at 22:34




8




8




@Adám No, the recursive string parsing logic required is the reason I wrote this prompt.
– Techrocket9
Aug 21 at 22:43




@Adám No, the recursive string parsing logic required is the reason I wrote this prompt.
– Techrocket9
Aug 21 at 22:43




2




2




If the input is ['a','..b', '.c', '..d'], what should the output be? ['a','..b', '.c', '..d'] or ['a','.c','..b', '..d'] or some other thing? (I'm using '.' instead of space for visual clarity).
– Chas Brown
Aug 22 at 0:03





If the input is ['a','..b', '.c', '..d'], what should the output be? ['a','..b', '.c', '..d'] or ['a','.c','..b', '..d'] or some other thing? (I'm using '.' instead of space for visual clarity).
– Chas Brown
Aug 22 at 0:03





2




2




@streetster strings (a-z XOR A-Z)
– Adám
Aug 22 at 21:12




@streetster strings (a-z XOR A-Z)
– Adám
Aug 22 at 21:12










9 Answers
9






active

oldest

votes

















up vote
1
down vote



accepted











Pyth, 23 bytes



jeMtSuaG+f</Td/HdeGHQ]Y


Try it here!






share|improve this answer





























    up vote
    14
    down vote














    Python 2, 117 bytes





    lambda S:[s[-1]for s in sorted(reduce(lambda t,s:t+[[v for v in t[-1]if v.count(' ')<s.count(' ')]+[s]],S,[]))[1:]]


    Try it online!



    Takes as input a list of strings; and outputs a list of strings, sorted as required.



    The idea is to turn each element into a list which contains the "absolute path" as a list; and then let Python handle the sorting. E.g. if the input is:



    [
    'a',
    ' c',
    ' d',
    ' b'
    ]


    Then via the reduce(), we convert to a list of lists:



    [
    ['a'],
    ['a',' c'],
    ['a',' c', ' d'],
    ['a',' b']
    ]


    which gets sorted as:



    [
    ['a'],
    ['a',' b']
    ['a',' c'],
    ['a',' c', ' d'],
    ]


    and then output the last element of each list in the list-of-lists to get:



    [
    'a',
    ' b'
    ' c',
    ' d',
    ]





    share|improve this answer






















    • Wow the solution I was about to post was 183 bytes...I suck lol
      – Rushabh Mehta
      Aug 22 at 0:18






    • 4




      @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
      – Chas Brown
      Aug 22 at 0:28

















    up vote
    7
    down vote














    APL (Dyalog Unicode), 31 bytesSBCS





    Anonymous prefix lambda, takes and returns list of strings.



    ⍵[⍋1=≢⍵:⍺⋄⍵⍀↑' '(,⊂⍨⊣=,)¨⍵]


    Try it online!



    … "dfn"; ⍵ is argument



     ⍵[…] index the argument with the following indices:



      ' '(…)¨⍵ apply the following tacit function to each string with space as left argument:



       , concatenate the space to the string



       ⊣= Boolean list indicating where the space is equal to each character that



       ,⊂⍨ use that to partition (begin part where true) the concatenation of space and string



      ↑ mix list of lists of strings into matrix of strings



      …⍀ vertical cumulative reduction by this "dfn"; ⍺ and ⍵ are upper and lower args:



       ≢⍵ the length of the lower string



       1= is that equal to 1? (i.e. is there nothing but the single space there?)



       :⍺ if so, return the upper argument



       ⋄⍵ else, return the lower argument



      ⍋ grade up (find indices which will sort that)






    share|improve this answer





























      up vote
      7
      down vote














      Retina, 47 bytes



      +-1m`(?<=^2(S+).*?¶( *)) 
      $1
      O$`
      $L$&
      S+



      Try it online! Note: Several lines have trailing spaces. Explanation:



      +-1m`(?<=^2(S+).*?¶( *)) 
      $1


      The first step is to insert each word into following lines at the same indentation. For example, with the lines aisle, wasabi and elf the resulting lines are aisle, aisle wasabi and aisle wasabi elf. I discovered this regex by trial and error so there may be edge cases with it.



      O$`
      $L$&


      We can now sort the lines case-insensitively.



      S+ 



      Delete all of the inserted words.






      share|improve this answer



























        up vote
        4
        down vote














        Perl 6, 120 83 81 63 54 37 47 42 bytes



        -5 bytes thanks to nwellnhof





        my@a;.sort:@a[+.comb(' ')..*+1]=$_;~@a


        Try it online!



        This uses Chas Brown's method. An anonymous code block that takes a list of lines and returns a list of lines.



        Explanation:



         # Anonymous code block
        my@a; # Declare a local list
        .sort # Sort the given list of lines
        : # By converting each line to:
        @a[+.comb(' ')..*+1]=$_; # Set the element at that indentation level onwards to that line
        ~@a # And return the list coerced to a string





        share|improve this answer






















        • @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
          – Jo King
          Aug 22 at 9:57










        • @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
          – Jo King
          Aug 22 at 11:01










        • Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
          – nwellnhof
          Aug 22 at 12:02

















        up vote
        3
        down vote














        Clean, 112 101 bytes



        import StdEnv
        f=flatten
        ?e=[0\' '<-e]
        $[h:t]#(a,b)=span(u= ?u> ?h)t
        =sort[[h:f($a)]: $b]
        $e=




        f o$


        Try it online!



        Anonymous function :: [[Char]] -> [[Char]] which wraps $ :: [[Char]] -> [[[Char]]] into the right output format. $ groups the strings into "more spaces than" and "everything else afterwards", recurses over each group and sorts when they're adjoined. At each step, the list being sorted looks like:



        [[head-of-group-1,child-1,child-2..],[head-of-group-2,child-1,child-2..]..]



        Clean, 127 bytes



        import StdEnv
        $l=[x++y\z<- ?(map(span((>)'!'))l),(x,y)<-z]
        ?[h:t]#(a,b)=span((u,_)=u>fst h)t
        =sort[[h:flatten(?a)]: ?b]
        ?e=


        Try it online!



        Defines the function $ :: [[Char]] -> [[Char]] which separates the strings into tuples in the form (spaces, letters) which are recursively sorted by the helper function ? :: [([Char],[Char])] -> [[([Char],[Char])]].



        Explained:



        $ list // the function $ of the list
        = [ // is
        spaces ++ letters // the spaces joined with the letters
        \ sublist <- ? ( // from each sublist in the application of ? to
        map ( // the application of
        span ((>)'!') // a function separating spaces and letters
        ) list // to every element in the list
        )
        , (spaces, letters) <- sublist // the spaces and letters from the sublist
        ]

        ? [head: tail] // in the function ? of the head and tail of the input
        # (group, others) // let the current group and the others equal
        = span ( // the result of separating until ... is false
        (u, _) = u > // only elements where there are more spaces
        fst head // than in the head of the input
        ) tail // the tail of the input
        = sort [
        [head // prepend the head of the input to
        : flatten (?group) // the flat application of ? to the first group
        ] // and prepend this to
        : ?others // the application of ? to the other group(s)
        ]

        ? empty = // match the empty list





        share|improve this answer





























          up vote
          1
          down vote














          JavaScript (Node.js), 114 100 92 88 bytes





          x=>x.map(y=>a=a.split(/ */.exec(y)[0]||a)[0]+y,a="_").sort().map(x=>/ *w+$/.exec(x)[0])


          Try it online!



          Similar approach to Chas Brown's Python answer, but using regular expressions instead.



          Explanation



          x => x.map( // 
          y => a = a.split( // Renders the indentation paths
          / */.exec(y)[0] // Checks the indentation level
          || a // If this is the top level, go to root
          )[0] + y, // Appends the child to the parent
          a = "_" // At first the cursor is at the root
          ) //
          .sort() // Sorts the indentation paths
          .map( //
          x => / *w+$/.exec(x)[0] // Extracts only the last level of the path
          ) //





          share|improve this answer





























            up vote
            0
            down vote














            K4, 51 bytes



            Solution:



            ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x


            Example:



            q)k),/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x("bdellium";" fox";" hound";" alien";"aisle";" wasabi";" elf";" alien";" horseradish";" xeno";"irk";"wren";"tsunami";"djinn";" zebra")
            "aisle"
            " horseradish"
            " xeno"
            " wasabi"
            " alien"
            " elf"
            "bdellium"
            " alien"
            " fox"
            " hound"
            "djinn"
            " zebra"
            "irk"
            "tsunami"
            "wren"


            Assumptions:



            a. That each hierarchy will start with the lowest level, i.e. you will not get:



            bdellium
            fox
            hound
            alien


            Explanation:



            ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x / the solution
            / lambda function, implicit x
            " "=/:x / " " equal to each right (/:) x
            +/' / sum up each
            s: / save as s
            &/ / find the minimum (ie highest level)
            s= / is s equal to the minimum?
            & / indices where true
            w: / save as w
            x@ / index into x at these indices
            < / return indices to sort ascending
            @ / index into
            ( ) / do this together
            w_x / cut x at indices w
            r: / save as r
            1_' / drop first from each r
            .z.s@ / apply recurse (.z.s)
            ,' / join each both
            ( ) / do this together
            1#'r / take first from each r
            ,/ / flatten





            share|improve this answer





























              up vote
              0
              down vote













              Perl 5, 166 bytes



              sub fmy$p=shift;my@r;while(@i)$i[0]=~/S/;$c=$-[0];if($p<$c)$r[-1].=$_ for f($c)elsif($p>$c)lastelsepush@r,shift@isort@rpush@i,$_ while<>;print sort@[f 0]


              Ungolfed (sort of):



              sub f 
              my $p = shift;
              my @r;
              while(@i)
              $i[0] =~ /S/;
              $c = $-[0];
              if($p < $c)
              $r[-1] .= $_ for f($c)
              elsif ($p > $c)
              last
              else
              push @r, shift @i


              sort @r


              push @i, $_ while <>;
              print sort@[f 0]


              It's a pretty straightforward recursive implementation. We check the indentation level by searching for the first non-space character (/S/) and getting its index ($-[0]). Unfortunately, we actually have to declare a handful of variables that are used in the recursion, or else they'll be implicitly global and the recursion won't work correctly.






              share|improve this answer




















                Your Answer




                StackExchange.ifUsing("editor", function ()
                return StackExchange.using("mathjaxEditing", function ()
                StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
                StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
                );
                );
                , "mathjax-editing");

                StackExchange.ifUsing("editor", function ()
                StackExchange.using("externalEditor", function ()
                StackExchange.using("snippets", function ()
                StackExchange.snippets.init();
                );
                );
                , "code-snippets");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "200"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                convertImagesToLinks: false,
                noModals: false,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: null,
                bindNavPrevention: true,
                postfix: "",
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                 

                draft saved


                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f171003%2findentation-based-sort%23new-answer', 'question_page');

                );

                Post as a guest






























                9 Answers
                9






                active

                oldest

                votes








                9 Answers
                9






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                1
                down vote



                accepted











                Pyth, 23 bytes



                jeMtSuaG+f</Td/HdeGHQ]Y


                Try it here!






                share|improve this answer


























                  up vote
                  1
                  down vote



                  accepted











                  Pyth, 23 bytes



                  jeMtSuaG+f</Td/HdeGHQ]Y


                  Try it here!






                  share|improve this answer
























                    up vote
                    1
                    down vote



                    accepted







                    up vote
                    1
                    down vote



                    accepted







                    Pyth, 23 bytes



                    jeMtSuaG+f</Td/HdeGHQ]Y


                    Try it here!






                    share|improve this answer















                    Pyth, 23 bytes



                    jeMtSuaG+f</Td/HdeGHQ]Y


                    Try it here!







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Aug 22 at 9:49

























                    answered Aug 22 at 9:40









                    Mr. Xcoder

                    30.2k757193




                    30.2k757193




















                        up vote
                        14
                        down vote














                        Python 2, 117 bytes





                        lambda S:[s[-1]for s in sorted(reduce(lambda t,s:t+[[v for v in t[-1]if v.count(' ')<s.count(' ')]+[s]],S,[]))[1:]]


                        Try it online!



                        Takes as input a list of strings; and outputs a list of strings, sorted as required.



                        The idea is to turn each element into a list which contains the "absolute path" as a list; and then let Python handle the sorting. E.g. if the input is:



                        [
                        'a',
                        ' c',
                        ' d',
                        ' b'
                        ]


                        Then via the reduce(), we convert to a list of lists:



                        [
                        ['a'],
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ['a',' b']
                        ]


                        which gets sorted as:



                        [
                        ['a'],
                        ['a',' b']
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ]


                        and then output the last element of each list in the list-of-lists to get:



                        [
                        'a',
                        ' b'
                        ' c',
                        ' d',
                        ]





                        share|improve this answer






















                        • Wow the solution I was about to post was 183 bytes...I suck lol
                          – Rushabh Mehta
                          Aug 22 at 0:18






                        • 4




                          @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
                          – Chas Brown
                          Aug 22 at 0:28














                        up vote
                        14
                        down vote














                        Python 2, 117 bytes





                        lambda S:[s[-1]for s in sorted(reduce(lambda t,s:t+[[v for v in t[-1]if v.count(' ')<s.count(' ')]+[s]],S,[]))[1:]]


                        Try it online!



                        Takes as input a list of strings; and outputs a list of strings, sorted as required.



                        The idea is to turn each element into a list which contains the "absolute path" as a list; and then let Python handle the sorting. E.g. if the input is:



                        [
                        'a',
                        ' c',
                        ' d',
                        ' b'
                        ]


                        Then via the reduce(), we convert to a list of lists:



                        [
                        ['a'],
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ['a',' b']
                        ]


                        which gets sorted as:



                        [
                        ['a'],
                        ['a',' b']
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ]


                        and then output the last element of each list in the list-of-lists to get:



                        [
                        'a',
                        ' b'
                        ' c',
                        ' d',
                        ]





                        share|improve this answer






















                        • Wow the solution I was about to post was 183 bytes...I suck lol
                          – Rushabh Mehta
                          Aug 22 at 0:18






                        • 4




                          @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
                          – Chas Brown
                          Aug 22 at 0:28












                        up vote
                        14
                        down vote










                        up vote
                        14
                        down vote










                        Python 2, 117 bytes





                        lambda S:[s[-1]for s in sorted(reduce(lambda t,s:t+[[v for v in t[-1]if v.count(' ')<s.count(' ')]+[s]],S,[]))[1:]]


                        Try it online!



                        Takes as input a list of strings; and outputs a list of strings, sorted as required.



                        The idea is to turn each element into a list which contains the "absolute path" as a list; and then let Python handle the sorting. E.g. if the input is:



                        [
                        'a',
                        ' c',
                        ' d',
                        ' b'
                        ]


                        Then via the reduce(), we convert to a list of lists:



                        [
                        ['a'],
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ['a',' b']
                        ]


                        which gets sorted as:



                        [
                        ['a'],
                        ['a',' b']
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ]


                        and then output the last element of each list in the list-of-lists to get:



                        [
                        'a',
                        ' b'
                        ' c',
                        ' d',
                        ]





                        share|improve this answer















                        Python 2, 117 bytes





                        lambda S:[s[-1]for s in sorted(reduce(lambda t,s:t+[[v for v in t[-1]if v.count(' ')<s.count(' ')]+[s]],S,[]))[1:]]


                        Try it online!



                        Takes as input a list of strings; and outputs a list of strings, sorted as required.



                        The idea is to turn each element into a list which contains the "absolute path" as a list; and then let Python handle the sorting. E.g. if the input is:



                        [
                        'a',
                        ' c',
                        ' d',
                        ' b'
                        ]


                        Then via the reduce(), we convert to a list of lists:



                        [
                        ['a'],
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ['a',' b']
                        ]


                        which gets sorted as:



                        [
                        ['a'],
                        ['a',' b']
                        ['a',' c'],
                        ['a',' c', ' d'],
                        ]


                        and then output the last element of each list in the list-of-lists to get:



                        [
                        'a',
                        ' b'
                        ' c',
                        ' d',
                        ]






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Aug 22 at 0:38

























                        answered Aug 21 at 23:52









                        Chas Brown

                        4,1361319




                        4,1361319











                        • Wow the solution I was about to post was 183 bytes...I suck lol
                          – Rushabh Mehta
                          Aug 22 at 0:18






                        • 4




                          @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
                          – Chas Brown
                          Aug 22 at 0:28
















                        • Wow the solution I was about to post was 183 bytes...I suck lol
                          – Rushabh Mehta
                          Aug 22 at 0:18






                        • 4




                          @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
                          – Chas Brown
                          Aug 22 at 0:28















                        Wow the solution I was about to post was 183 bytes...I suck lol
                        – Rushabh Mehta
                        Aug 22 at 0:18




                        Wow the solution I was about to post was 183 bytes...I suck lol
                        – Rushabh Mehta
                        Aug 22 at 0:18




                        4




                        4




                        @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
                        – Chas Brown
                        Aug 22 at 0:28




                        @Rushabh Mehta: My first try was around 205 bytes... then hack away! :)
                        – Chas Brown
                        Aug 22 at 0:28










                        up vote
                        7
                        down vote














                        APL (Dyalog Unicode), 31 bytesSBCS





                        Anonymous prefix lambda, takes and returns list of strings.



                        ⍵[⍋1=≢⍵:⍺⋄⍵⍀↑' '(,⊂⍨⊣=,)¨⍵]


                        Try it online!



                        … "dfn"; ⍵ is argument



                         ⍵[…] index the argument with the following indices:



                          ' '(…)¨⍵ apply the following tacit function to each string with space as left argument:



                           , concatenate the space to the string



                           ⊣= Boolean list indicating where the space is equal to each character that



                           ,⊂⍨ use that to partition (begin part where true) the concatenation of space and string



                          ↑ mix list of lists of strings into matrix of strings



                          …⍀ vertical cumulative reduction by this "dfn"; ⍺ and ⍵ are upper and lower args:



                           ≢⍵ the length of the lower string



                           1= is that equal to 1? (i.e. is there nothing but the single space there?)



                           :⍺ if so, return the upper argument



                           ⋄⍵ else, return the lower argument



                          ⍋ grade up (find indices which will sort that)






                        share|improve this answer


























                          up vote
                          7
                          down vote














                          APL (Dyalog Unicode), 31 bytesSBCS





                          Anonymous prefix lambda, takes and returns list of strings.



                          ⍵[⍋1=≢⍵:⍺⋄⍵⍀↑' '(,⊂⍨⊣=,)¨⍵]


                          Try it online!



                          … "dfn"; ⍵ is argument



                           ⍵[…] index the argument with the following indices:



                            ' '(…)¨⍵ apply the following tacit function to each string with space as left argument:



                             , concatenate the space to the string



                             ⊣= Boolean list indicating where the space is equal to each character that



                             ,⊂⍨ use that to partition (begin part where true) the concatenation of space and string



                            ↑ mix list of lists of strings into matrix of strings



                            …⍀ vertical cumulative reduction by this "dfn"; ⍺ and ⍵ are upper and lower args:



                             ≢⍵ the length of the lower string



                             1= is that equal to 1? (i.e. is there nothing but the single space there?)



                             :⍺ if so, return the upper argument



                             ⋄⍵ else, return the lower argument



                            ⍋ grade up (find indices which will sort that)






                          share|improve this answer
























                            up vote
                            7
                            down vote










                            up vote
                            7
                            down vote










                            APL (Dyalog Unicode), 31 bytesSBCS





                            Anonymous prefix lambda, takes and returns list of strings.



                            ⍵[⍋1=≢⍵:⍺⋄⍵⍀↑' '(,⊂⍨⊣=,)¨⍵]


                            Try it online!



                            … "dfn"; ⍵ is argument



                             ⍵[…] index the argument with the following indices:



                              ' '(…)¨⍵ apply the following tacit function to each string with space as left argument:



                               , concatenate the space to the string



                               ⊣= Boolean list indicating where the space is equal to each character that



                               ,⊂⍨ use that to partition (begin part where true) the concatenation of space and string



                              ↑ mix list of lists of strings into matrix of strings



                              …⍀ vertical cumulative reduction by this "dfn"; ⍺ and ⍵ are upper and lower args:



                               ≢⍵ the length of the lower string



                               1= is that equal to 1? (i.e. is there nothing but the single space there?)



                               :⍺ if so, return the upper argument



                               ⋄⍵ else, return the lower argument



                              ⍋ grade up (find indices which will sort that)






                            share|improve this answer















                            APL (Dyalog Unicode), 31 bytesSBCS





                            Anonymous prefix lambda, takes and returns list of strings.



                            ⍵[⍋1=≢⍵:⍺⋄⍵⍀↑' '(,⊂⍨⊣=,)¨⍵]


                            Try it online!



                            … "dfn"; ⍵ is argument



                             ⍵[…] index the argument with the following indices:



                              ' '(…)¨⍵ apply the following tacit function to each string with space as left argument:



                               , concatenate the space to the string



                               ⊣= Boolean list indicating where the space is equal to each character that



                               ,⊂⍨ use that to partition (begin part where true) the concatenation of space and string



                              ↑ mix list of lists of strings into matrix of strings



                              …⍀ vertical cumulative reduction by this "dfn"; ⍺ and ⍵ are upper and lower args:



                               ≢⍵ the length of the lower string



                               1= is that equal to 1? (i.e. is there nothing but the single space there?)



                               :⍺ if so, return the upper argument



                               ⋄⍵ else, return the lower argument



                              ⍋ grade up (find indices which will sort that)







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Aug 21 at 23:46

























                            answered Aug 21 at 23:33









                            Adám

                            27.7k268185




                            27.7k268185




















                                up vote
                                7
                                down vote














                                Retina, 47 bytes



                                +-1m`(?<=^2(S+).*?¶( *)) 
                                $1
                                O$`
                                $L$&
                                S+



                                Try it online! Note: Several lines have trailing spaces. Explanation:



                                +-1m`(?<=^2(S+).*?¶( *)) 
                                $1


                                The first step is to insert each word into following lines at the same indentation. For example, with the lines aisle, wasabi and elf the resulting lines are aisle, aisle wasabi and aisle wasabi elf. I discovered this regex by trial and error so there may be edge cases with it.



                                O$`
                                $L$&


                                We can now sort the lines case-insensitively.



                                S+ 



                                Delete all of the inserted words.






                                share|improve this answer
























                                  up vote
                                  7
                                  down vote














                                  Retina, 47 bytes



                                  +-1m`(?<=^2(S+).*?¶( *)) 
                                  $1
                                  O$`
                                  $L$&
                                  S+



                                  Try it online! Note: Several lines have trailing spaces. Explanation:



                                  +-1m`(?<=^2(S+).*?¶( *)) 
                                  $1


                                  The first step is to insert each word into following lines at the same indentation. For example, with the lines aisle, wasabi and elf the resulting lines are aisle, aisle wasabi and aisle wasabi elf. I discovered this regex by trial and error so there may be edge cases with it.



                                  O$`
                                  $L$&


                                  We can now sort the lines case-insensitively.



                                  S+ 



                                  Delete all of the inserted words.






                                  share|improve this answer






















                                    up vote
                                    7
                                    down vote










                                    up vote
                                    7
                                    down vote










                                    Retina, 47 bytes



                                    +-1m`(?<=^2(S+).*?¶( *)) 
                                    $1
                                    O$`
                                    $L$&
                                    S+



                                    Try it online! Note: Several lines have trailing spaces. Explanation:



                                    +-1m`(?<=^2(S+).*?¶( *)) 
                                    $1


                                    The first step is to insert each word into following lines at the same indentation. For example, with the lines aisle, wasabi and elf the resulting lines are aisle, aisle wasabi and aisle wasabi elf. I discovered this regex by trial and error so there may be edge cases with it.



                                    O$`
                                    $L$&


                                    We can now sort the lines case-insensitively.



                                    S+ 



                                    Delete all of the inserted words.






                                    share|improve this answer













                                    Retina, 47 bytes



                                    +-1m`(?<=^2(S+).*?¶( *)) 
                                    $1
                                    O$`
                                    $L$&
                                    S+



                                    Try it online! Note: Several lines have trailing spaces. Explanation:



                                    +-1m`(?<=^2(S+).*?¶( *)) 
                                    $1


                                    The first step is to insert each word into following lines at the same indentation. For example, with the lines aisle, wasabi and elf the resulting lines are aisle, aisle wasabi and aisle wasabi elf. I discovered this regex by trial and error so there may be edge cases with it.



                                    O$`
                                    $L$&


                                    We can now sort the lines case-insensitively.



                                    S+ 



                                    Delete all of the inserted words.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Aug 22 at 0:47









                                    Neil

                                    74.9k744170




                                    74.9k744170




















                                        up vote
                                        4
                                        down vote














                                        Perl 6, 120 83 81 63 54 37 47 42 bytes



                                        -5 bytes thanks to nwellnhof





                                        my@a;.sort:@a[+.comb(' ')..*+1]=$_;~@a


                                        Try it online!



                                        This uses Chas Brown's method. An anonymous code block that takes a list of lines and returns a list of lines.



                                        Explanation:



                                         # Anonymous code block
                                        my@a; # Declare a local list
                                        .sort # Sort the given list of lines
                                        : # By converting each line to:
                                        @a[+.comb(' ')..*+1]=$_; # Set the element at that indentation level onwards to that line
                                        ~@a # And return the list coerced to a string





                                        share|improve this answer






















                                        • @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
                                          – Jo King
                                          Aug 22 at 9:57










                                        • @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
                                          – Jo King
                                          Aug 22 at 11:01










                                        • Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
                                          – nwellnhof
                                          Aug 22 at 12:02














                                        up vote
                                        4
                                        down vote














                                        Perl 6, 120 83 81 63 54 37 47 42 bytes



                                        -5 bytes thanks to nwellnhof





                                        my@a;.sort:@a[+.comb(' ')..*+1]=$_;~@a


                                        Try it online!



                                        This uses Chas Brown's method. An anonymous code block that takes a list of lines and returns a list of lines.



                                        Explanation:



                                         # Anonymous code block
                                        my@a; # Declare a local list
                                        .sort # Sort the given list of lines
                                        : # By converting each line to:
                                        @a[+.comb(' ')..*+1]=$_; # Set the element at that indentation level onwards to that line
                                        ~@a # And return the list coerced to a string





                                        share|improve this answer






















                                        • @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
                                          – Jo King
                                          Aug 22 at 9:57










                                        • @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
                                          – Jo King
                                          Aug 22 at 11:01










                                        • Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
                                          – nwellnhof
                                          Aug 22 at 12:02












                                        up vote
                                        4
                                        down vote










                                        up vote
                                        4
                                        down vote










                                        Perl 6, 120 83 81 63 54 37 47 42 bytes



                                        -5 bytes thanks to nwellnhof





                                        my@a;.sort:@a[+.comb(' ')..*+1]=$_;~@a


                                        Try it online!



                                        This uses Chas Brown's method. An anonymous code block that takes a list of lines and returns a list of lines.



                                        Explanation:



                                         # Anonymous code block
                                        my@a; # Declare a local list
                                        .sort # Sort the given list of lines
                                        : # By converting each line to:
                                        @a[+.comb(' ')..*+1]=$_; # Set the element at that indentation level onwards to that line
                                        ~@a # And return the list coerced to a string





                                        share|improve this answer















                                        Perl 6, 120 83 81 63 54 37 47 42 bytes



                                        -5 bytes thanks to nwellnhof





                                        my@a;.sort:@a[+.comb(' ')..*+1]=$_;~@a


                                        Try it online!



                                        This uses Chas Brown's method. An anonymous code block that takes a list of lines and returns a list of lines.



                                        Explanation:



                                         # Anonymous code block
                                        my@a; # Declare a local list
                                        .sort # Sort the given list of lines
                                        : # By converting each line to:
                                        @a[+.comb(' ')..*+1]=$_; # Set the element at that indentation level onwards to that line
                                        ~@a # And return the list coerced to a string






                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Aug 22 at 10:59

























                                        answered Aug 21 at 23:46









                                        Jo King

                                        14.9k24084




                                        14.9k24084











                                        • @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
                                          – Jo King
                                          Aug 22 at 9:57










                                        • @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
                                          – Jo King
                                          Aug 22 at 11:01










                                        • Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
                                          – nwellnhof
                                          Aug 22 at 12:02
















                                        • @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
                                          – Jo King
                                          Aug 22 at 9:57










                                        • @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
                                          – Jo King
                                          Aug 22 at 11:01










                                        • Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
                                          – nwellnhof
                                          Aug 22 at 12:02















                                        @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
                                        – Jo King
                                        Aug 22 at 9:57




                                        @nwellnhof Thanks for pointing that out. I think I've fixed it in the latest version
                                        – Jo King
                                        Aug 22 at 9:57












                                        @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
                                        – Jo King
                                        Aug 22 at 11:01




                                        @nwellnhof Ah well, it was shorter in a previous iteration. Thanks for the bytes off, but I had to change it slightly
                                        – Jo King
                                        Aug 22 at 11:01












                                        Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
                                        – nwellnhof
                                        Aug 22 at 12:02




                                        Oh, right. Actually, something like my@a;.sort:@a[+.comb(' ')...*>@a]=$_;~@a is required to support higher indentation levels.
                                        – nwellnhof
                                        Aug 22 at 12:02










                                        up vote
                                        3
                                        down vote














                                        Clean, 112 101 bytes



                                        import StdEnv
                                        f=flatten
                                        ?e=[0\' '<-e]
                                        $[h:t]#(a,b)=span(u= ?u> ?h)t
                                        =sort[[h:f($a)]: $b]
                                        $e=




                                        f o$


                                        Try it online!



                                        Anonymous function :: [[Char]] -> [[Char]] which wraps $ :: [[Char]] -> [[[Char]]] into the right output format. $ groups the strings into "more spaces than" and "everything else afterwards", recurses over each group and sorts when they're adjoined. At each step, the list being sorted looks like:



                                        [[head-of-group-1,child-1,child-2..],[head-of-group-2,child-1,child-2..]..]



                                        Clean, 127 bytes



                                        import StdEnv
                                        $l=[x++y\z<- ?(map(span((>)'!'))l),(x,y)<-z]
                                        ?[h:t]#(a,b)=span((u,_)=u>fst h)t
                                        =sort[[h:flatten(?a)]: ?b]
                                        ?e=


                                        Try it online!



                                        Defines the function $ :: [[Char]] -> [[Char]] which separates the strings into tuples in the form (spaces, letters) which are recursively sorted by the helper function ? :: [([Char],[Char])] -> [[([Char],[Char])]].



                                        Explained:



                                        $ list // the function $ of the list
                                        = [ // is
                                        spaces ++ letters // the spaces joined with the letters
                                        \ sublist <- ? ( // from each sublist in the application of ? to
                                        map ( // the application of
                                        span ((>)'!') // a function separating spaces and letters
                                        ) list // to every element in the list
                                        )
                                        , (spaces, letters) <- sublist // the spaces and letters from the sublist
                                        ]

                                        ? [head: tail] // in the function ? of the head and tail of the input
                                        # (group, others) // let the current group and the others equal
                                        = span ( // the result of separating until ... is false
                                        (u, _) = u > // only elements where there are more spaces
                                        fst head // than in the head of the input
                                        ) tail // the tail of the input
                                        = sort [
                                        [head // prepend the head of the input to
                                        : flatten (?group) // the flat application of ? to the first group
                                        ] // and prepend this to
                                        : ?others // the application of ? to the other group(s)
                                        ]

                                        ? empty = // match the empty list





                                        share|improve this answer


























                                          up vote
                                          3
                                          down vote














                                          Clean, 112 101 bytes



                                          import StdEnv
                                          f=flatten
                                          ?e=[0\' '<-e]
                                          $[h:t]#(a,b)=span(u= ?u> ?h)t
                                          =sort[[h:f($a)]: $b]
                                          $e=




                                          f o$


                                          Try it online!



                                          Anonymous function :: [[Char]] -> [[Char]] which wraps $ :: [[Char]] -> [[[Char]]] into the right output format. $ groups the strings into "more spaces than" and "everything else afterwards", recurses over each group and sorts when they're adjoined. At each step, the list being sorted looks like:



                                          [[head-of-group-1,child-1,child-2..],[head-of-group-2,child-1,child-2..]..]



                                          Clean, 127 bytes



                                          import StdEnv
                                          $l=[x++y\z<- ?(map(span((>)'!'))l),(x,y)<-z]
                                          ?[h:t]#(a,b)=span((u,_)=u>fst h)t
                                          =sort[[h:flatten(?a)]: ?b]
                                          ?e=


                                          Try it online!



                                          Defines the function $ :: [[Char]] -> [[Char]] which separates the strings into tuples in the form (spaces, letters) which are recursively sorted by the helper function ? :: [([Char],[Char])] -> [[([Char],[Char])]].



                                          Explained:



                                          $ list // the function $ of the list
                                          = [ // is
                                          spaces ++ letters // the spaces joined with the letters
                                          \ sublist <- ? ( // from each sublist in the application of ? to
                                          map ( // the application of
                                          span ((>)'!') // a function separating spaces and letters
                                          ) list // to every element in the list
                                          )
                                          , (spaces, letters) <- sublist // the spaces and letters from the sublist
                                          ]

                                          ? [head: tail] // in the function ? of the head and tail of the input
                                          # (group, others) // let the current group and the others equal
                                          = span ( // the result of separating until ... is false
                                          (u, _) = u > // only elements where there are more spaces
                                          fst head // than in the head of the input
                                          ) tail // the tail of the input
                                          = sort [
                                          [head // prepend the head of the input to
                                          : flatten (?group) // the flat application of ? to the first group
                                          ] // and prepend this to
                                          : ?others // the application of ? to the other group(s)
                                          ]

                                          ? empty = // match the empty list





                                          share|improve this answer
























                                            up vote
                                            3
                                            down vote










                                            up vote
                                            3
                                            down vote










                                            Clean, 112 101 bytes



                                            import StdEnv
                                            f=flatten
                                            ?e=[0\' '<-e]
                                            $[h:t]#(a,b)=span(u= ?u> ?h)t
                                            =sort[[h:f($a)]: $b]
                                            $e=




                                            f o$


                                            Try it online!



                                            Anonymous function :: [[Char]] -> [[Char]] which wraps $ :: [[Char]] -> [[[Char]]] into the right output format. $ groups the strings into "more spaces than" and "everything else afterwards", recurses over each group and sorts when they're adjoined. At each step, the list being sorted looks like:



                                            [[head-of-group-1,child-1,child-2..],[head-of-group-2,child-1,child-2..]..]



                                            Clean, 127 bytes



                                            import StdEnv
                                            $l=[x++y\z<- ?(map(span((>)'!'))l),(x,y)<-z]
                                            ?[h:t]#(a,b)=span((u,_)=u>fst h)t
                                            =sort[[h:flatten(?a)]: ?b]
                                            ?e=


                                            Try it online!



                                            Defines the function $ :: [[Char]] -> [[Char]] which separates the strings into tuples in the form (spaces, letters) which are recursively sorted by the helper function ? :: [([Char],[Char])] -> [[([Char],[Char])]].



                                            Explained:



                                            $ list // the function $ of the list
                                            = [ // is
                                            spaces ++ letters // the spaces joined with the letters
                                            \ sublist <- ? ( // from each sublist in the application of ? to
                                            map ( // the application of
                                            span ((>)'!') // a function separating spaces and letters
                                            ) list // to every element in the list
                                            )
                                            , (spaces, letters) <- sublist // the spaces and letters from the sublist
                                            ]

                                            ? [head: tail] // in the function ? of the head and tail of the input
                                            # (group, others) // let the current group and the others equal
                                            = span ( // the result of separating until ... is false
                                            (u, _) = u > // only elements where there are more spaces
                                            fst head // than in the head of the input
                                            ) tail // the tail of the input
                                            = sort [
                                            [head // prepend the head of the input to
                                            : flatten (?group) // the flat application of ? to the first group
                                            ] // and prepend this to
                                            : ?others // the application of ? to the other group(s)
                                            ]

                                            ? empty = // match the empty list





                                            share|improve this answer















                                            Clean, 112 101 bytes



                                            import StdEnv
                                            f=flatten
                                            ?e=[0\' '<-e]
                                            $[h:t]#(a,b)=span(u= ?u> ?h)t
                                            =sort[[h:f($a)]: $b]
                                            $e=




                                            f o$


                                            Try it online!



                                            Anonymous function :: [[Char]] -> [[Char]] which wraps $ :: [[Char]] -> [[[Char]]] into the right output format. $ groups the strings into "more spaces than" and "everything else afterwards", recurses over each group and sorts when they're adjoined. At each step, the list being sorted looks like:



                                            [[head-of-group-1,child-1,child-2..],[head-of-group-2,child-1,child-2..]..]



                                            Clean, 127 bytes



                                            import StdEnv
                                            $l=[x++y\z<- ?(map(span((>)'!'))l),(x,y)<-z]
                                            ?[h:t]#(a,b)=span((u,_)=u>fst h)t
                                            =sort[[h:flatten(?a)]: ?b]
                                            ?e=


                                            Try it online!



                                            Defines the function $ :: [[Char]] -> [[Char]] which separates the strings into tuples in the form (spaces, letters) which are recursively sorted by the helper function ? :: [([Char],[Char])] -> [[([Char],[Char])]].



                                            Explained:



                                            $ list // the function $ of the list
                                            = [ // is
                                            spaces ++ letters // the spaces joined with the letters
                                            \ sublist <- ? ( // from each sublist in the application of ? to
                                            map ( // the application of
                                            span ((>)'!') // a function separating spaces and letters
                                            ) list // to every element in the list
                                            )
                                            , (spaces, letters) <- sublist // the spaces and letters from the sublist
                                            ]

                                            ? [head: tail] // in the function ? of the head and tail of the input
                                            # (group, others) // let the current group and the others equal
                                            = span ( // the result of separating until ... is false
                                            (u, _) = u > // only elements where there are more spaces
                                            fst head // than in the head of the input
                                            ) tail // the tail of the input
                                            = sort [
                                            [head // prepend the head of the input to
                                            : flatten (?group) // the flat application of ? to the first group
                                            ] // and prepend this to
                                            : ?others // the application of ? to the other group(s)
                                            ]

                                            ? empty = // match the empty list






                                            share|improve this answer














                                            share|improve this answer



                                            share|improve this answer








                                            edited Aug 22 at 1:26

























                                            answered Aug 21 at 23:51









                                            Οurous

                                            5,1631931




                                            5,1631931




















                                                up vote
                                                1
                                                down vote














                                                JavaScript (Node.js), 114 100 92 88 bytes





                                                x=>x.map(y=>a=a.split(/ */.exec(y)[0]||a)[0]+y,a="_").sort().map(x=>/ *w+$/.exec(x)[0])


                                                Try it online!



                                                Similar approach to Chas Brown's Python answer, but using regular expressions instead.



                                                Explanation



                                                x => x.map( // 
                                                y => a = a.split( // Renders the indentation paths
                                                / */.exec(y)[0] // Checks the indentation level
                                                || a // If this is the top level, go to root
                                                )[0] + y, // Appends the child to the parent
                                                a = "_" // At first the cursor is at the root
                                                ) //
                                                .sort() // Sorts the indentation paths
                                                .map( //
                                                x => / *w+$/.exec(x)[0] // Extracts only the last level of the path
                                                ) //





                                                share|improve this answer


























                                                  up vote
                                                  1
                                                  down vote














                                                  JavaScript (Node.js), 114 100 92 88 bytes





                                                  x=>x.map(y=>a=a.split(/ */.exec(y)[0]||a)[0]+y,a="_").sort().map(x=>/ *w+$/.exec(x)[0])


                                                  Try it online!



                                                  Similar approach to Chas Brown's Python answer, but using regular expressions instead.



                                                  Explanation



                                                  x => x.map( // 
                                                  y => a = a.split( // Renders the indentation paths
                                                  / */.exec(y)[0] // Checks the indentation level
                                                  || a // If this is the top level, go to root
                                                  )[0] + y, // Appends the child to the parent
                                                  a = "_" // At first the cursor is at the root
                                                  ) //
                                                  .sort() // Sorts the indentation paths
                                                  .map( //
                                                  x => / *w+$/.exec(x)[0] // Extracts only the last level of the path
                                                  ) //





                                                  share|improve this answer
























                                                    up vote
                                                    1
                                                    down vote










                                                    up vote
                                                    1
                                                    down vote










                                                    JavaScript (Node.js), 114 100 92 88 bytes





                                                    x=>x.map(y=>a=a.split(/ */.exec(y)[0]||a)[0]+y,a="_").sort().map(x=>/ *w+$/.exec(x)[0])


                                                    Try it online!



                                                    Similar approach to Chas Brown's Python answer, but using regular expressions instead.



                                                    Explanation



                                                    x => x.map( // 
                                                    y => a = a.split( // Renders the indentation paths
                                                    / */.exec(y)[0] // Checks the indentation level
                                                    || a // If this is the top level, go to root
                                                    )[0] + y, // Appends the child to the parent
                                                    a = "_" // At first the cursor is at the root
                                                    ) //
                                                    .sort() // Sorts the indentation paths
                                                    .map( //
                                                    x => / *w+$/.exec(x)[0] // Extracts only the last level of the path
                                                    ) //





                                                    share|improve this answer















                                                    JavaScript (Node.js), 114 100 92 88 bytes





                                                    x=>x.map(y=>a=a.split(/ */.exec(y)[0]||a)[0]+y,a="_").sort().map(x=>/ *w+$/.exec(x)[0])


                                                    Try it online!



                                                    Similar approach to Chas Brown's Python answer, but using regular expressions instead.



                                                    Explanation



                                                    x => x.map( // 
                                                    y => a = a.split( // Renders the indentation paths
                                                    / */.exec(y)[0] // Checks the indentation level
                                                    || a // If this is the top level, go to root
                                                    )[0] + y, // Appends the child to the parent
                                                    a = "_" // At first the cursor is at the root
                                                    ) //
                                                    .sort() // Sorts the indentation paths
                                                    .map( //
                                                    x => / *w+$/.exec(x)[0] // Extracts only the last level of the path
                                                    ) //






                                                    share|improve this answer














                                                    share|improve this answer



                                                    share|improve this answer








                                                    edited Aug 22 at 10:27

























                                                    answered Aug 22 at 3:28









                                                    user71546

                                                    1,31529




                                                    1,31529




















                                                        up vote
                                                        0
                                                        down vote














                                                        K4, 51 bytes



                                                        Solution:



                                                        ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x


                                                        Example:



                                                        q)k),/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x("bdellium";" fox";" hound";" alien";"aisle";" wasabi";" elf";" alien";" horseradish";" xeno";"irk";"wren";"tsunami";"djinn";" zebra")
                                                        "aisle"
                                                        " horseradish"
                                                        " xeno"
                                                        " wasabi"
                                                        " alien"
                                                        " elf"
                                                        "bdellium"
                                                        " alien"
                                                        " fox"
                                                        " hound"
                                                        "djinn"
                                                        " zebra"
                                                        "irk"
                                                        "tsunami"
                                                        "wren"


                                                        Assumptions:



                                                        a. That each hierarchy will start with the lowest level, i.e. you will not get:



                                                        bdellium
                                                        fox
                                                        hound
                                                        alien


                                                        Explanation:



                                                        ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x / the solution
                                                        / lambda function, implicit x
                                                        " "=/:x / " " equal to each right (/:) x
                                                        +/' / sum up each
                                                        s: / save as s
                                                        &/ / find the minimum (ie highest level)
                                                        s= / is s equal to the minimum?
                                                        & / indices where true
                                                        w: / save as w
                                                        x@ / index into x at these indices
                                                        < / return indices to sort ascending
                                                        @ / index into
                                                        ( ) / do this together
                                                        w_x / cut x at indices w
                                                        r: / save as r
                                                        1_' / drop first from each r
                                                        .z.s@ / apply recurse (.z.s)
                                                        ,' / join each both
                                                        ( ) / do this together
                                                        1#'r / take first from each r
                                                        ,/ / flatten





                                                        share|improve this answer


























                                                          up vote
                                                          0
                                                          down vote














                                                          K4, 51 bytes



                                                          Solution:



                                                          ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x


                                                          Example:



                                                          q)k),/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x("bdellium";" fox";" hound";" alien";"aisle";" wasabi";" elf";" alien";" horseradish";" xeno";"irk";"wren";"tsunami";"djinn";" zebra")
                                                          "aisle"
                                                          " horseradish"
                                                          " xeno"
                                                          " wasabi"
                                                          " alien"
                                                          " elf"
                                                          "bdellium"
                                                          " alien"
                                                          " fox"
                                                          " hound"
                                                          "djinn"
                                                          " zebra"
                                                          "irk"
                                                          "tsunami"
                                                          "wren"


                                                          Assumptions:



                                                          a. That each hierarchy will start with the lowest level, i.e. you will not get:



                                                          bdellium
                                                          fox
                                                          hound
                                                          alien


                                                          Explanation:



                                                          ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x / the solution
                                                          / lambda function, implicit x
                                                          " "=/:x / " " equal to each right (/:) x
                                                          +/' / sum up each
                                                          s: / save as s
                                                          &/ / find the minimum (ie highest level)
                                                          s= / is s equal to the minimum?
                                                          & / indices where true
                                                          w: / save as w
                                                          x@ / index into x at these indices
                                                          < / return indices to sort ascending
                                                          @ / index into
                                                          ( ) / do this together
                                                          w_x / cut x at indices w
                                                          r: / save as r
                                                          1_' / drop first from each r
                                                          .z.s@ / apply recurse (.z.s)
                                                          ,' / join each both
                                                          ( ) / do this together
                                                          1#'r / take first from each r
                                                          ,/ / flatten





                                                          share|improve this answer
























                                                            up vote
                                                            0
                                                            down vote










                                                            up vote
                                                            0
                                                            down vote










                                                            K4, 51 bytes



                                                            Solution:



                                                            ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x


                                                            Example:



                                                            q)k),/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x("bdellium";" fox";" hound";" alien";"aisle";" wasabi";" elf";" alien";" horseradish";" xeno";"irk";"wren";"tsunami";"djinn";" zebra")
                                                            "aisle"
                                                            " horseradish"
                                                            " xeno"
                                                            " wasabi"
                                                            " alien"
                                                            " elf"
                                                            "bdellium"
                                                            " alien"
                                                            " fox"
                                                            " hound"
                                                            "djinn"
                                                            " zebra"
                                                            "irk"
                                                            "tsunami"
                                                            "wren"


                                                            Assumptions:



                                                            a. That each hierarchy will start with the lowest level, i.e. you will not get:



                                                            bdellium
                                                            fox
                                                            hound
                                                            alien


                                                            Explanation:



                                                            ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x / the solution
                                                            / lambda function, implicit x
                                                            " "=/:x / " " equal to each right (/:) x
                                                            +/' / sum up each
                                                            s: / save as s
                                                            &/ / find the minimum (ie highest level)
                                                            s= / is s equal to the minimum?
                                                            & / indices where true
                                                            w: / save as w
                                                            x@ / index into x at these indices
                                                            < / return indices to sort ascending
                                                            @ / index into
                                                            ( ) / do this together
                                                            w_x / cut x at indices w
                                                            r: / save as r
                                                            1_' / drop first from each r
                                                            .z.s@ / apply recurse (.z.s)
                                                            ,' / join each both
                                                            ( ) / do this together
                                                            1#'r / take first from each r
                                                            ,/ / flatten





                                                            share|improve this answer















                                                            K4, 51 bytes



                                                            Solution:



                                                            ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x


                                                            Example:



                                                            q)k),/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x("bdellium";" fox";" hound";" alien";"aisle";" wasabi";" elf";" alien";" horseradish";" xeno";"irk";"wren";"tsunami";"djinn";" zebra")
                                                            "aisle"
                                                            " horseradish"
                                                            " xeno"
                                                            " wasabi"
                                                            " alien"
                                                            " elf"
                                                            "bdellium"
                                                            " alien"
                                                            " fox"
                                                            " hound"
                                                            "djinn"
                                                            " zebra"
                                                            "irk"
                                                            "tsunami"
                                                            "wren"


                                                            Assumptions:



                                                            a. That each hierarchy will start with the lowest level, i.e. you will not get:



                                                            bdellium
                                                            fox
                                                            hound
                                                            alien


                                                            Explanation:



                                                            ,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x / the solution
                                                            / lambda function, implicit x
                                                            " "=/:x / " " equal to each right (/:) x
                                                            +/' / sum up each
                                                            s: / save as s
                                                            &/ / find the minimum (ie highest level)
                                                            s= / is s equal to the minimum?
                                                            & / indices where true
                                                            w: / save as w
                                                            x@ / index into x at these indices
                                                            < / return indices to sort ascending
                                                            @ / index into
                                                            ( ) / do this together
                                                            w_x / cut x at indices w
                                                            r: / save as r
                                                            1_' / drop first from each r
                                                            .z.s@ / apply recurse (.z.s)
                                                            ,' / join each both
                                                            ( ) / do this together
                                                            1#'r / take first from each r
                                                            ,/ / flatten






                                                            share|improve this answer














                                                            share|improve this answer



                                                            share|improve this answer








                                                            edited Aug 22 at 21:13

























                                                            answered Aug 22 at 20:45









                                                            streetster

                                                            2,074515




                                                            2,074515




















                                                                up vote
                                                                0
                                                                down vote













                                                                Perl 5, 166 bytes



                                                                sub fmy$p=shift;my@r;while(@i)$i[0]=~/S/;$c=$-[0];if($p<$c)$r[-1].=$_ for f($c)elsif($p>$c)lastelsepush@r,shift@isort@rpush@i,$_ while<>;print sort@[f 0]


                                                                Ungolfed (sort of):



                                                                sub f 
                                                                my $p = shift;
                                                                my @r;
                                                                while(@i)
                                                                $i[0] =~ /S/;
                                                                $c = $-[0];
                                                                if($p < $c)
                                                                $r[-1] .= $_ for f($c)
                                                                elsif ($p > $c)
                                                                last
                                                                else
                                                                push @r, shift @i


                                                                sort @r


                                                                push @i, $_ while <>;
                                                                print sort@[f 0]


                                                                It's a pretty straightforward recursive implementation. We check the indentation level by searching for the first non-space character (/S/) and getting its index ($-[0]). Unfortunately, we actually have to declare a handful of variables that are used in the recursion, or else they'll be implicitly global and the recursion won't work correctly.






                                                                share|improve this answer
























                                                                  up vote
                                                                  0
                                                                  down vote













                                                                  Perl 5, 166 bytes



                                                                  sub fmy$p=shift;my@r;while(@i)$i[0]=~/S/;$c=$-[0];if($p<$c)$r[-1].=$_ for f($c)elsif($p>$c)lastelsepush@r,shift@isort@rpush@i,$_ while<>;print sort@[f 0]


                                                                  Ungolfed (sort of):



                                                                  sub f 
                                                                  my $p = shift;
                                                                  my @r;
                                                                  while(@i)
                                                                  $i[0] =~ /S/;
                                                                  $c = $-[0];
                                                                  if($p < $c)
                                                                  $r[-1] .= $_ for f($c)
                                                                  elsif ($p > $c)
                                                                  last
                                                                  else
                                                                  push @r, shift @i


                                                                  sort @r


                                                                  push @i, $_ while <>;
                                                                  print sort@[f 0]


                                                                  It's a pretty straightforward recursive implementation. We check the indentation level by searching for the first non-space character (/S/) and getting its index ($-[0]). Unfortunately, we actually have to declare a handful of variables that are used in the recursion, or else they'll be implicitly global and the recursion won't work correctly.






                                                                  share|improve this answer






















                                                                    up vote
                                                                    0
                                                                    down vote










                                                                    up vote
                                                                    0
                                                                    down vote









                                                                    Perl 5, 166 bytes



                                                                    sub fmy$p=shift;my@r;while(@i)$i[0]=~/S/;$c=$-[0];if($p<$c)$r[-1].=$_ for f($c)elsif($p>$c)lastelsepush@r,shift@isort@rpush@i,$_ while<>;print sort@[f 0]


                                                                    Ungolfed (sort of):



                                                                    sub f 
                                                                    my $p = shift;
                                                                    my @r;
                                                                    while(@i)
                                                                    $i[0] =~ /S/;
                                                                    $c = $-[0];
                                                                    if($p < $c)
                                                                    $r[-1] .= $_ for f($c)
                                                                    elsif ($p > $c)
                                                                    last
                                                                    else
                                                                    push @r, shift @i


                                                                    sort @r


                                                                    push @i, $_ while <>;
                                                                    print sort@[f 0]


                                                                    It's a pretty straightforward recursive implementation. We check the indentation level by searching for the first non-space character (/S/) and getting its index ($-[0]). Unfortunately, we actually have to declare a handful of variables that are used in the recursion, or else they'll be implicitly global and the recursion won't work correctly.






                                                                    share|improve this answer












                                                                    Perl 5, 166 bytes



                                                                    sub fmy$p=shift;my@r;while(@i)$i[0]=~/S/;$c=$-[0];if($p<$c)$r[-1].=$_ for f($c)elsif($p>$c)lastelsepush@r,shift@isort@rpush@i,$_ while<>;print sort@[f 0]


                                                                    Ungolfed (sort of):



                                                                    sub f 
                                                                    my $p = shift;
                                                                    my @r;
                                                                    while(@i)
                                                                    $i[0] =~ /S/;
                                                                    $c = $-[0];
                                                                    if($p < $c)
                                                                    $r[-1] .= $_ for f($c)
                                                                    elsif ($p > $c)
                                                                    last
                                                                    else
                                                                    push @r, shift @i


                                                                    sort @r


                                                                    push @i, $_ while <>;
                                                                    print sort@[f 0]


                                                                    It's a pretty straightforward recursive implementation. We check the indentation level by searching for the first non-space character (/S/) and getting its index ($-[0]). Unfortunately, we actually have to declare a handful of variables that are used in the recursion, or else they'll be implicitly global and the recursion won't work correctly.







                                                                    share|improve this answer












                                                                    share|improve this answer



                                                                    share|improve this answer










                                                                    answered Aug 22 at 23:37









                                                                    Silvio Mayolo

                                                                    1,399817




                                                                    1,399817



























                                                                         

                                                                        draft saved


                                                                        draft discarded















































                                                                         


                                                                        draft saved


                                                                        draft discarded














                                                                        StackExchange.ready(
                                                                        function ()
                                                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f171003%2findentation-based-sort%23new-answer', 'question_page');

                                                                        );

                                                                        Post as a guest













































































                                                                        Comments

                                                                        Popular posts from this blog

                                                                        What does second last employer means? [closed]

                                                                        List of Gilmore Girls characters

                                                                        Confectionery