Nota: Este es el # 2 en una serie de desafíos de manipulación de matrices . Para el desafío anterior, haga clic aquí .
Separar listas anidadas
Para separar los valores en una lista anidada, aplánelo y luego ajuste cada valor para que tenga la misma profundidad anidada que antes.
Es decir, esta lista:
[1, [2, 3], [4, 4, [5, 2], 1]]
Se convertiría:
[1, [2], [3], [4], [4], [[5]], [[2]], [1]]
El reto
Su tarea es escribir un programa que tome cualquier lista anidada de enteros positivos (dentro de los límites de su idioma) y realice esta operación de separación.
Puede enviar una función que tome la lista como argumento o un programa completo que realice E / S.
Como se trata de código de golf , ¡el envío más corto (en bytes) gana! *
* Las lagunas de golf estándar están prohibidas. Ya sabes que hacer.
Casos de prueba
Las listas de entrada solo contendrán enteros en el tamaño entero estándar de su idioma. Para evitar las restricciones de los idiomas que les impiden competir, los valores no se anidarán a profundidades de más de 10.
Puede suponer que la entrada no tendrá sublistas vacías: por ejemplo [[5, []]]
, no se dará. Sin embargo, la lista principal podría estar vacía.
[] -> []
[[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]
No dude en dejar un comentario si me he perdido un caso de esquina.
Ejemplo
Tiré juntos una solución rápida Python (ungolfed) 3 como ejemplo - se puede probarlo en repl.it .
fuente
Respuestas:
Brachylog , 16 bytes
Pruébalo en línea!
Explicación
fuente
Z
argumento sobre TIO? Sin él, esto parece salir con verdadero / falso, lo que hace que parezcaZ
necesario en el recuento de bytes.Z
le dice a Brachylog que el argumento de salida es una variable. Esta es esta variable que se unifica con la salida resultante. Cuando lo elimina, le indica a Brachylog que la salida es una variable anónima y, en cambio, imprimirá si el predicado principal tiene éxito o falla. Esto es lo mismo que en Prolog, donde el resultado se "pone" en una variable.Mathematica,
2421 byteso uno de estos:
Explicación
La razón por la que esto es tan breve es que es básicamente una recursión que no requiere un caso base explícito.
Aquí hay mucha azúcar sintáctica, así que comencemos por desvelar esto.
&
denota una función sin nombre a la izquierda, cuyo argumento se escribe como#
. Dentro de esta función se#0
refiere a la función misma, que le permite a uno escribir funciones recursivas sin nombre. Pero comencemos dando un nombre a la función interna y sacándola:El otro azúcar sintáctico importante es el
f/@x
que es la abreviatura de,Map[f, x]
es decir, invocaf
todos los elementos dex
. La razónf[x_] := ... f /@ x
no conduce a una recursión infinita es que mapear algo sobre un átomo deja el átomo sin cambios sin realmente llamar a la función. Por lo tanto, no necesitamos verificar el caso base (el elemento actual es un entero) explícitamente.Entonces, la función
f
recurre primero a la lista más profunda dentrox
, en cuyo punto sef/@
convierte en un no-op. Luego llamamos al uso##& @@ List /@
de eso. La asignaciónList
sobre la lista simplemente envuelve cada elemento en una lista separada, por lo que se{1, 2, 3}
convierte{{1}, {2}, {3}}
. Luego lo aplicamos##&
, lo que significa que la cabeza (es decir, la lista externa) se reemplaza por##&
, por lo que esto se convierte en##&[{1}, {2}, {3}]
. Pero##&
simplemente devuelve sus argumentos como unSequence
(que se puede considerar como una lista sin envolver, o una especie de operador "splat" en otros idiomas).Por lo tanto,
##& @@ List /@
convierte una lista{1, 2, 3}
en{1}, {2}, {3}
(más o menos, esa última cosa está realmente envuelta en la cabezaSequence
, pero desaparece tan pronto como usamos el valor en cualquier lugar).Eso deja la pregunta de por qué
f
ya no es la solución al desafío. El problema es que la lista más externa debe tratarse de manera diferente. Si tenemos aportes{{1, 2}, {3, 4}}
queremos{{1}, {2}, {3}, {4}}
y no{{1}}, {{2}}, {{3}}, {{4}}
. Mi solución original fijado esto pasando el resultado final como una lista de argumentos paraJoin
que restaurar el nivel externo de las listas, pero éste sólo se salta el nivel externo mediante el uso def
sí mismo en un mapa en la salida. Porf
lo tanto, solo se aplica a los elementos individuales de la lista más externa y nunca toca esa lista.En cuanto a las otras tres soluciones, la primera simplemente aplica la recursión fuera de la
f
cual funciona igual de bien. Las otras dos soluciones evitan unaMap
operación repetida componiendo primero dos funciones y luego mapeando el resultado solo una vez.fuente
J ,
1918 bytesEste es un verbo anónimo que toma y devuelve matrices en caja, que son la versión J (bastante engorrosa) de matrices anidadas. Véalo pasar todos los casos de prueba.
Explicación
Esto utiliza las operaciones algo exóticas
{::
( mapa ) yS:
( propagación ), que operan en matrices en caja.{::
reemplaza cada hoja con el camino encuadrado a esa hoja.S:
aplica un verbo dado a una profundidad de anidamiento dada, luego divide los resultados en una matriz.fuente
R, 199 bytes
Esta pregunta fue DURA. Las listas de R son un poco extrañas y no es absolutamente sencillo recorrer todos los elementos de las sublistas. Tampoco es sencillo determinar la profundidad de esa lista. Luego, el desafío es recrear la lista con todos los elementos separados, por lo que también necesitamos una forma de crear adaptativamente una lista de cierta profundidad.
La solución consta de dos grandes partes. Una función recursiva que recorre todas las listas y registra la profundidad:
Cuando tenemos las profundidades de cada entrada del vector
unlist(l)
, almacenadasd
, creamos implícitamente una listalapply
y la llenamos con la siguiente función:En esta llamada de solicitud, creamos un objeto
q
con el valor de la entrada en la lista, verificamos su profundidad y vemos si no es cero. Si es cero, podemos dejarlo como un valor numérico. Si no es cero, debemos anidarlo en esa cantidad de listas. Entonces llamamos ad
tiempos for-loop y repetidamente llamamosq=list(q)
.lapply
luego pone todos estos valoresq
en una lista, creando la salida deseada.Programa completo con espaciado adecuado y tal:
fuente
is.list(y)
en lugar declass(y)=='list'
? no puedo verificar que eso realmente funcione.Retina , 34 bytes
Pruébalo en línea!
fuente
(?<-2>)
trabajo?C (gcc), 147 bytes
Entrada de ejemplo:
Salida de ejemplo:
fuente
apilada , no competitiva, 25 bytes
Esta es una función porque modifica el miembro superior de la pila. Si desea una función de buena fe, simplemente agregue
[
y]
al principio y al final. Pruébalo aquí!Aquí hay una versión legible:
Caso de prueba:
Salida sin líneas nuevas:
fuente
*
como argumento para bloquear el código?d-1
tiempos de discusión .$func
Es una función que puede ser manipulada.PHP,
10194 bytesahorré 1 byte gracias a @Christoph, salvé otros 6 inspirados por eso.
función recursiva, bastante sencilla
Descompostura
fuente
$r
obtiene elementos en el bucle o la función devuelve una matriz vacía. Puede generar avisos, pero estos no se imprimen con la configuración predeterminada.!cos()
.cos()
devuelvenull
para cada matriz y un flotante! = 0 para cada entero positivo. Quiero decir ... ¿a quién le importan las advertencias?is_int
: invertir la condición no guarda nada; Necesito un espacio entreelse
yforeach
. PERO:$b[0]
para un entero esNULL
.Python 2,
122106bytesPuntaje bastante terrible, solo una implementación sencilla.
¡Gracias a @Zachary T por ayudar a ahorrar 16 bytes!
Llame
x
con un argumento para ejecutar. Por alguna razón, solo se puede ejecutar una vez.fuente
a+=[n(l,d)]
aa+=n(l,d),
(tenga en cuenta la coma final)t
?n
a la función y eliminar el primer argumento, ya que siempre será asíl
.JavaScript (Firefox 30-57), 53 bytes
La mejor respuesta de ES6 que tengo hasta ahora es de 76 bytes:
fuente
f=
.Pyth - 29 bytes
Test Suite .
fuente
Perl 6 ,
6047 bytes( Pruébelo en línea )
Explicación:
[... for |$^a]
: Itere sobre la matriz de entrada y construya una nueva matriz a partir de ella.$_ ~~ List ?? ... !! ...
: Para cada elemento, verifique si es en sí mismo una matriz.|([$_] for .&f)
: Si el elemento es una matriz, aplíquele recursivamente la función, repita los elementos de la nueva matriz devuelta por esa llamada recursiva, ajuste cada elemento en una matriz propia y deslícelos en la lista externa.$_
: Si el elemento no es una matriz, pásalo como está.fuente
Haskell, 71 bytes
Nuevamente, tengo que definir mi propio tipo de lista, porque las listas nativas de Haskell no se pueden anidar arbitrariamente. Este nuevo tipo
L
se puede devolver desde una función pero no se puede imprimir de forma predeterminada, por lo que para ver un resultado defino unashow
instancia paraL
:Ahora podemos hacer alguna prueba en el REPL:
Cómo funciona: una recursión simple que pasa el nivel de anidación en función de los
C
constructores. Comenzamos con la función de identidadid
y cada vez que hay una lista (-> coincidencia de patrónd#C l=
) agregamos una capa adicional deC
(->C .pure.d
) a la llamada recursiva de#
todos los elementos de la lista. Si encontramos un número, simplemente aplicamos la función de nivel de anidamientod
al número.fuente
APL (Dyalog) , 44 bytes *
Función de prefijo tácito anónimo. Toma la lista APL anidada como argumento y devuelve una matriz APL anidada.
Pruébalo en línea!
{
…}
Aplique la siguiente función explícita donde el argumento está representado por⍵
:⎕JSON⍵
convertir el argumento a JSONj←
almacenar enj
'[]'∘.=
tabla dondej
es igual a los corchetes abiertos (fila superior) y cerrados (fila inferior)-⌿
fila superior menos fila inferior (reducción de diferencia vertical)+\
suma acumulativa (esto da el nivel de anidación para cada personaje)(
...)⊆
partición, comenzando una nueva partición siempre que un 1 no esté precedido por un 1 en ...j∊⎕D
donde cada personaje dej
es un miembro del conjunto de D igits⊃¨
elija el primero de cada uno (esto proporciona un nivel de anidación por número de varios dígitos)∊{
...}¨
aplique la siguiente función a cada nivel de anidamiento (⍵
), utilizando el elemento correspondiente del argumento ϵ nistado (aplanado) como argumento izquierdo (⍺
):,⍺
descifrar (enumerar) el número (porque los escalares no se pueden encerrar)⊂⍣⍵
adjuntar⍵
tiempos⊃
revelar (porque la lista más interna es en sí misma un recinto)* Uso de Dyalog Classic con
⎕ML←3
(predeterminado en muchos sistemas), sustituyendo⊂
por⊆
y↑
para⊃
. Tio!fuente