Nesse desafio, sua tarefa é criar um programa que utilize uma matriz aninhada e retorne uma matriz achatada unidimensional. Por exemplo [10,20,[30,[40]],50]
deve saída [10,20,30,40,50]
.
Entrada
A entrada será uma matriz aninhada (por exemplo [10,20,[[[10]]]]
). Ele conterá apenas números inteiros (negativos e positivos), seqüências de caracteres e matrizes. Você pode usar a entrada como argumento de função, STDIN ou o que for mais adequado ao seu idioma. Você pode assumir que a matriz de entrada não terá uma matriz vazia.
Saída
A saída será uma matriz unidimensional plana com os mesmos elementos do mesmo tipo que na matriz aninhada e na mesma ordem.
Casos de teste
[10,20,30] -> [10,20,30]
[[10]] -> [10]
[["Hi"],[[10]]] -> ["Hi",10]
[[[20],["Hi"],"Hi",20]] -> [20,"Hi","Hi",20]
[[["[]"],"[]"]] -> ["[]","[]"]
Sinta-se à vontade para solicitar esclarecimentos usando comentários. Isso é código-golfe , então o código mais curto em bytes vence!
Nota: Se o seu idioma contiver um built-in para isso, você NÃO deve usá-lo.
Editar
Inclua também um link para um site em que seu código possa ser executado.
fonte
unflatten
pergunta, mas nenhumaflatten
pergunta sobre o PPCG.["[",[["[",],'[',"['['"]]
como um caso de teste.'
e"
como delimitadores. (Mas eu concordo que um caso de teste envolvendo[
,]
,"
e\
dentro de uma string seria útil.)Respostas:
K, 3 bytes
Este é um idioma bastante comum. "Juntar sobre convergir".
tente aqui com oK .
Como funciona:
Join (
,
) funde átomos ou listas para produzir uma lista. Over (/
) pega um verbo (neste caso, junte-se) e o aplica entre cada elemento de uma lista, da esquerda para a direita. Assim, o composto,/
achatará todos os elementos de nível superior da lista. O símbolo,/
na verdade, tem significados diferentes, dependendo da valência (número de argumentos) do verbo com o qual é composto. Quando fornecemos,/
como verbo, o final/
age como "convergir" - ele se aplica repetidamente,/
à entrada até que pare de mudar. Alguns outros idiomas chamam um recurso como este de "combinador de ponto fixo". Ao fundir repetidamente as listas de nível inferior, você chegará a uma única lista plana e nenhuma das operações perturbará a ordem dos elementos. Isso parece resolver o problema.fonte
JavaScript (ES6), 35 bytes
Inspirado na resposta de @ user81655 :
fonte
Mathematica,
1614 bytesUma função sem nome que pega e retorna uma lista, por exemplo:
Explicação
Festa sintática do açúcar!
Para entender como isto funciona, nota que cada expressão em Mathematica é ou um átomo (por exemplo, números, símbolos, cordas) ou um composto de expressão a forma
f[a, b, c, ...]
, ondef
,a
,b
,c
são eles próprios expressões arbitrárias. Aqui,f
é chamado a cabeça da expressão. Tudo o resto é apenas açúcar sintático. Por exemplo,{a, b, c}
é justoList[a, b, c]
.Começamos com o
//@
qual mapeia uma função em todos os níveis de uma lista. Por exemplo:Observe que este mapas
f
átomos e expressões compostas. O que estamos procurando agora é uma maneira de se livrar das listas e manter todo o resto.A
Apply
função é normalmente usada para alimentar os elementos de uma lista como argumentos separados para uma função, mas sua definição real é mais geral e simplesmente substitui a cabeça de uma expressão. Por exemplo,Apply[g, f[a, b]]
dág[a, b]
.Agora há uma "cabeça" especial chamada
Sequence
que simplesmente desaparece. Por exemplo,{a, Sequence[b, c], d}
apenas avalia como{a, b, c, d}
. A idéia de achatar a lista é substituir os cabeçalhos de todas as listas internas por,Sequence
para que eles sejam divididos em sua lista circundante. Então, o que queremos éApply
chegarSequence
às listas. Convenientemente seApply
algo com um átomo, ele apenas o deixará inalterado, para que não tenhamos que distinguir os tipos de expressões.Finalmente, há um pequeno problema:
f
também é aplicado ao nível mais externo, para que também remova o mais externoList
, o que não queremos. A maneira mais curta de combater isso é simplesmente agrupar o resultado em uma lista novamente, de modo que os arredoresSequence
possa desaparecer com segurança.Observe que não há nem
Apply
nemSequence
no código.@@
é uma forma de operadorApply
e##&
é um truque de golfe padrão para encurtar o longo nome internoSequence
. Então, desenredando tudo um pouco, temos algo como:Para mais detalhes sobre como e por que
##&
funciona, consulte a seção "Sequências de argumentos" na minha resposta para obter as dicas do Mathematica .fonte
//@
. Muito útil para conhecer!//@
captura um padrão elegante. Me lembra um pouco de alguns dos combinadores recursivos no Joy. Você tem um link para uma boa referência a funções relacionadas no Mathematica? Estou muito interessado em maneiras de levar em consideração a recursão explícita dos programas.Map
,MapAt
,Apply
, bem comoReplace
e funções relacionadas. Em geral, embora haja muitas funções que usam um parâmetro levelspec opcional (consulte minha solução original de 16 bytes), que permite aplicar a função em vários / todos os níveis ao mesmo tempo.Python 2, 43 bytes
Em uma lista, repete-se nos elementos e concatena os resultados. Em uma sequência ou número, é envolto em uma lista de singleton.
Infelizmente, o Python 2 está solicitando tipos de
int < list < string
sanduícheslist
entre os outros, exigindo duas desigualdades para verificar. Então, em vez disso,l*0
é verificado na lista vazia[]
, caso contrário, fornece0
ou""
.fonte
Ruby,
434234 bytesSolução recursiva. Agora com manipulação de exceção! (pode muito bem acreditar no @akostadinov por inspirar a mudança)
Link IDEOne
fonte
rescue
assimtry
bloco, então você usabegin
para diferenciar as partes que deseja pegar e as que não tem. Então, como você está procurando o resto do quarteirão antes dele, tecnicamente não precisa? O resto é apenas um espaço em branco aparado, pois Ruby interpreta a linha como...inject(:+) rescue [a]
a = raise("haha") rescue 1
, atribuiria1
aa
. É 'rescue
, como há um inlineif
ewhile
.JavaScript (ES6), 41 bytes
fonte
Perl 6 , 24 bytes
Explicação:
Teste:
fonte
Haskell, 43 bytes
Haskell não possui listas aninhadas com diferentes profundidades das sublistas nem tipos mistos para os elementos da lista. Para aninhamento, defino um tipo de dados personalizado
D
que é uma folhaL
que contém algum elemento ou um nóN
que é uma lista deD
s. Para os elementos mistos, uso o tipo de dados predefinidoEither
que combina dois tipos em um, aquiEither String Integer
. O novo tipoD
e a função achatarf
são totalmente polimórficos no tipo de elementos da folha, portanto, não preciso tomar muito cuidado com nadaEither
.Exemplo de uso:
f (N[N[L(Right 20)], N[L(Left "Hi")], L(Left "Hi") , L(Right 20)])
->[Right 20,Left "Hi",Left "Hi",Right 20]
.fonte
Pitão,
765 bytesExperimente on-line: demonstração ou Test Suite
Mas é claro, também há uma função interna, que lida com a tarefa em apenas 2 bytes:
.n
( Conjunto de Testes )fonte
G
implicitamente, se eu não o escrever.JavaScript (Firefox 30-57), 43 bytes
Só porque eu poderia mesmo evitar o uso
concat
.fonte
[for(of)]
está disponível apenas no Firefox 30+. Foi proposto para o ES7, mas depois caiu.for(__ in __)
Perl,
3429 bytesFunções.
Se precisar achatar para listar como
my @a = f(@a)
, 29 bytes:Teste no Ideone
Se precisar achatar para ref da matriz
my $a = f($a)
, 34 bytes:Teste em Ideone .
Perl 5.22.0+, 27 bytes
Graças a hobbs .
Se precisar achatar para listar como
my @a = f(@a)
, 27 bytes:Teste no JDoodle
Se precisar achatar para ref da matriz
my $a = f($a)
, 32 bytes:Teste no JDoodle .
fonte
?@{f@$_}:
deveria funcionar em vez de?@{f(@$_)}:
, economizando dois bytes.f
é uma função porquef
ainda não foi declarada.sub f{}sub f{... f@$_ ...}
trabalhando.ref
não precisa do parens para trabalhar, economizando 2 bytes. 2. Tanto quanto posso ver,sub f{map{ref?f(@$_):$_}@_}
está dentro das regras e salva outras 5.f
pega uma matriz (sem ref) como uma lista, para que possa retornar o mesmo.ref
, o compilador assume que?
está iniciando a?PATTERN?
operação comoref(?PATTERN?)
. Portanto, o compilador procura o segundo?
e gera erro.?PATTERN?
was removed in 5.22.0 (m?PATTERN?
still works) and I'm testing on a recent version. So you can gain those two bytes by specifying 5.22+.Julia, 29 bytes
This is recursive splatting into a concatenate function until a reaching a fix point. Example
fonte
Retina, 30 bytes
Try it online! (The first line is only used to run multiple test cases at once.)
O Retina não tem conceito de matrizes, literais ou números de strings, então eu decidi usar um formato de entrada "comum" de
[...,...]
matrizes de estilo e"
strings -delimited, onde\
pode ser usado dentro das strings para escapar de qualquer caractere (em particular"
and\
itself).O programa em si simplesmente corresponde a uma sequência completa ou a um colchete e os substitui pelo
$1
que mantém as strings e remove os colchetes. O limite1>
ignora a primeira correspondência para que não removamos a liderança[
. No entanto, isso remove a trilha]
, então a adicionamos novamente em um estágio separado.fonte
Pyke, 11 bytes
Experimente aqui!
Explicação:
Ou 7 bytes após uma correção de bug
Experimente aqui!
Explicação:
Ou até 2 bytes se a impressão em stdout for permitida (isso pode estar incluído nos recursos internos)
Experimente aqui!
This deeply applies the
print_newline
function to every non-sequence item in the input and recurses for sequence items.fonte
Java (v8)
390276 bytesJust for completeness and all that. :) Can't say Java's code-efficient.
fonte
oaf
too
, and changeflatten
tof
.final
s, the whole thing can be a lambda, you don't needpublic static
...false
with1>2
, and additional 2 bytes you could get if you declare n but not define (compiler automatically define it as 0)Python, 57 bytes
Try it online: Python 2, Python 3
Thanks to Kevin Lau for the
list==type(x)
trick.fonte
type(x)==list
is shorter thanisinstance(x,list)
.[`x`>'['and...
? (That works in Python 2 only.)Ruby
there is builtin
flatten
method.You can run here: http://www.tutorialspoint.com/execute_ruby_online.php
One 43 bytes, but thought to share:
One 45 bytes that is more efficient than the previous and the other ruby answer:
here's benchmark:
result:
fonte
Note: If your language contains a built-in for this, then you must NOT use it
.rescue
rescue
looks to be rather slow btw, liketry/catch
in javaPerl,
3934 + 1 (-p
flag) 35 bytesOneliner. Inspired by Martin Büttner.
Test it on Ideone.
fonte
Clojure, 68 bytes
mapcat
first applies function to each element and then concats results. So every time it concats one 'nesting level' is lost. Concat does not work on not sequences so elements have to be wrapped into vector if they're not vector.You can try it here: http://www.tryclj.com
fonte
ANSI C, 193 bytes
:-/, any suggestions? Btw, I did try to find an online source to compile this but the WL is strict for this code to compile. It will work for VS and gcc otherwise.
fonte
JavaScript 20 bytes
The array + array is equal to array.toString
fonte
a
is an argument of the function. I will try to edit out the function now.a=>
to the beginning of your code.C#, 48 bytes
Thought I'd post it also since nobody has given a C# solution yet. Suggestions welcome!
fonte
i
initialized? and are you sure it works on the[["[]"],"[]"]
example?i=>$"{i.Replace("[","").Replace("]","")}"
?Racket, 63 bytes
fonte
Java 8 165 chars
Ungolfed into a class:
This answer is based on Jeremy Harton's approach. I used it changed it in some places and created a more golf-like version.
fonte
JavaScript, 17 Bytes
Finally, JavaScript's type conversions can be put to some good use! Please note that this will actually output an array, but string conversion (putting it into HTML) causes it to become a comma separated list.
If comma separated lists are acceptable output, then the following is valid:
7 Bytes
NOTE: Snippet is broken for some reason
fonte
["["]
... I tried running(a=>eval(
[${a}]))(["["])
and got aSyntaxError
oninput
event with abutton
click.PHP, 73 Bytes
fonte
Attache, 14 bytes
Try it online!
Fortunately, Attache has a "vectorization" operator, which applies a function at the atoms of a list. In this case, all we need to do is to set up a reaper with
Reap
andSow
all atoms of the input_
with@>
. I think it's quite elegant.Alternatives
15 bytes:
Fixpoint{`'^^_}
16 bytes:
Fixpoint!&Concat
17 bytes:
{q:=[]q&Push@>_q}
17 bytes:
Fixpoint[&Concat]
fonte
Elixir, 74 bytes
First Elixir answer, so can probably be golfed a bit.
Try it online.
Explanation:
Of course, if builtins were allowed, this could have been 25 bytes instead:
Try it online.
fonte
Jelly, 4 bytes
Try it online!
Explanation
Built-in
F
would be one byte if allowed.fonte
Wolfram Language (Mathematica), 13 bytes
Try it online!
Un-golfed:
F[x_] := Level[x, {-1}]
picks out the elements of the structure at the last level of its tree form. I'm not sure this counts as "avoiding the builtin" (which would be
Flatten
).fonte