Saindo do ninho


23

Dada uma lista não plana de números inteiros, produza uma lista de listas contendo os números inteiros em cada nível de aninhamento, começando com o nível menos aninhado, com os valores em sua ordem original na lista de entrada quando lidos da esquerda para a direita. Se duas ou mais listas estiverem no mesmo nível de aninhamento na lista de entrada, elas deverão ser combinadas em uma única lista na saída. A saída não deve conter nenhuma lista vazia - os níveis de aninhamento que contêm apenas listas devem ser ignorados completamente.

Você pode assumir que os números inteiros estão todos no intervalo (inclusive) [-100, 100]. Não há comprimento máximo ou profundidade de aninhamento para as listas. Não haverá listas vazias na entrada - cada nível de aninhamento conterá pelo menos um número inteiro ou lista.

A entrada e a saída devem estar na lista nativa / array / enumerable / iterable / etc do seu idioma. ou em qualquer formato razoável e inequívoco, se o seu idioma não possuir um tipo de sequência.

Exemplos

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

Respostas:


5

Pyth, 17

 us-GeaYsI#GQ)S#Y

O espaço principal é importante. Isso filtra a lista se os valores são invariáveis ​​na sfunção, remove esses valores da lista e o achata em um nível. Os valores também são armazenados Ye, quando imprimimos, removemos os valores vazios filtrando se o valor classificado da lista é verdadeiro.

Suíte de teste

Como alternativa, uma resposta de 15 bytes com um formato de saída duvidoso:

 us-GpWJsI#GJQ)

Suíte de teste

Expansão:

 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

5

Mathematica, 56 54 52 bytes

-2 bytes devido a Alephalpha .

-2 bytes devido a CatsAreFluffy .

Cases[#,_?AtomQ,{i}]~Table~{i,Depth@#}/.{}->Nothing&

Na verdade, exclui níveis vazios.


1
Cases[#,_?AtomQ,{i}]~Table~{i,Depth@#}~DeleteCases~{}&
Alephalpha

1
Cases[#,_?AtomQ,{i}]~Table~{i,Depth@#}/.{}->Nothing&, 2 bytes mais curto
CalculatorFeline

3

Python 2, 78 bytes

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 bytes

#~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 bytes

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

Obrigado Neil por ajudar a eliminar 32 bytes.


1
Muitas oportunidades para jogar golfe aqui. Alguns são fáceis de remover o !=nullque nullé falso de qualquer maneira. O b=também é desnecessário. Depois de removido, você pode mover o .filter(a=>x)para o &&bque reduz a função externa para uma chamada para a função interna, que pode ser incorporada. Eu estou à esquerda com este: 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

A @Neil d[0]?avaliaria falsese era igual a 0, que está dentro da faixa [-100,100]. E assim seriad=>d
Patrick Roberts

@ Neil Vomitou este com pressa, então eu sabia que havia outras oportunidades para reduzi-lo, mas isso é muito melhor do que eu poderia ter feito até então. Obrigado! Ah, e Patrick está certo na verificação nula sendo necessária por esse motivo. Eu fui com d===+dembora, uma vez que salva 2 bytes na verificação nula.
Mwr247

1
@Dendrobium Isso não resolverá o último caso (ou nenhum caso com [...,[[...]]]) adequadamente #
Mwr247

1
@PatrickRoberts d=>destá OK, pois dsempre é um array ou nulo nesse ponto, mas é um ponto justo d[0], embora sempre exista algo d.mapque seja verdadeiro para um array, mas falso para um número.
Neil


0

Python, 108 99 bytes

Isso me parece um pouco demorado, mas eu não conseguia diminuir o prazo de uma linha e, se eu tentar usar em orvez de if, recebo listas vazias nos resultados.

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

Experimente online

Editar: salvou 9 bytes graças ao estouro de pilha


Você deve alterar seus recuos para espaços únicos, para que sejam renderizados corretamente no bloco de código. Você também pode usar filter(None,o)para remover listas vazias que estão no nível de aninhamento mais externo de o.
Mego 19/02

Eu prefiro ver meu código com abas. Os espaços são maus.
mbomb007

O SE Markdown converte as guias em 4 espaços, para que não haja como escapar delas :) Usar um único espaço no Markdown faz com que a contagem de bytes do bloco de código realmente corresponda à contagem de bytes do código.
Mego 19/02

Meu código em si contém guias, se você quiser editá-lo. É o que está por dentro que conta. ;)
mbomb007

0

Python 3, 109 bytes

Como sempre, estúpido Python 2 características como comparar ints e lists média que Python 3 sai por trás. Ah bem...

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 bytes

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

A entrada é esperada em @i, a saída produzida em @o. (Espero que isso seja aceitável).

Exemplo:

@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);

Saída:

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

0

Clojure, 119 bytes

(116 com seq? E entrada como listas, uma modificação trivial)

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

Melhor intenção:

(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 chamado com dois argumentos (o nível atual e uma coleção), ele cria um mapa não ordenado de um elemento {level: value}, ou chama frecursivamente se um número não (presumivelmente uma coleção) é visto.

Esses mini-mapas são então mesclados em uma única sorted-mape as principais colisões são tratadas por concatfunção.valsretorna os valores do mapa do primeiro nível ao último.

Se um número é o único em seu nível, ele permanece sendo um vec, outros são convertidos em listas por concat.

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

Se a entrada era um em listvez de vecentão number?poderia ser substituída por seq?, estranhamente o vetor não é, seq?mas é sequential?. Mas tenho preguiça de implementar essa versão, refazer exemplos etc.


0

Raquete 259 bytes

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

Teste:

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

Saída:

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

0

MATL , 37 bytes

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

Experimente online!

Funciona com a versão atual (13.0.0) do idioma / compilador.

Isso produz a saída como linhas de valores separados por espaço, onde cada linha corresponde ao mesmo nível de aninhamento e diferentes níveis de aninhamento são separados por novas linhas.

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.