Nota: Este é o número 2 em uma série de desafios de manipulação de matriz . Para o desafio anterior, clique aqui .
Separando listas aninhadas
Para separar valores em uma lista aninhada, alise-o e, em seguida, agrupe cada valor para que ele fique na mesma profundidade aninhada de antes.
Ou seja, esta lista:
[1, [2, 3], [4, 4, [5, 2], 1]]
Se tornaria:
[1, [2], [3], [4], [4], [[5]], [[2]], [1]]
O desafio
Sua tarefa é escrever um programa que utilize qualquer lista aninhada de números inteiros positivos (dentro dos limites do seu idioma) e execute essa operação de separação.
Você pode enviar uma função que considere a lista como argumento ou um programa completo que execute E / S.
Como se trata de código-golfe , o envio mais curto (em bytes) vence! *
* As brechas de golfe padrão são proibidas. Você sabe o que fazer.
Casos de teste
As listas de entrada sempre conterão números inteiros no tamanho inteiro padrão do seu idioma. Para evitar restrições de idiomas que os impedem de competir, os valores não serão aninhados em profundidades superiores a 10.
Você pode assumir que a entrada não terá sub-listas vazias: por exemplo - [[5, []]]
não será fornecida. No entanto, a lista principal pode estar vazia.
[] -> []
[[1, 2]] -> [[1], [2]]
[3, [4, 5]] -> [3, [4], [5]]
[3, [3, [3]]] -> [3, [3], [[3]]]
[[6, [[7]]]] -> [[6], [[[7]]]]
[[5, 10], 11] -> [[5], [10], 11]
Não hesite em deixar um comentário se eu perdi uma caixa de esquina.
Exemplo
Eu joguei junto um (ungolfed) Python solução rápida 3 como um exemplo - você pode testá-lo em repl.it .
fonte
Respostas:
Braquilog , 16 bytes
Experimente online!
Explicação
fonte
Z
argumento faz no TIO? Sem ele, isso parece gerar true / false, o que faz parecerZ
necessário na contagem de bytes.Z
diz ao Brachylog que o argumento de saída é uma variável. Essa é a variável que é unificada com a saída resultante. Quando você o remove, ele informa ao Brachylog que a saída é uma variável anônima e, em vez disso, imprimirá se o predicado principal é bem-sucedido ou falha. É o mesmo que no Prolog, onde o resultado é "colocado" em uma variável.Mathematica,
2421 bytesou um destes:
Explicação
A razão disso é tão curto é que é basicamente uma recursão que não requer um caso base explícito.
Há muito açúcar sintático aqui, então vamos começar por isso.
&
denota uma função sem nome restante, cujo argumento é escrito como#
. Dentro desta função#0
refere-se à própria função, que permite escrever funções recursivas sem nome. Mas vamos começar dando um nome à função interna e retirando-a:O outro açúcar sintático importante é o
f/@x
que é curto,Map[f, x]
ou seja, ele invocaf
todos os elementos dex
. O motivof[x_] := ... f /@ x
não leva à recursão infinita é que o mapeamento de algo sobre um átomo deixa o átomo inalterado sem realmente chamar a função. Portanto, não precisamos verificar o caso base (o elemento atual é um número inteiro) explicitamente.Portanto, a função
f
primeiro recursa para a lista mais profundax
, e nesse pontof/@
torna-se um não operacional. Então chamamos de uso##& @@ List /@
nisso. O mapeamentoList
sobre a lista simplesmente agrupa cada elemento em uma lista separada,{1, 2, 3}
tornando - se assim{{1}, {2}, {3}}
. Em seguida, aplicamos##&
a ele, o que significa que a cabeça (ou seja, a lista externa) é substituída por##&
, então isso se transforma##&[{1}, {2}, {3}]
. Mas##&
simplesmente retorna seus argumentos como umSequence
(que você pode considerar uma lista desembrulhada ou uma espécie de operador "splat" em outros idiomas).Então,
##& @@ List /@
transforma uma lista{1, 2, 3}
em{1}, {2}, {3}
(mais ou menos, essa última coisa é realmente envolvida na cabeçaSequence
, mas isso desaparece assim que usamos o valor em qualquer lugar).Isso deixa a questão de por que
f
já não é a solução para o desafio. O problema é que a lista mais externa deve ser tratada de maneira diferente. Se tivermos entrada{{1, 2}, {3, 4}}
, queremos{{1}, {2}, {3}, {4}}
e não{{1}}, {{2}}, {{3}}, {{4}}
. Minha solução original corrigiu isso passando o resultado final como uma lista de argumentos para aJoin
qual restauraria o nível externo de listas, mas esse apenas ignora o nível externo usando-f
se em um mapa na saída. Portanto,f
é aplicado apenas aos elementos individuais da lista mais externa e nunca chega a tocar nessa lista.Quanto às outras três soluções, a primeira simplesmente aplica a recursão fora da
f
qual funciona da mesma forma. As outras duas soluções evitam umaMap
operação repetida , compondo primeiro duas funções e depois mapeando o resultado apenas uma vez.fonte
J ,
1918 bytesEste é um verbo anônimo que recebe e retorna matrizes em caixa, que são a versão de J (bastante complicada) de matrizes aninhadas. Veja passar em todos os casos de teste.
Explicação
Isso usa as operações um tanto exóticas
{::
( mapa ) eS:
( spread ), que operam em matrizes in a box.{::
substitui cada folha pelo caminho em caixa para essa folha.S:
aplica um determinado verbo a uma profundidade de aninhamento e divide os resultados em uma matriz.fonte
R, 199 bytes
Esta pergunta foi difícil. As listas de R são um pouco estranhas e não é absolutamente fácil repetir todos os elementos das sublistas. Também não é fácil determinar a profundidade dessa lista. Em seguida, o desafio passa a ser recriar a lista com todos os elementos separados; portanto, também precisamos de uma maneira adaptativa de criar uma lista com uma certa profundidade.
A solução consiste em duas grandes partes. Uma função recursiva que percorre todas as listas e registra a profundidade:
Quando temos as profundezas de todas as entradas do vetor
unlist(l)
armazenadasd
, criamos implicitamente uma listalapply
e a preenchemos com a seguinte função:Nesta chamada de aplicação, criamos um objeto
q
com o valor da entrada na lista, verificamos sua profundidade e verificamos se é diferente de zero. Se for zero, podemos apenas deixá-lo como um valor numérico. Se for diferente de zero, precisamos aninhar essa quantidade de listas. Então, chamamosd
tempos de loop for e repetidamenteq=list(q)
.lapply
depois coloca todos esses valoresq
em uma lista, criando a saída desejada.Programa completo com espaçamento adequado e tais:
fonte
is.list(y)
em vez declass(y)=='list'
? Não é possível verificar se isso realmente funcionará.Retina , 34 bytes
Experimente online!
fonte
(?<-2>)
trabalho?C (gcc), 147 bytes
Exemplo de entrada:
Exemplo de saída:
fonte
empilhados , não-concorrentes, 25 bytes
Essa é uma função, pois modifica o membro superior da pilha. Se você deseja uma função genuína, basta adicionar
[
e]
ao começo e ao fim. Experimente aqui!Aqui está uma versão legível:
Caso de teste:
Saída sem novas linhas:
fonte
*
como argumento para o bloco de código?d-1
tempos dos argumentos .$func
é uma função que pode ser manipulada.PHP,
10194 bytessalvou 1 byte graças a @Christoph, salvou outros 6 inspirados por isso.
função recursiva, bastante direta
demolir
fonte
$r
recebe elementos no circuito ou a função devolve uma matriz vazia. Pode gerar avisos, mas eles não são impressos com a configuração padrão.!cos()
.cos()
retornanull
para todo array e float! = 0 para todo inteiro positivo. Quero dizer ... quem se importa com avisos?is_int
: Inverter a condição não salva nada; Eu preciso de um espaço entreelse
eforeach
. MAS:$b[0]
para um número inteiro éNULL
.Python 2,
122106 bytesPontuação bastante terrível, apenas uma implementação direta.
Obrigado a @Zachary T por ajudar a economizar 16 bytes!
Ligue
x
com um argumento para executar. Por algum motivo, ele pode ser executado apenas uma vez.fonte
a+=[n(l,d)]
paraa+=n(l,d),
(observe a vírgula à direita)t
?n
para a função e remover o primeiro argumento, pois sempre serál
.JavaScript (Firefox 30-57), 53 bytes
A melhor resposta ES6 que tenho até agora é 76 bytes:
fonte
f=
.Pitão - 29 bytes
Conjunto de Teste .
fonte
Perl 6 ,
6047 bytes( Experimente online. )
Explicação:
[... for |$^a]
: Itere sobre a matriz de entrada e construa uma nova matriz a partir dela.$_ ~~ List ?? ... !! ...
: Para cada elemento, verifique se ele próprio é uma matriz.|([$_] for .&f)
: Se o elemento for uma matriz, aplique recursivamente a função, itere sobre os elementos da nova matriz retornada pela chamada recursiva, envolva cada elemento em uma matriz própria e insira-os na lista externa.$_
: Se o elemento não for uma matriz, passe-o como está.fonte
Haskell, 71 bytes
Novamente, tenho que definir meu próprio tipo de lista, porque as listas de nativos de Haskell não podem ser aninhadas arbitrariamente. Esse novo tipo
L
pode ser retornado de uma função, mas não ser impresso por padrão; portanto, para ver um resultado, defino umashow
instância paraL
:Agora podemos fazer alguns testes no REPL:
Como funciona: uma recursão simples que passa o nível de aninhamento em função dos
C
construtores. Começamos com a função de identidadeid
e sempre que houver uma lista (-> correspondência de padrãod#C l=
), adicionamos uma camada adicional deC
(->C .pure.d
) à chamada recursiva de#
todos os elementos da lista. Se encontrarmos um número, simplesmente aplicamos a função de nível de aninhamentod
ao número.fonte
APL (Dyalog) , 44 bytes *
Função de prefixo tácito anônimo. Toma a lista de APL aninhada como argumento e retorna uma matriz de APL aninhada.
Experimente online!
{
…}
Aplique a seguinte função explícita em que o argumento é representado por⍵
:⎕JSON⍵
converter o argumento para JSONj←
armazenar emj
'[]'∘.=
tabela em quej
é igual a colchetes abertos (linha superior) e fechados (linha inferior)-⌿
linha superior menos linha inferior (redução da diferença vertical)+\
soma cumulativa (isso fornece o nível de aninhamento para cada personagem)(
…)⊆
Partição, iniciando uma nova partição sempre que um 1 não é precedido por um 1 em…j∊⎕D
onde cada caracterej
é um membro do conjunto de D igits⊃¨
escolha o primeiro de cada (isso fornece o nível de aninhamento por número de vários dígitos)∊{
...}¨
aplicar a seguinte função para cada nvel de encadeamento (⍵
), usando o elemento correspondente do ε nlisted (achatada) argumento como argumento esquerda (⍺
):,⍺
percorrer (listificar) o número (porque os escalares não podem ser incluídos)⊂⍣⍵
incluir⍵
horários⊃
divulgar (porque a própria lista mais interna é um gabinete)* Usando o Dyalog Classic com
⎕ML←3
(padrão em muitos sistemas), substituindo⊂
por⊆
e↑
para⊃
. Tio!fonte