Esse desafio foi inspirado por uma pergunta no Mathematica.SE .
Digamos que você tenha uma lista / matriz aninhada de alguma estrutura arbitrária (as listas em cada nível não necessariamente têm o mesmo comprimento). Para simplificar, assumiremos que os nós são números inteiros não negativos ou matrizes vazias. Como um exemplo
[[[1, 3], 2], [1, 4], 12, [[0, [], 0], [5, [7]]]]
Às vezes, é mais conveniente achatar essa lista para executar alguma manipulação dos nós, por exemplo
--> [1, 3, 2, 1, 4, 12, 0, 0, 5, 7]
--> [1, 1, 0, 1, 0, 0, 0, 0, 1, 1]
Mas, no final, você realmente deseja preservar a estrutura original, portanto, deseja transformar isso novamente em
--> [[[1, 1], 0], [1, 0], 0, [[0, [], 0], [1, [1]]]
Sua tarefa é executar o último passo.
Dada uma lista aninhada de números inteiros não negativos arbitrários, que representa a estrutura desejada do resultado, e uma lista simples de números inteiros não negativos, que representam os valores desejados, reformula a lista simples na forma da lista estruturada. Você pode assumir que ambas as listas contêm o mesmo número de números inteiros.
Como de costume, você não precisa lidar com entradas inválidas (por exemplo, a segunda lista não é plana, a entrada está sintaticamente malformada, não possui números inteiros como nós, etc.). Você pode modificar as matrizes de entrada no seu código.
Você pode escrever uma função ou programa, recebendo entradas via STDIN, argumento de linha de comando ou argumento de função, e pode retornar o resultado ou imprimi-lo em STDOUT. Você pode usar qualquer formato conveniente de lista ou sequência para representar entrada e saída (desde que o formato seja inequívoco e a entrada não seja pré-processada). Além disso, o formato de ambas as entradas precisa ser consistente (para que você não possa considerar uma entrada como uma string e a outra como uma lista, por exemplo). Você pode acessar as listas de entrada em qualquer ordem, mas especifique o método exato de entrada em sua resposta.
Mais uma restrição: você não deve usar expressões regulares. Este é um desafio de manipulação de array, não um desafio de manipulação de string.
Isso é código de golfe, então a resposta mais curta (em bytes) vence.
Casos de teste
Structure Values Result
[[[1,3],2],[1,4],12,[[0,0],[5,[7]]]] [1,1,0,1,0,0,0,0,1,1] [[[1,1],0],[1,0],0,[[0,0],[1,[1]]]]
[[[0,0],0],[0,0],0,[[0,0],[0,[0]]]] [1,1,0,1,0,0,0,0,1,1] [[[1,1],0],[1,0],0,[[0,0],[1,[1]]]]
[] [] []
[[]] [] [[]]
[0,1,2,3] [5,1,0,5] [5,1,0,5]
[[[[[0]]]]] [123] [[[[[123]]]]]
[0,[1,[]],[[]],[2,3],[]] [1,6,1,8] [1,[6,[]],[[]],[1,8],[]]
fonte
Respostas:
CJam,
18 1613 bytesRecebe entrada via STDIN no mesmo formato da resposta CJam anterior:
e gera a sequência de resultados para STDOUT
Simplesmente trato a primeira linha como string, converto todos os caracteres de dígito em novas linhas, divido em uma ou mais ocorrências de novas linhas, coloco a segunda linha como uma matriz na pilha, envolvo em uma matriz e compactamos as duas matrizes (linhas). A impressão é automática e, como a primeira linha foi tratada como string, ela mantém seus colchetes.
Expansão de código
Obrigado a @ user23013 por salvar 3 bytes.
Experimente online aqui
fonte
/La-
:%
.%
é para dividir também, e também se divide em várias ocorrências!JavaScript, ES6, 44 bytes
Isso cria uma função
f
que pode ser chamada comoou seja, a matriz aninhada e a matriz de valores como argumentos de entrada. A saída da função é a matriz aninhada convertida.
Essa é uma pergunta muito boa para recursão, é por isso que a resposta é uma função de recursão pura e agradável. Eu crio uma função
f
que converte o primeiro argumento usando omap
método Para cada elemento, se o elemento for uma matriz, ele chamaf
novamente, caso contrário, para números inteiros, obtém o i- ésimo item e o retorna, incrementando o valor dei
. O valor dei
é passado para baixo em cada chamada recursiva, para manter a ordem correta.A detecção de matriz vs. número inteiro é novamente realizada usando o
map
método Para uma variável de matriz,map
é uma função válida, enquanto para variáveis inteiras, não há propriedade ou função chamadamap
definida para a variável.Isso funciona em um navegador Firefox mais recente (devido ao ES6).
fonte
.map
no código. Existe alguma maneira de reduzi-lo ainda mais? Enfim, bom código!map
está vinculado ao contexto, portanto, o primeiro mapa pertence aa
enquanto o próximo mapa pertence a cada umx
na iteração. Não há outra maneira mais curta de se referirmap
, nem diferenciar array de números inteiros.JavaScript, ES6, 41 bytes
Fiquei realmente impressionado com a resposta do Optimizer , foi muito inteligente e aprendi muito. No entanto, ao examiná-lo, encontrei uma maneira de encurtar um pouco e corrigir um pequeno bug:
Peguei a
i
variável e a substitui por ashift()
. Isso o torna um pouco mais curto e corrige o problema com o fato dei
ser passado por valor e não por referência, o que fez com que alguns números da matriz final se repetissem e outros no final não fossem usados. Mais uma vez, a resposta do Optimizer foi muito bem pensada, melhor do que eu poderia ter feito, apenas consertei um pouco.fonte
Dyalog APL, 14 caracteres
Este é um acéfalo:
(∊a)←b
.Normalmente,
∊a
significaa
achatado, mas quando ocorre no lado esquerdo de uma tarefa, ele faz exatamente o que esse problema está pedindo. Para cumprir o requisito de ser uma função, ele precisa de alguns rabiscos extras:{a←⍺⋄(∊a)←⍵⋄a}
(chaves para lambda;⍺
e⍵
para argumentos esquerdo e direito;⋄
para separador de instruções).Teste em tryapl.org. Observe que no APL o vetor numérico vazio é indicado por
⍬
("zilde"). Os vetores de um elemento são construídos com(,A)
porque(A)
significariam um escalar. Na saída, esta coisa:representa um vetor numérico vazio. O
0
no centro mostra o "elemento prototípico", que não é um elemento da matriz.fonte
(,1)
e(1)
ou por que o bit final é apenas apresentado como em[1|1]
vez de[1|[1]]
?]box on
) não distingue entre eles. Há outra função no Dyalog (display
dedfns.dws
) que faz uma distinção, mas infelizmente o tryapl restringe o carregamento de áreas de trabalho adicionais (por exemplo, bibliotecas). :(∊{0=⍴⍴⍵:⍕⍵ ⋄ '['(∇¨⍵)']'}a
. Ou isto:∊{0=⍴⍴⍵:⍕⍵ ⋄ '['(1↓,'|',[1.5]∇¨⍵)']'}a
se você insiste no separador|
,.]display a
no tryapl. Fornece informações completas sobre a estrutura. Desculpe, eu não percebi isso no começo.Python, 51
Exemplo:
fonte
Python 2, 50
Este foi um problema muito bonito. Enquanto continuava trabalhando, percebi que bits do meu código eram desnecessários e a lógica se desmoronou em uma expressão simples. A maior parte do golfe estava em encontrar o algoritmo certo.
s
é a estrutura ev
é a lista plana da lista. A idéia é verificar ses
é um número inteiro coms<[]
(o Python 2 trata os números como menores que as listas). Se for, simplesmente pegue e retorne o primeiro elemento dev
, removendo-o dev
. Caso contrário, recorra para as sublistas des
.O
pop
é um pedaço de mágica imperativa no código de estilo muito funcional. Como todosv
apontam para a mesma instância, a remoção de um elemento de um remove-ov
em toda a árvore de execução; portanto, cada númerov
é usado apenas uma vez. A compreensão da lista[f(x,v)for x in s]
cria uma árvore de chamada que é expandida em profundidade primeiro e da esquerda para a direita, fazendo com que os elementosv
sejam colocados na ordem correta.Eu escrevi isso independentemente da resposta do grc , mas acabou sendo o mesmo para mover um único
[
(e nomes de variáveis). A mudança salva um caractere devido ao espaçamento. A mudança de colchete significa manipular o caso do nó imediatamente na função, e não como parte da compreensão da lista, que eu não havia considerado.Podemos salvar um caractere para 49 se esticarmos os requisitos de entrada para obter o valor de STDIN e a estrutura como argumento de função. Isso nos permite usar
map
.fonte
Ruby, 39
Repete-se até que o elemento na lista seja um número inteiro.
Uma vez que chamar Integer.map dá uma exceção,
ele vai para a parte de resgate, que "abre / desloca" o 1º elemento da 2ª lista.
Regex soln ... um pouco mais:
Experimente com alguns casos de teste
fonte
CJam,
43 37 3533 bytesEsta é uma conversão direta da minha resposta JS . Um pouco longo, a maioria dos quais é utilizada pela detecção de tipo.
Toma as duas matrizes de entrada em duas linhas de STDIN, como
e saídas para STDOUT como
Experimente online aqui
fonte
Haskell,
113104 bytes (86 + 18 da declaração de tipo de dados)O Haskell não possui um tipo de dados de matriz aninhada interno, então tive que rolar o meu. Por esse motivo, o programa contém apenas correspondência de padrões e recursão estrutural explícita. O último caso de teste lê
e avalia para
fonte
Mathematica, 41 bytes
Essa é uma função sem nome que assume a estrutura como o primeiro argumento e a lista de valores como o segundo argumento (e retorna uma lista).
Esta é uma versão em golfe da resposta aceita na pergunta que inspirou esse desafio. Estou postando isso eu mesmo e não aceitarei essa resposta (na verdade, ela deve permanecer a mais curta, o que duvido). Isso é para impedir que mais alguém vença o desafio, basicamente copiando a resposta.
Como funciona:
Listable
função pura. As funções listáveis são aplicadas automaticamente aos elementos de um argumento da lista (recursivamente) em vez da própria lista, portanto, chamarf
a lista estruturada basicamente retornará uma lista da mesma estrutura com cada número inteiroi
substituído porf[i]
.m
e um contadori
.f
(independentemente do argumento), retornamos o próximo elemento dem
.fonte
Rebol -
87 6660Ungolfed:
Exemplo:
fonte
C #,
225 + 13 = 239185 + 35 = 220172 + 35 = 207 bytesRequer isto:
Aceita
object[]
s como argumentos.Código não destruído:
fonte
using o=System.Object
e substituindo todas as instâncias doobject
com simplesmenteo
. msdn.microsoft.com/en-us/library/sf0df423.aspxClone
é raso. Se a modificação das entradas for permitida, você não precisará clonar. Se não for permitido, você precisará de uma clonagem adequada.Python 2, 64 bytes
Ouvi dizer que você gosta de listas em listas, por isso coloco funções em funções.
Edit: Olhando para a resposta do grc agora percebo que era completamente desnecessário. Ah bem...
fonte
SWI-Prolog 82
Exemplo de execução:
O último
[]
da consulta é para verificar o número incompatível de elementos, o que não parece ser necessário nesta pergunta.fonte
is_list
) necessários?Erlang,
11693 bytesUsa duas funções impuras
f
eg
.f
manipula o dicionário do processo configurandon
a lista simples e mapeia cada elemento da lista aninhadag(X)
.g
em seguida, definen
o final da lista simples toda vez que encontra um valor que não seja da lista e retorna o cabeçalho da lista simples.fonte
Perl 5, 49 bytes
O primeiro argumento é a estrutura do modelo, o segundo são os valores.
Programa de teste
fonte
Powershell: 115
a matriz de entrada é $ i, o mapeamento é $ m, a saída é $ o
$ h é uma string que contém a função recursiva, e você pode executar o código contido em uma string com. $ h ... E seria 30 bytes mais curto se o powershell não insistisse em achatar matrizes de valor único para escalares e uma matriz com um único valor nulo para nulo
e um visualizador de estrutura de matriz útil para verificar resultados
editar: 149
salve como unflatten.ps1:
edit: 136, criação de matriz de saída em linha e saída de gravação
ligue com. \ unflatten.ps1 [matriz de entrada] [matriz de mapeamento]
a saída é gravada no pipeline - execute isso primeiro:
e corra com
fonte
C #, (40 + 123) = 163 bytes OR (67 + 81) = 148 bytes
O C # sofre com sua digitação estática e espaços para nome longos aqui.
Método de matriz
Usando instruções:
Código:
Método Stack (usa a estrutura Stack em vez de matrizes)
Usando instruções:
Código:
Primeiras tentativas, primeiro código de golfe aqui.
fonte