En este desafío, su tarea es crear un programa que tome una matriz anidada y devuelva una matriz plana unidimensional. Por ejemplo [10,20,[30,[40]],50]
debería salir [10,20,30,40,50]
.
Entrada
La entrada será una matriz anidada (p. Ej. [10,20,[[[10]]]]
). Contendrá solo números enteros (negativos y positivos), cadenas y matrices. Puede tomar la entrada como argumento de función, STDIN o lo que se adapte a su idioma. Puede suponer que la matriz de entrada no tendrá una matriz vacía.
Salida
La salida será una matriz unidimensional plana con los mismos elementos del mismo tipo que en la matriz anidada y en el MISMO orden.
Casos de prueba
[10,20,30] -> [10,20,30]
[[10]] -> [10]
[["Hi"],[[10]]] -> ["Hi",10]
[[[20],["Hi"],"Hi",20]] -> [20,"Hi","Hi",20]
[[["[]"],"[]"]] -> ["[]","[]"]
No dude en solicitar cualquier aclaración mediante el uso de comentarios. Este es el código de golf , por lo que gana el código más corto en bytes.
Nota: Si su idioma contiene una función incorporada para esto, NO debe usarlo.
Editar
Incluya también un enlace a un sitio web donde se pueda ejecutar su código.
unflatten
pregunta pero ningunaflatten
pregunta sobre PPCG.["[",[["[",],'[',"['['"]]
como caso de prueba.'
y"
como delimitadores. (Pero estoy de acuerdo que involucra a un caso de prueba[
,]
,"
y\
dentro de una cadena sería útil.)Respuestas:
K, 3 bytes
Este es un idioma bastante común. "Unirse sobre converger".
Pruébalo aquí con OK .
Cómo funciona:
Join (
,
) fusiona átomos o listas para producir una lista. Over (/
) toma un verbo (en este caso, join) y lo aplica entre cada elemento de una lista, de izquierda a derecha. Por lo tanto, el compuesto,/
aplanará todos los elementos de nivel superior de la lista. El símbolo en/
realidad tiene diferentes significados dependiendo de la valencia (número de argumentos) del verbo con el que está compuesto. Cuando proporcionamos,/
como verbo, el final/
actúa como "converger": se aplica repetidamente,/
a la entrada hasta que deja de cambiar. Algunos otros idiomas llaman a una característica como esta un "combinador de punto fijo". Al fusionar repetidamente las listas de nivel inferior, finalmente llegará a una sola lista plana, y ninguna de las operaciones perturbará el orden de los elementos. Esto parece resolver el problema.fuente
JavaScript (ES6), 35 bytes
Inspirado por la respuesta de @ user81655 :
fuente
Mathematica,
1614 bytesUna función sin nombre que toma y devuelve una lista, por ejemplo:
Explicación
¡Fiesta de azúcar sintáctica!
Para entender cómo funciona este, nota que cada expresión en Mathematica es o bien un átomo (por ejemplo, números, cadenas, símbolos) o una expresión compuesto de la forma
f[a, b, c, ...]
, en dondef
,a
,b
,c
son en sí mismas expresiones arbitrarias. Aquí,f
se llama la cabeza de la expresión. Todo lo demás además de eso es solo azúcar sintáctico. Por ejemplo,{a, b, c}
es justoList[a, b, c]
.Comenzamos con
//@
qué asigna una función en todos los niveles de una lista. Por ejemplo:Tenga en cuenta que esto asigna
f
sobre átomos, así como expresiones compuestas. Lo que estamos buscando ahora es una forma de deshacernos de los encabezados de la lista y conservar todo lo demás.La
Apply
función se usa normalmente para alimentar los elementos de una lista como argumentos separados para una función, pero su definición real es más general y simplemente reemplaza el encabezado de una expresión. Por ejemplo,Apply[g, f[a, b]]
dag[a, b]
.Ahora hay una "cabeza" especial llamada
Sequence
que simplemente desaparece. Por ejemplo,{a, Sequence[b, c], d}
solo evalúa a{a, b, c, d}
. La idea para aplanar la lista es reemplazar los encabezados de todas las listas internas con elSequence
fin de que salpiquen en su lista circundante. Entonces, lo que queremos esApply
encabezarSequence
las listas. Convenientemente, si hacemosApply
algo con un átomo, simplemente deja el átomo sin cambios, por lo que no tenemos que distinguir entre tipos de expresiones.Finalmente, hay un pequeño problema:
f
también se aplica al nivel más externo, de modo que también elimina el más externoList
, que no queremos. La forma más corta de contrarrestar eso es simplemente envolver el resultado en una lista nuevamente, de modo que el entornoSequence
pueda desaparecer de forma segura.Tenga en cuenta que no hay
Apply
niSequence
en el código.@@
es una forma de operadorApply
y##&
es un truco de golf estándar para acortar el largo nombre incorporadoSequence
. Entonces, ungolf todo un poco, obtenemos algo como:Para obtener más detalles sobre cómo y por qué
##&
funciona, consulte la sección "Secuencias de argumentos" en mi respuesta para los consejos de Mathematica .fuente
//@
. Muy útil para saber!//@
captura un patrón ordenado. Me recuerda un poco a algunos de los combinadores recursivos de Joy. ¿Tiene un enlace a una buena referencia a alguna función relacionada en Mathematica? Estoy muy interesado en formas de factorizar la recursividad explícita de los programas.Map
,MapAt
,Apply
, así comoReplace
y las funciones relacionadas. En general, aunque hay muchas funciones que toman un parámetro opcional de especificación de nivel (vea mi solución original de 16 bytes), que le permite aplicar la función en múltiples / todos los niveles a la vez.Python 2, 43 bytes
En una lista, recurre a los elementos y concatena los resultados. En una cadena o número, se encierra en una lista singleton.
Desafortunadamente, el pedido de Python 2 para los tipos de
int < list < string
sándwicheslist
entre los demás, requiere dos desigualdades para verificar. Por lo tanto, en cambio,l*0
se verifica con la lista vacía[]
, de lo contrario se da0
o""
.fuente
Ruby,
434234 bytesSolución recursiva. ¡Ahora con manejo excepcional! (aunque también podría dar crédito a @akostadinov por inspirar el cambio)
IDEOne enlace
fuente
rescue
asítry
bloque, por lo que puedes usarlobegin
para diferenciar las partes que quieres atrapar y las que no. Entonces, dado que estás atrapando todo el resto del bloque antes, ¿técnicamente no lo necesitas? El resto es solo espacios en blanco recortados, ya que Ruby interpreta la línea como...inject(:+) rescue [a]
a = raise("haha") rescue 1
, asignaría1
aa
. Es 'rescue
, como hay una líneaif
ywhile
.JavaScript (ES6), 41 bytes
fuente
Perl 6 , 24 bytes
Explicación:
Prueba:
fuente
Haskell, 43 bytes
Haskell no tiene listas anidadas con diferentes profundidades de las sublistas ni tipos mixtos para los elementos de la lista. Para anidar, defino un tipo de datos personalizado
D
que es una hojaL
que contiene algún elemento o un nodoN
que es una lista deD
s. Para los elementos mixtos, uso el tipo de datos predefinidoEither
que combina dos tipos en uno, aquíEither String Integer
. El nuevo tipoD
y la función de aplanamientof
son totalmente polimórficos en el tipo de elementos de la hoja, por lo que no tengo que tener mucho cuidado con nada al respectoEither
.Ejemplo 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]
.fuente
Pyth,
765 bytesPruébelo en línea: Demostración o conjunto de pruebas
Pero, por supuesto, también hay una función integrada, que maneja la tarea en solo 2 bytes:
.n
( Test Suite )fuente
G
implícitamente, si no lo escribo.JavaScript (Firefox 30-57), 43 bytes
Solo porque incluso podría evitar usarlo
concat
.fuente
[for(of)]
solo está disponible en Firefox 30+. Se propuso para ES7 pero luego se descartó.for(__ in __)
Perl,
3429 bytesFunciones
Si necesita aplanarse para enumerar como
my @a = f(@a)
, 29 bytes:Pruébalo en Ideone
Si necesita aplanarse para hacer referencia a la matriz
my $a = f($a)
, 34 bytes:Pruébalo en Ideone .
Perl 5.22.0+, 27 bytes
Gracias a hobbs .
Si necesita aplanarse para mostrar como
my @a = f(@a)
, 27 bytes:Pruébalo en JDoodle
Si necesita aplanarse a la referencia de matriz
my $a = f($a)
, 32 bytes:Pruébelo en JDoodle .
fuente
?@{f@$_}:
debería funcionar en lugar de?@{f(@$_)}:
ahorrar dos bytes.f
es una función porquef
aún no se ha declarado.sub f{}sub f{... f@$_ ...}
trabajando.ref
no necesita que los parens funcionen, ahorrando 2 bytes. 2. Hasta donde puedo ver,sub f{map{ref?f(@$_):$_}@_}
está dentro de las reglas y guarda otros 5.f
toma una matriz (no ref) como una lista, por lo que puede devolver lo mismo.ref
entonces el compilador supone que?
está comenzando a?PATTERN?
funcionar comoref(?PATTERN?)
. Entonces el compilador busca en segundo lugar?
y arroja un error.?PATTERN?
fue eliminado en 5.22.0 (m?PATTERN?
todavía funciona) y estoy probando en una versión reciente. Entonces puede obtener esos dos bytes especificando 5.22+.Julia, 29 bytes
Esto es salpicaduras recursivas en una función concatenada hasta llegar a un punto fijo. Ejemplo
fuente
Retina , 30 bytes
Pruébalo en línea!(La primera línea solo se usa para ejecutar múltiples casos de prueba a la vez).
Retina no tiene ningún concepto de matrices, literales de cadena o números, por lo que decidí ir con un formato de entrada "común" de
[...,...]
matrices de estilo y"
cadenas delimitadas, donde\
se puede usar dentro de las cadenas para escapar de cualquier carácter (en particular"
y en\
sí mismo).El programa en sí mismo simplemente combina una cadena completa o un corchete, y los reemplaza con los
$1
que mantienen las cadenas y eliminan los corchetes. El límite1>
omite la primera coincidencia para que no eliminemos el inicio[
. Sin embargo, esto elimina el final]
, por lo que lo agregamos nuevamente en una etapa separada.fuente
Pyke, 11 bytes
Pruébalo aquí!
Explicación:
O 7 bytes después de una corrección de errores.
Pruébalo aquí!
Explicación:
O incluso 2 bytes si está permitida la impresión en stdout (esto podría estar incluido en los elementos integrados)
Pruébalo aquí!
Esto aplica profundamente la
print_newline
función a cada elemento que no sea de secuencia en la entrada y se repite para los elementos de secuencia.fuente
Java (v8)
390276 bytesSolo por lo completo y todo eso. :) No puedo decir que el código de Java sea eficiente.
fuente
oaf
ao
, y cambiarflatten
af
.final
s, todo puede ser una lambda, no necesitaspublic static
...false
con1>2
, y 2 bytes adicionales que podría obtener si declara n pero no define (el compilador lo define automáticamente como 0)Python, 57 bytes
Pruébelo en línea: Python 2 , Python 3
Gracias a Kevin Lau por el
list==type(x)
truco.fuente
type(x)==list
es más corto queisinstance(x,list)
.[`x`>'['and...
? (Eso funciona solo en Python 2).Rubí
hay incorporado
flatten
método .Puedes correr aquí: http://www.tutorialspoint.com/execute_ruby_online.php
Uno de 43 bytes, pero pensó compartir:
Uno de 45 bytes que es más eficiente que el anterior y el otro rubí responde:
Aquí está el punto de referencia:
resultado:
fuente
Note: If your language contains a built-in for this, then you must NOT use it
.rescue
rescue
parece ser bastante lento por cierto, comotry/catch
en JavaPerl,
3934 + 1 (-p
bandera) 35 bytesUn trazador de líneas. Inspirado por Martin Büttner .
Pruébalo en Ideone .
fuente
Clojure, 68 bytes
mapcat
primero aplica la función a cada elemento y luego concatena los resultados. Entonces, cada vez que concatena se pierde un 'nivel de anidación'. Concat no funciona en secuencias no, por lo que los elementos deben envolverse en vectores si no son vectores.Puedes probarlo aquí: http://www.tryclj.com
fuente
ANSI C, 193 bytes
:-/, ¿alguna sugerencia? Por cierto, intenté encontrar una fuente en línea para compilar esto, pero el WL es estricto para este código. Funcionará para VS y gcc de lo contrario.
fuente
JavaScript 20 bytes
La matriz + matriz es igual a array.toString
fuente
a
es un argumento de la función. Intentaré editar la función ahora.a=>
al comienzo de su código.C #, 48 bytes
Pensé que también lo publicaría ya que nadie ha dado una solución C # todavía. Sugerencias bienvenidas!
fuente
i
inicializa? y estás seguro de que funciona en el[["[]"],"[]"]
ejemplo?i=>$"{i.Replace("[","").Replace("]","")}"
?Raqueta, 63 bytes
fuente
Java 8 165 caracteres
Sin golfista en una clase:
Esta respuesta se basa en el enfoque de Jeremy Harton . Lo usé, lo cambié en algunos lugares y creé una versión más similar al golf.
fuente
JavaScript, 17 bytes
¡Finalmente, las conversiones de tipos de JavaScript se pueden usar bien! Tenga en cuenta que esto realmente generará una matriz, pero la conversión de cadenas (ponerla en HTML) hace que se convierta en una lista separada por comas.
Si las listas separadas por comas son resultados aceptables, entonces lo siguiente es válido:
7 bytes
NOTA: el fragmento está roto por alguna razón
fuente
["["]
... Intenté ejecutar(a=>eval(
[$ {a}]))(["["])
y obtuve unSyntaxError
oninput
evento con unbutton
clic.PHP, 73 bytes
fuente
Adjunto , 14 bytes
Pruébalo en línea!
Afortunadamente, Attache tiene un operador de "vectorización", que aplica una función en los átomos de una lista. En este caso, todo lo que tenemos que hacer es configurar un segador con
Reap
ySow
todos los átomos de la entrada_
con@>
. Creo que es bastante elegante.Alternativas
15 bytes:
Fixpoint{`'^^_}
16 bytes:
Fixpoint!&Concat
17 bytes:
{q:=[]q&Push@>_q}
17 bytes:
Fixpoint[&Concat]
fuente
Elixir , 74 bytes
Primera respuesta de Elixir, por lo que probablemente se pueda jugar un poco al golf.
Pruébalo en línea.
Explicación:
Por supuesto, si se permitieran las incorporaciones, esto podría haber sido 25 bytes en su lugar:
Pruébalo en línea.
fuente
Jalea , 4 bytes
Pruébalo en línea!
Explicación
Incorporado
F
sería un byte si está permitido.fuente
Wolfram Language (Mathematica) , 13 bytes
Pruébalo en línea!
Sin golf:
F[x_] := Level[x, {-1}]
selecciona los elementos de la estructura en el último nivel de su forma de árbol . No estoy seguro de que esto cuente como "evitar la construcción" (que sería
Flatten
).fuente