Сортування на основі відступу


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

Якщо вам подобається, подумайте про це як перелік каталогів, і вам потрібно сортувати імена в кожному каталозі.

Хвилини

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

Оцінка балів

Це , тому відповідь, в якій використовується найменше байт, виграє.


7
Приємний виклик!
Adám

1
Btw, наступного разу, подумайте про використання пісочниці для виправлення проблем із викликом, перш ніж розміщувати її на головному сайті.
Adám

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

а потім вивести останній елемент кожного списку у списку списків, щоб отримати:

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

Нічого собі рішення, яке я збирався опублікувати, було 183 байти ... Я смоктав лол
Дон Тисяча

4
@Rushabh Mehta: Перша моя спроба полягала в 205 байтах ... потім рубати! :)
Час Браун

7

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

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

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

Спробуйте в Інтернеті!

{} "Dfn"; є аргументом

⍵[] Індексуйте аргумент за допомогою таких індексів:

  ' '()¨⍵ Застосувати наступну функцію мовчання до кожного рядка з пробілом як лівий аргумент:

   , об'єднати простір у рядок

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

   ,⊂⍨ використовувати це для розділення (почати частину там, де істинно) конкатенації простору та рядка

   змішати список списків рядків у матрицю рядків

  {}⍀ Вертикальне кумулятивне зменшення на цей "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

Перл 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 Дякую, що вказав на це. Я думаю, що я виправив це в останній версії
Jo King

@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)яка рекурсивно сортується за допомогою функції helper ? :: [([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

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

Спробуйте в Інтернеті!

Аналогічний підхід до відповіді Шатона Брауна на 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

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

Безголів (вид):

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]). На жаль, нам насправді доводиться оголошувати кілька змінних, які використовуються в рекурсії, інакше вони будуть неявно глобальними, і рекурсія не буде працювати належним чином.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.