Lasciando il nido


23

Dato un elenco non intero di numeri interi, genera un elenco di elenchi contenenti gli interi in ciascun livello di annidamento, a partire dal livello meno nidificato, con i valori nel loro ordine originale nell'elenco di input quando letti da sinistra a destra. Se due o più elenchi si trovano allo stesso livello di annidamento nell'elenco di input, devono essere combinati in un unico elenco nell'output. L'output non deve contenere elenchi vuoti: i livelli di annidamento che contengono solo elenchi devono essere saltati del tutto.

Si può presumere che gli interi siano tutti nell'intervallo (inclusivo) [-100, 100]. Non esiste una lunghezza massima o una profondità di annidamento per gli elenchi. Non ci saranno elenchi vuoti nell'input: ogni livello di annidamento conterrà almeno un numero intero o un elenco.

L'input e l'output devono essere nell'elenco nativo / array / enumerable / iterable / etc della tua lingua. formato o in qualsiasi formato ragionevole e inequivocabile se nella tua lingua manca un tipo di sequenza.

Esempi

[1, 2, [3, [4, 5], 6, [7, [8], 9]]] => [[1, 2], [3, 6], [4, 5, 7, 9], [8]]

[3, 1, [12, [14, [18], 2], 1], [[4]], 5] => [[3, 1, 5], [12, 1], [14, 2, 4], [18]]

[2, 1, [[5]], 6] => [[2, 1, 6], [5]]

[[54, [43, 76, [[[-19]]]], 20], 12] => [[12], [54, 20], [43, 76], [-19]]

[[[50]], [[50]]] => [[50, 50]]

Risposte:


5

Pyth, 17

 us-GeaYsI#GQ)S#Y

Lo spazio principale è importante. Ciò filtra l'elenco sul fatto che i valori siano invarianti sulla sfunzione, quindi rimuove tali valori dall'elenco e lo appiattisce di un livello. Anche i valori sono memorizzati Ye quando stampiamo rimuoviamo i valori vuoti filtrando se il valore ordinato dell'elenco è vero.

Test Suite

In alternativa, una risposta di 15 byte con un formato di output dubbi:

 us-GpWJsI#GJQ)

Test Suite

Espansione:

 us-GeaYsI#GQ)S#Y     ##   Q = eval(input)
 u          Q)        ##   reduce to fixed point, starting with G = Q
        sI#G          ##   get the values that are not lists from G
                      ##   this works because s<int> = <int> but s<list> = flatter list
      aY              ##   append the list of these values to Y
     e                ##   flatten the list
   -G                 ##   remove the values in the list from G
              S#Y     ##   remove empty lists from Y


3

Python 2, 78 byte

f=lambda l:l and zip(*[[x]for x in l if[]>x])+f(sum([x for x in l if[]<x],[]))


1

Mathematica 55 64 62 byte

#~Select~AtomQ/.{}->Nothing&/@Table[Level[#,{k}],{k,Depth@#}]&

%&[{1, 2, {3, {4, 5}, 6, {7, {8}, 9}}}]

{{1, 2}, {3, 6}, {4, 5, 7, 9}, {8}}


1

JavaScript, 112 80 byte

F=(a,b=[],c=0)=>a.map(d=>d!==+d?F(d,b,c+1):b[c]=[...b[c]||[],d])&&b.filter(d=>d)

Grazie a Neil per aver contribuito a radere 32 byte.


1
Molte opportunità per giocare a golf qui. Alcuni facili sono rimuovere comunque !=nullcome nullè falsy. Il b=è anche inutile. Dopo averlo rimosso, è possibile spostare il .filter(a=>x)verso il &&bquale quindi riduce la funzione esterna a una chiamata alla funzione interna che è quindi possibile incorporare. Mi rimane questo: f=(a,b=[],c=0)=>a.map(d=>d[0]?f(d,b,c+1):b[c]=[...b[c]||[],d])&&b.filter(d=>d).
Neil,

@Neil d[0]?valuterebbe falsese fosse uguale a 0, che è all'interno dell'intervallo [-100,100]. E così sarebbed=>d
Patrick Roberts, il

@Neil Ha lanciato questo in fretta, quindi sapevo che c'erano altre opportunità per ridurlo, ma questo è molto meglio di quanto avrei potuto fare anche allora. Grazie! Oh, e Patrick ha ragione sul fatto che il controllo null sia necessario per quel motivo. Sono andato con d===+dperò, dal momento che salva 2 byte sul controllo null.
Mwr247,

1
@Dendrobium che non gestirà [...,[[...]]]correttamente l'ultimo caso (o nessun caso con )
Mwr247,

1
@PatrickRoberts d=>dè OK dato che dè sempre un array o null a quel punto, ma un punto giusto riguardo d[0], sebbene ci sia sempre d.mapquale sarà la verità per un array ma falsa per un numero.
Neil,

1

Gelatina, 24 byte

fFW®;©ṛ¹ḟF;/µŒḊ’$¡W®Tị¤;

Provalo online!

Se fossero consentiti elenchi separati da una nuova riga, questo potrebbe essere ridotto a 14 byte .

fFṄ¹¹?ḟ@¹;/µ¹¿

Provalo online!


0

Python, 108 99 byte

Mi sembra un po 'lungo, ma non potrei accorciare una riga, e se provo a usare orinvece di if, ottengo elenchi vuoti nei risultati.

def f(L):
    o=[];i=[];j=[]
    for x in L:[i,j][[]<x]+=[x]
    if i:o+=[i]
    if j:o+=f(sum(j,[]))
    return o

Provalo online

Modifica: salvato 9 byte grazie allo StackTranslate.it


È necessario modificare i rientri in spazi singoli, in modo che vengano visualizzati correttamente nel blocco di codice. È inoltre possibile utilizzare filter(None,o)per rimuovere elenchi vuoti che si trovano al livello di nidificazione più esterno di o.
Mego,

Preferisco visualizzare il mio codice con le schede. Gli spazi sono cattivi.
mbomb007,

SE Markdown converte le schede in 4 spazi, quindi non è possibile sfuggirle comunque :) L'uso di un singolo spazio nel Markdown fa sì che il conteggio dei byte del blocco di codice corrisponda effettivamente al conteggio dei byte del codice.
Mego,

Il mio codice stesso contiene schede se cerchi di modificarlo, però. Ciò che conta è ciò che c'è dentro. ;)
mbomb007,

0

Python 3, 109 byte

Come sempre, le stupide funzionalità di Python 2 come il confronto tra ints e lists significano che Python 3 viene fuori. Oh bene...

def d(s):
 o=[]
 while s:
  l,*n=[],
  for i in s:
   try:n+=i
   except:l+=[i]
  if l:o+=[l]
  s=n
 return o

0

Perl, 63 byte

{$o[$x++]=[@t]if@t=grep{!ref}@i;(@i=map{@$_}grep{ref}@i)&&redo}

L'ingresso è previsto in @i, l'output prodotto in @o. (Spero che questo sia accettabile).

Esempio:

@i=[[54, [43, 76, [[[-19]]]], 20], 12];                              # input

{$o[$x++]=[@t]if@t=grep{!ref}@i;(@i=map{@$_}grep{ref}@i)&&redo}      # the snippet

use Data::Dumper;                                                    # print output
$Data::Dumper::Indent=0;  # keep everything on one line
$Data::Dumper::Terse=1;   # don't print $VAR =
print Dumper(\@o);

Produzione:

[[12],[54,20],[43,76],[-19]]

0

Clojure, 119 byte

(116 con seq? E input come liste, una banale modifica)

(defn f([v](vals(apply merge-with concat(sorted-map)(flatten(f 0 v)))))([l v](map #(if(number? %){l[%]}(f(inc l)%))v)))

Meglio inteso:

(defn f([v]  (vals(apply merge-with concat(sorted-map)(flatten(f 0 v)))))
       ([l v](map #(if(number? %){l[%]}(f(inc l)%))v)))

Quando viene chiamato con due argomenti (il livello corrente e una raccolta) crea una mappa non ordinata a un elemento simile {level: value}o chiama fricorsivamente se viene visto un non numero (presumibilmente una raccolta).

Queste mini-mappe vengono quindi unite in una singola sorted-mape le collisioni chiave vengono gestite dalla concatfunzione. valsrestituisce i valori della mappa dal primo livello all'ultimo.

Se un numero è l'unico al suo livello, allora rimane a vec, gli altri vengono convertiti in elenchi da concat.

(f [[54, [43, 76, [[[-19]]]], 20], 12])
([12] (54 20) (43 76) [-19])

Se l'input era un listinvece di vecallora number?potrebbe essere sostituito da seq?, stranamente il vettore non seq?lo è ma lo è sequential?. Ma sono troppo pigro per implementare quella versione, ripetere esempi, ecc.


0

Racchetta 259 byte

(let((ol'())(m 0))(let p((l l)(n 0))(cond[(empty? l)][(list?(car l))(set! m(+ 1 n))
(p(car l)(+ 1 n))(p(cdr l)n)][(set! ol(cons(list n(car l))ol))(p(cdr l)n )]))
(for/list((i(+ 1 m)))(flatten(map(λ(x)(cdr x))(filter(λ(x)(= i(list-ref x 0)))(reverse ol))))))

Ungolfed:

(define (f l)
  (define ol '())
  (define maxn 0)
  (let loop ((l l)              ; in this loop each item is added with its level
             (n 0))
    (cond
      [(empty? l)]
      [(list? (first l))
       (set! maxn (add1 n))
       (loop (first l) (add1 n))
       (loop (rest l) n)]
      [else
       (set! ol (cons (list n (first l)) ol))
       (loop (rest l) n )]))

  ; now ol is '((0 1) (0 2) (1 3) (2 4) (2 5) (1 6) (2 7) (3 8) (2 9)) 

  (for/list ((i (add1 maxn)))   ; here similar levels are combined
    (flatten
     (map (λ (x) (rest x))      ; level numbers are removed
          (filter (λ (x) (= i(list-ref x 0)))
                  (reverse ol))))))

test:

(f '[1 2 [3 [4 5] 6 [7 [8] 9]]])

Produzione:

'((1 2) (3 6) (4 5 7 9) (8))

0

MATL , 37 byte

j']['!=dYsXKu"GK@=)'[\[\],]'32YXUn?1M

Provalo online!

Funziona con la versione corrente (13.0.0) del linguaggio / compilatore.

Ciò produce l'output come linee di valori separati da spazio, in cui ogni riga corrisponde allo stesso livello di annidamento e diversi livelli di annidamento sono separati da nuove righe.

j            % read input as string (row array of chars)
']['!        % 2x1 array containing ']'  and '['
=            % test for equality, all combinations
d            % row array obtained as first row minus second row
Ys           % cumulative sum. Each number is a nesting level
XK           % copy to clibdoard K
u            % unique values: all existing nesting levels
"            % for each nesting level
  G          %   push input
  K          %   push array that indicates nesting level of each input character
  @          %   push level corresponding to this iteration
  =          %   true for characters corresponding to that nesting level
  )          %   pick those characters
  '[\[\],]'  %   characters to be replaced
  32         %   space
  YX         %   regexp replacement
  U          %   only numbers and spaces remain: convert string to array of numbers
  n?         %   if non-empty
    1M       %     push that array of numbers again
             %   end if implicitly
             % end for each implicitly
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.