Classificação baseada em recuo

35

Dada uma lista ordenada de cadeias de letras no mesmo caso (az XOR AZ), em que cada cadeia é precedida por 0 ou mais caracteres de espaço (), produz a mesma lista, mas com as cadeias classificadas em cada nível de indentação. As profundidades de indentação sob pais diferentes contam como listas distintas para fins de classificação.

Exemplo

Se sua entrada for:

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

sua saída deve ser

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

Se desejar, pense nela como uma lista de diretórios e você precisa classificar os nomes em cada diretório.

Minutiae

  • Um item pode ser recuado por qualquer número de espaços. Se for recuado pelo mesmo número de espaços que o item anterior, ele pertence à mesma hierarquia de classificação que o item anterior. Se for recuado por mais espaços, será o início de uma nova sub-hierarquia.
  • Se uma linha é recuada por menos espaços do que a linha acima, ela se vincula ao subgrupo mais próximo acima dela com o mesmo # ou menos espaços antes dela (como rábano no exemplo acima, que se vincula ao grupo wasabi acima dela porque wasabi é o primeiro item acima dele a não ter mais espaços do que o rábano)
  • Você deve preservar o nível de indentação de cada item de entrada em sua saída
  • Guias na saída não são permitidas
  • A primeira linha da entrada nunca será recuada
  • Seu programa deve manipular pelo menos uma das seqüências de caracteres todas em maiúsculas e minúsculas; não precisa lidar com ambos.

Pontuação

Este é um , então a resposta que usa o menor número de bytes vence.

Techrocket9
fonte
7
Bom desafio!
Adám 21/08/19
11
Aliás, para a próxima vez, considere usar o Sandbox para resolver problemas com um desafio antes de publicá-lo no site principal.
Adám 21/08/18
8
@ Adám Não, a lógica de análise de string recursiva necessária é a razão pela qual escrevi esse prompt.
usar o seguinte código
2
Se a entrada for ['a','..b', '.c', '..d'], qual deve ser a saída? ['a','..b', '.c', '..d']ou ['a','.c','..b', '..d']ou alguma outra coisa? (Estou usando o '.'espaço em vez de clareza visual).
quer
2
@streetster strings (az XOR AZ)
Adám

Respostas:

14

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

Experimente online!

Toma como entrada uma lista de strings; e gera uma lista de cadeias, classificadas conforme necessário.

A idéia é transformar cada elemento em uma lista que contenha o "caminho absoluto" como uma lista; e então deixe o Python lidar com a classificação. Por exemplo, se a entrada for:

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

Em seguida, através do reduce(), convertemos para uma lista de listas:

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

que é classificado como:

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

e, em seguida, imprima o último elemento de cada lista na lista de listas para obter:

[
 'a',
 ' b'
 ' c',
 '  d',
]
Chas Brown
fonte
Uau, a solução que eu estava prestes a postar era de 183 bytes ... Eu sou péssimo, lol #
Don Thousand
4
@Rushabh Mehta: Minha primeira tentativa foi em torno de 205 bytes ... e depois foi embora! :)
Chas Brown
7

APL (Dyalog Unicode) , SBCS de 31 bytes

Prefixo anônimo lambda, pega e retorna lista de strings.

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

Experimente online!

{... } "dfn"; é argumento

⍵[] Indexe o argumento com os seguintes índices:

  ' '()¨⍵ Aplique a seguinte função tácita a cada sequência com espaço como argumento à esquerda:

   , concatenar o espaço para a string

   ⊣= Lista booleana indicando onde o espaço é igual a cada caractere que

   ,⊂⍨ use isso para particionar (começar parte onde true) a concatenação de espaço e string

   misture lista de listas de strings em matriz de strings

  {}⍀ Redução cumulativa vertical por este "dfn"; e são argumentos superiores e inferiores:

   ≢⍵ o comprimento da corda inferior

   1= isso é igual a 1? (ou seja, não há nada além do espaço único lá?)

   :⍺ Nesse caso, retorne o argumento superior

   ⋄⍵ caso contrário, retorne o argumento inferior

   graduação (encontre índices que classifiquem isso)

Adão
fonte
7

Retina , 47 bytes

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

Experimente online! Nota: Várias linhas têm espaços à direita. Explicação:

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

O primeiro passo é inserir cada palavra nas seguintes linhas no mesmo recuo. Por exemplo, com as linhas aisle, wasabie elfas linhas resultantes são aisle, aisle wasabie aisle wasabi elf. Descobri esse regex por tentativa e erro, portanto pode haver casos extremos com ele.

O$`
$L$&

Agora podemos classificar as linhas sem distinção entre maiúsculas e minúsculas.

\S+ 
 

Exclua todas as palavras inseridas.

Neil
fonte
4

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

-5 bytes graças a nwellnhof

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

Experimente online!

Isso usa o método de Chas Brown . Um bloco de código anônimo que pega uma lista de linhas e retorna uma lista de linhas.

Explicação:

{                                        }  # 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
Brincadeira
fonte
@nwellnhof Obrigado por apontar isso. Eu acho que eu corrigi-lo na versão mais recente
Jo King
@nwellnhof Ah, bem, foi mais curto em uma iteração anterior. Obrigado pelos bytes desativados, mas tive que alterá-lo um pouco #
Jo King
Oh, certo. Na verdade, algo como {my@a;.sort:{@a[+.comb(' ')...*>@a]=$_;~@a}}é necessário para suportar níveis mais altos de indentação.
Nwellnhof 22/08/19
3

Limpo , 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$

Experimente online!

Função anônima :: [[Char]] -> [[Char]]que envolve $ :: [[Char]] -> [[[Char]]]o formato de saída correto. $agrupa as seqüências de caracteres em "mais espaços que" e "tudo o mais depois", se repete sobre cada grupo e classifica quando estão unidas. A cada etapa, a lista que está sendo classificada se parece com:

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

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

Experimente online!

Define a função $ :: [[Char]] -> [[Char]]que separa as seqüências de caracteres em tuplas no formulário (spaces, letters)que são classificadas recursivamente pela função auxiliar ? :: [([Char],[Char])] -> [[([Char],[Char])]].

Explicado:

$ 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
Furioso
fonte
1

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

Experimente online!

Abordagem semelhante à resposta Python de Chas Brown, mas usando expressões regulares.

Explicação

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
)                                   //
Shieru Asakoto
fonte
0

K4 , 51 bytes

Solução:

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

Exemplo:

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"

Suposições:

uma. Que cada hierarquia começará com o nível mais baixo, ou seja, você não terá:

bdellium
      fox
    hound
    alien

Explicação:

{,/(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
rua
fonte
0

Perl 5, 166 bytes

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 (tipo de):

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

É uma implementação recursiva bastante direta. Verificamos o nível de indentação pesquisando o primeiro caractere não espacial ( /\S/) e obtendo seu índice ( $-[0]). Infelizmente, precisamos declarar algumas variáveis ​​usadas na recursão, caso contrário elas serão implicitamente globais e a recursão não funcionará corretamente.

Silvio Mayolo
fonte