Сортировка на основе отступов

35

Учитывая упорядоченный список буквенных строк в одном и том же случае (az XOR AZ), где каждой строке предшествует 0 или более пробелов (), выведите тот же список, но со строками, отсортированными на каждом уровне отступа. Глубины отступов для разных родителей считаются отдельными списками для целей сортировки.

пример

Если вы вводите:

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

Если вам нравится, подумайте об этом, как о списке каталогов, и вам нужно отсортировать имена в каждом каталоге.

мелочи

  • Элемент может иметь отступ на любое количество пробелов. Если он имеет одинаковое количество пробелов с предыдущим элементом, он принадлежит к той же иерархии сортировки, что и предыдущий элемент. Если он отступает большему количеству пробелов, это начало новой подчиненной иерархии.
  • Если строка имеет отступ с меньшим количеством пробелов, чем строка над ней, она соединяется с ближайшей подгруппой над ней с таким же # или меньшим количеством пробелов перед ней (как хрен в приведенном выше примере, который связывается с группой васаби над ней, потому что васаби - первый предмет над ним, который не имеет больше места, чем хрен)
  • Вы должны сохранить уровень отступа каждого элемента ввода в вашем выводе
  • Вкладки в выводе запрещены
  • Первая строка ввода никогда не будет иметь отступ
  • Ваша программа должна обрабатывать хотя бы одну строку из всех прописных и строчных букв; это не должно обращаться с обоими.

счет

Это , поэтому ответ, который использует наименьшее количество байтов, выигрывает.

Techrocket9
источник
7
Отличный вызов!
Адам
1
Кстати, в следующий раз, рассмотрите возможность использования Песочницы для устранения проблем с проблемой, прежде чем публиковать ее на главном сайте.
Адам
8
@ Adám Нет, необходимая логика рекурсивного разбора строк - вот причина, по которой я написал это приглашение.
Techrocket9
2
Если входной ['a','..b', '.c', '..d'], то каким должен быть выход? ['a','..b', '.c', '..d']или ['a','.c','..b', '..d']какая-то другая вещь? (Я использую '.'вместо места для наглядности).
Час Браун
2
@ streetster strings (az XOR AZ)
Adám

Ответы:

14

Python 2 , 117 байт

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

Попробуйте онлайн!

Принимает в качестве входных данных список строк; и выводит список строк, отсортированных по мере необходимости.

Идея состоит в том, чтобы превратить каждый элемент в список, который содержит «абсолютный путь» в виде списка; а затем пусть Python обрабатывает сортировку. Например, если вход:

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

Затем с помощью reduce()мы преобразуем в список списков:

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

который сортируется как:

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

и затем выведите последний элемент каждого списка в list-of-lists, чтобы получить:

[
 'a',
 ' b'
 ' c',
 '  d',
]
Час Браун
источник
Ничего себе, решение, которое я собирался опубликовать, было 183 байта ... Я сосу лол
Дон Тысяча
4
@Rushabh Мехта: моя первая попытка была около 205 байтов ... потом взломать! :)
Час Браун
7

APL (Dyalog Unicode) , 31 байт SBCS

Анонимный префикс лямбда, принимает и возвращает список строк.

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

Попробуйте онлайн!

{} "Дфн"; это аргумент

⍵[] Индексировать аргумент следующими индексами:

  ' '()¨⍵ Применить следующую скрытую функцию к каждой строке с пробелом в качестве левого аргумента:

   , объединить пробел со строкой

   ⊣= Логический список, указывающий, где пробел равен каждому символу

   ,⊂⍨ используйте это, чтобы разделить (начать часть, где истина) объединение пробела и строки

   смешать список списков строк в матрицу строк

  {}⍀ Кумулятивное уменьшение по вертикали этим «dfn»; а верхние и нижние арги:

   ≢⍵ длина нижней строки

   1= это равно 1? (то есть там нет ничего, кроме единственного пробела?)

   :⍺ если так, верните верхний аргумент

   ⋄⍵ иначе, верните нижний аргумент

   оценить (найти индексы, которые будут сортировать это)

Адам
источник
7

Сетчатка , 47 байт

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

Попробуйте онлайн! Примечание: несколько строк имеют пробелы. Объяснение:

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

Первый шаг - вставить каждое слово в следующие строки с одинаковым отступом. Например, с помощью линии aisle, wasabiи elfполученные линии aisle, aisle wasabiи aisle wasabi elf. Я обнаружил это регулярное выражение методом проб и ошибок, поэтому в нем могут быть крайние случаи.

O$`
$L$&

Теперь мы можем сортировать строки без учета регистра.

\S+ 
 

Удалить все вставленные слова.

Нил
источник
4

Perl 6 , 120 83 81 63 54 37 47 42 байта

-5 байт благодаря nwellnhof

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

Попробуйте онлайн!

Это использует метод Часа Брауна . Блок анонимного кода, который принимает список строк и возвращает список строк.

Объяснение:

{                                        }  # 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
Джо Кинг
источник
@nwellnhof Спасибо за указание на это. Я думаю, что я исправил это в последней версии
Джо Кинг
@nwellnhof Ну, это было короче в предыдущей итерации. Спасибо за отключение байтов, но мне пришлось немного изменить его
Джо Кинг
О верно. На самом деле, что-то подобное {my@a;.sort:{@a[+.comb(' ')...*>@a]=$_;~@a}}требуется для поддержки более высоких уровней отступов.
nwellnhof
3

Чистый , 112 101 байт

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

f o$

Попробуйте онлайн!

Анонимная функция, :: [[Char]] -> [[Char]]которая переносится $ :: [[Char]] -> [[[Char]]]в правильный формат вывода. $группирует строки в «больше пробелов, чем» и «все остальное после», рекурсивно обрабатывает каждую группу и сортирует, когда они присоединены. На каждом шаге сортируемый список выглядит так:

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

Чисто , 127 байт

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

Попробуйте онлайн!

Определяет функцию, $ :: [[Char]] -> [[Char]]которая разделяет строки на кортежи в форме, (spaces, letters)которые рекурсивно сортируются вспомогательной функцией ? :: [([Char],[Char])] -> [[([Char],[Char])]].

Разъяснение:

$ 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
Οurous
источник
1

JavaScript (Node.js) , 114 100 92 88 байт

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

Попробуйте онлайн!

Аналогичный подход к ответу Chas Brown на Python, но с использованием регулярных выражений.

объяснение

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
)                                   //
Сиеру Асакото
источник
0

К4 , 51 байт

Решение:

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

Пример:

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"

Предположения:

а. То, что каждая иерархия будет начинаться с самого низкого уровня, т.е. вы не получите:

bdellium
      fox
    hound
    alien

Объяснение:

{,/(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
streetster
источник
0

Perl 5, 166 байт

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

Ungolfed (вроде):

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

Это довольно простая рекурсивная реализация. Мы проверяем уровень отступа, ища первый непробельный символ ( /\S/) и получая его индекс ( $-[0]). К сожалению, нам действительно нужно объявить несколько переменных, которые используются в рекурсии, иначе они будут неявно глобальными и рекурсия не будет работать правильно.

Сильвио Майоло
источник