Ordinamento basato su rientro


35

Dato un elenco ordinato di stringhe di lettere dello stesso caso (az XOR AZ) in cui ogni stringa è preceduta da 0 o più caratteri spazio (), genera lo stesso elenco ma con le stringhe ordinate a ciascun livello di rientro. Le profondità di rientro in genitori diversi contano come elenchi distinti ai fini dell'ordinamento.

Esempio

Se il tuo input è:

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

il tuo output dovrebbe essere

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

Se lo desideri, pensalo come un elenco di directory e devi ordinare i nomi all'interno di ciascuna directory.

minutiae

  • Un oggetto può essere rientrato da qualsiasi numero di spazi. Se è indentato dallo stesso numero di spazi dell'elemento precedente, appartiene alla stessa gerarchia di ordinamento dell'elemento precedente. Se è indentato da più spazi, è l'inizio di una nuova sotto-gerarchia.
  • Se una linea è indentata da meno spazi rispetto alla linea sopra di essa, si collega al sottogruppo più vicino sopra di essa con lo stesso # o meno spazi prima di essa (come il rafano nell'esempio sopra, che si collega al gruppo wasabi sopra di essa perché wasabi è il primo oggetto sopra di esso a non avere più spazi del rafano)
  • È necessario preservare il livello di rientro di ciascun elemento di input nell'output
  • Le schede nell'output non sono consentite
  • La prima riga dell'ingresso non sarà mai rientrata
  • Il programma deve gestire almeno una delle stringhe maiuscole e minuscole; non deve gestire entrambi.

punteggio

Questo è un , quindi vince la risposta che utilizza il minor numero di byte.


7
Bella sfida!
Adám,

1
A proposito, per la prossima volta, considera l'utilizzo di Sandbox per risolvere i problemi con una sfida prima di pubblicarlo sul sito principale.
Adám,

8
@ Adám No, la logica di analisi della stringa ricorsiva richiesta è il motivo per cui ho scritto questo messaggio.
Techrocket9,

2
Se l'input è ['a','..b', '.c', '..d'], quale dovrebbe essere l'output? ['a','..b', '.c', '..d']o ['a','.c','..b', '..d']o qualche altra cosa? (Sto usando '.'invece di spazio per chiarezza visiva).
Chas Brown,

2
Stringhe
Adám,

Risposte:



14

Python 2 , 117 byte

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

Provalo online!

Accetta come input un elenco di stringhe; e genera un elenco di stringhe, ordinate come richiesto.

L'idea è di trasformare ogni elemento in un elenco che contiene il "percorso assoluto" come un elenco; e quindi lasciare che Python gestisca l'ordinamento. Ad esempio, se l'input è:

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

Quindi tramite il reduce(), convertiamo in un elenco di elenchi:

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

che viene ordinato come:

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

e quindi emette l'ultimo elemento di ciascun elenco nell'elenco di elenchi per ottenere:

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

Wow, la soluzione che stavo per pubblicare era di 183 byte ... I suck lol
Don Thousand

4
@Rushabh Mehta: il mio primo tentativo è stato di circa 205 byte ... quindi hackerare! :)
Chas Brown,

7

APL (Dyalog Unicode) , 31 byte SBCS

Prefisso anonimo lambda, accetta e restituisce un elenco di stringhe.

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

Provalo online!

{... } "dfn"; è argomento

⍵[... ] indicizza l'argomento con i seguenti indici:

  ' '(... )¨⍵ applica la seguente funzione tacita a ciascuna stringa con spazio come argomento sinistro:

   , concatenare lo spazio alla stringa

   ⊣= Elenco booleano che indica dove lo spazio è uguale a ciascun carattere

   ,⊂⍨ usalo per partizionare (inizia la parte dove vero) la concatenazione di spazio e stringa

   mescola l'elenco di elenchi di stringhe in una matrice di stringhe

  {... }⍀ riduzione cumulativa verticale di questo "dfn"; e sono argomenti superiori e inferiori:

   ≢⍵ la lunghezza della corda inferiore

   1= è uguale a 1? (cioè non c'è altro che il singolo spazio lì?)

   :⍺ in tal caso, restituisce l'argomento superiore

   ⋄⍵ altrimenti, restituisce l'argomento inferiore

   voto (trova gli indici che lo ordineranno)


7

Retina , 47 byte

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

Provalo online! Nota: diverse linee hanno spazi finali. Spiegazione:

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

Il primo passo è inserire ogni parola nelle seguenti righe con lo stesso rientro. Ad esempio, con le linee aisle, wasabie elfle linee risultanti sono aisle, aisle wasabie aisle wasabi elf. Ho scoperto questa regex per tentativi ed errori, quindi potrebbero esserci casi limite con esso.

O$`
$L$&

Ora possiamo ordinare le linee senza distinzione tra maiuscole e minuscole.

\S+ 
 

Elimina tutte le parole inserite.


4

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

-5 byte grazie a nwellnhof

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

Provalo online!

Questo utilizza il metodo di Chas Brown . Un blocco di codice anonimo che accetta un elenco di righe e restituisce un elenco di righe.

Spiegazione:

{                                        }  # 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 Grazie per averlo sottolineato. Penso di averlo risolto nell'ultima versione
Jo King,

@nwellnhof Ah bene, era più breve in una precedente iterazione. Grazie per il byte, ma ho dovuto cambiarlo leggermente
Jo King,

Oh giusto. In realtà, {my@a;.sort:{@a[+.comb(' ')...*>@a]=$_;~@a}}è necessario qualcosa di simile per supportare livelli di rientro più elevati.
nwellnhof,

3

Pulito , 112 101 byte

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

f o$

Provalo online!

Funzione anonima :: [[Char]] -> [[Char]]che si avvolge $ :: [[Char]] -> [[[Char]]]nel formato di output corretto. $raggruppa le stringhe in "più spazi di" e "tutto il resto dopo", ricorre su ogni gruppo e ordina quando sono adiacenti. Ad ogni passaggio, l'elenco ordinato è simile a:

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

Pulito , 127 byte

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

Provalo online!

Definisce la funzione $ :: [[Char]] -> [[Char]]che separa le stringhe in tuple nella forma (spaces, letters)che sono ordinate in modo ricorsivo dalla funzione helper ? :: [([Char],[Char])] -> [[([Char],[Char])]].

Ha spiegato:

$ 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 byte

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

Provalo online!

Approccio simile alla risposta Python di Chas Brown, ma usando invece espressioni regolari.

Spiegazione

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

K4 , 51 byte

Soluzione:

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

Esempio:

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"

ipotesi:

un. Ogni gerarchia inizierà con il livello più basso, cioè non otterrai:

bdellium
      fox
    hound
    alien

Spiegazione:

{,/(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 byte

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 (sorta di):

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

È un'implementazione ricorsiva piuttosto semplice. Controlliamo il livello di rientro cercando il primo carattere non spaziale ( /\S/) e ottenendo il suo indice ( $-[0]). Sfortunatamente, in realtà dobbiamo dichiarare una manciata di variabili utilizzate nella ricorsione, altrimenti saranno implicitamente globali e la ricorsione non funzionerà correttamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.