Dada una matriz de cualquier profundidad, dibuje su contenido con bordes +-|
alrededor de cada submatriz. Esos son los caracteres ASCII para más, menos y tubería vertical.
Por ejemplo, si la matriz es [1, 2, 3]
, dibuje
+-----+
|1 2 3|
+-----+
Para una matriz anidada como [[1, 2, 3], [4, 5], [6, 7, 8]]
, dibujar
+-----------------+
|+-----+---+-----+|
||1 2 3|4 5|6 7 8||
|+-----+---+-----+|
+-----------------+
Para una matriz irregular como [[[1, 2, 3], [4, 5]], [6, 7, 8]]
, dibujar
+-------------------+
|+-----------+-----+|
||+-----+---+|6 7 8||
|||1 2 3|4 5|| ||
||+-----+---+| ||
|+-----------+-----+|
+-------------------+
Observe que hay más espacio después del dibujo [6, 7, 8]
. Puede dibujar el contenido en la línea superior, central o inferior, pero cualquiera que elija, debe ser coherente.
Este desafío fue inspirado por el verbo en recuadro<
de J.
Reglas
- Este es el código de golf, por lo que gana el código más corto.
- Los componentes que resuelven esto no están permitidos.
- La matriz de entrada contendrá solo valores enteros no negativos o matrices. Cada matriz será homogénea, lo que significa que sus elementos serán solo matrices o enteros, pero nunca una combinación de ambos.
- Cada submatriz puede estar anidada a cualquier profundidad.
- La salida puede ser como una cadena o como una matriz de cadenas donde cada cadena es una línea de salida.
Casos de prueba
[]
++
||
++
[[], []]
+---+
|+++|
|||||
|+++|
+---+
[[], [1], [], [2], [], [3], []]
+-----------+
|++-++-++-++|
|||1||2||3|||
|++-++-++-++|
+-----------+
[[[[[0]]]]]
+---------+
|+-------+|
||+-----+||
|||+---+|||
||||+-+||||
|||||0|||||
||||+-+||||
|||+---+|||
||+-----+||
|+-------+|
+---------+
[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]
+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|+-------+|+---+|1||
|||+---------+|||+-----+|||2 1|| ||
||||+-------+|||||3 2 1|||+---+| ||
|||||4 3 2 1|||||+-----+|| | ||
||||+-------+|||+-------+| | ||
|||+---------+|| | | ||
||+-----------+| | | ||
|+-------------+---------+-----+-+|
+---------------------------------+
-1
porque también limité los enteros para que no sean negativos. Entonces solo tendría que limpiar la salida de esos valores no válidos.Respuestas:
Dyalog APL , 56 bytes
Gracias a ngn por ayudar a eliminar aproximadamente un tercio de los bytes.
TryAPL
Defina la función , luego ejecute cada caso de prueba y compárelo con la
]Display
utilidad incorporada .[1, 2, 3]
[[1, 2, 3], [4, 5], [6, 7, 8]]
[[[1, 2, 3], [4, 5]], [6, 7, 8]]
[]
[[], []]
[[], [1], [], [2], [], [3], []]
[[[[[0]]]]]
[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]
Explicación
En general, esta es una función anónima
{...}
sobre un cerramiento⊂
. El último solo agrega otro nivel de anidación, lo que hace que el primero agregue un marco externo.La función anónima con espacios en blanco (
⋄
es el separador de sentencias):Aquí está de nuevo, pero con funciones de utilidad separadas:
Ahora déjame explicarte cada función:
CloseBox
toma una tabla y devuelve la misma tabla, pero con la primera columna de la tabla agregada a la derecha de la tabla. Por lo tanto, dada la tabla 1 por 3XYZ
, esta función devuelve la tabla 1 por 4XYZX
, de la siguiente manera:⊢
el argumento (encendido lo que está a la derecha),
antepuesto a⊣/
la columna más a la izquierda (encendido la reducción izquierda de cada fila)CreateVertical
toma una tabla y devuelve una cadena que consta de los caracteres que encajarían|
en los lados de la tabla, pero con dos+
s antepuestos para que coincidan con dos filas de-
. Finalmente, la tabla se rotará cíclicamente una fila para obtener una sola+---...
fila arriba y abajo. Por lo tanto, dada cualquier tabla de tres filas, esta función regresa de la++|||
siguiente manera:'++' ,
dos ventajas más antepuestas a'|' ⍴⍨
un estilo reformado por≢
la cuenta (filas) del argumentoAddHorizontals
toma una lista de listas, la convierte en una tabla, agrega dos filas de-
s en la parte superior, agrega los caracteres de borde izquierdo correspondientes a la izquierda, luego gira una fila hacia abajo, de modo que la tabla tenga un borde en la parte superior , izquierda y abajo. De la siguiente manera:1 ⊖
gire una fila (la fila superior va al final) deCreateVertical ,
la cadena++|||...
antepuesta (como una columna) para'-' ⍪⍣2
agregar menos dos veces a la parte superior del↑
argumento transformado de la lista de listas a la tabla{
La función anónima}
: si el argumento es una lista simple (no anidada), conviértala en una tabla de caracteres (por lo tanto, dada la lista de 3 elementos1 2 3
, esta función devuelve la tabla de caracteres visualmente idéntica de 1 por cinco1 2 3
). Si el argumento no es una lista simple, asegúrese de que los elementos sean tablas de caracteres simples; acolcharlos a la misma altura; enmarca cada uno en su parte superior, inferior e izquierda; combinarlos y finalmente tome la primera columna y agréguela a la derecha. De la siguiente manera:{
comience la definición de una función anónima⍵ ≡ ∊⍵:
si el argumento es idéntico al argumento aplanado (es decir, es una lista simple), luego:⍉
transponga el argumento⍪
stringificado⍉
transpuesto en⍕ ⍵
columnas; más:CloseBox
agregue la columna más a la izquierda a la derecha de⊃ ,/
losAddHorizontals¨
agregados revelados (porque la reducción encierra) se concatenan-
en la parte superior e inferior de cada una de↓ ↑ ↓¨
las∇¨ ⍵
funciones acolchadas a la misma altura * de esta función anónima aplicada a cada uno de los argumentos}
finaliza la definición de la función anónima* Lit. convierta cada tabla en una lista de listas, combine las listas de listas (relleno con cadenas vacías para llenar filas cortas) en una tabla, luego divida la tabla en una lista de listas de listas
fuente
JavaScript (ES6),
223203 bytesPuerto de la solución Ruby de @ MitchSchwartz. Versión anterior que funcionaba envolviendo recursivamente las matrices (y, por lo tanto, funcionaba para contenido arbitrario, no solo enteros):
Nota: Aunque estoy usando el operador de propagación en mi lista de argumentos, para obtener el resultado deseado, proporcione un único parámetro de la matriz original en lugar de intentar distribuir la matriz; Esto tiene el efecto de envolver la salida en el cuadro exterior deseado. Lamentablemente, la caja externa me cuesta 18 bytes, y la separación del espacio de los enteros me cuesta 8 bytes, de lo contrario la siguiente visualización alternativa sería suficiente para 197 bytes:
fuente
Cannot read property 'map' of undefined
para matrices vacías como[]
. Para[1,2,[]]
, el último subconjunto no se muestra para mí.[1,2,[]]
porque sus ejemplos solo muestran matrices que contienen enteros o matrices, pero no ambas.Ruby, 104 bytes
Función anónima que espera una cadena. Por ejemplo,
{{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}
producePuede usar este código para probar:
Esto comienza desde la fila del medio y funciona hacia afuera. Primero, las instancias de
}{
se reemplazan con|
. Luego, si bien todavía hay llaves, todas las{...}
cadenas más internas se transforman en las+-
secuencias apropiadas , mientras que los caracteres que no sean|{}
se convierten en espacios. Al final, los tirantes intermedios se convierten en tubos.fuente
Brainfuck, 423 bytes
Formateado con algunos comentarios:
Pruébalo en línea.
Espera entradas formateadas como
(((((4 3 2 1))))(((3 2 1)))((2 1))(1))
con una nueva línea final y produce salidas de la forma:La idea básica es calcular qué personaje imprimir en función de la profundidad de anidamiento. El formato de salida es tal que el índice de fila del borde superior de un cuadro es igual a la profundidad de la matriz correspondiente, con simetría en la fila central.
La cinta se divide en nodos de 7 celdas, y cada nodo representa una columna en la salida.
El primer bucle consume la entrada e inicializa los nodos, haciendo un seguimiento de la profundidad y si la columna corresponde a un paréntesis (es decir, si la columna contiene un borde vertical), y las ocurrencias de colapso
)(
en nodos individuales.El siguiente ciclo genera una fila por iteración. Dentro de este bucle, otro bucle atraviesa los nodos e imprime un carácter por iteración; Aquí es donde tiene lugar la mayor parte del trabajo.
Durante el ciclo de inicialización, el diseño de memoria de un nodo al comienzo de una iteración es
x d 0 c 0 0 0
donde
x
es una bandera booleana para saber si el carácter anterior era un paréntesis de cierre, sid
es profundidad (más uno) y sic
es el carácter actual.Durante el ciclo de impresión de caracteres, el diseño de memoria de un nodo al comienzo de una iteración es
0 0 d1 d2 c p y
donde
d1
indica profundidad en comparación con el índice de fila para la mitad superior;d2
es similard1
pero para la mitad inferior;c
es el carácter de entrada para esa columna si es dígito o espacio, de lo contrario cero;p
indica fase, es decir, mitad superior, media o mitad inferior; yy
es una bandera que se propaga de izquierda a derecha, haciendo un seguimiento de si ya hemos llegado a la fila del medio. Tenga en cuenta que, dado que sey
convierte en cero después de procesar un nodo, podemos usar lay
celda del nodo anterior para ganar más espacio de trabajo.Esta configuración nos permite evitar calcular explícitamente la profundidad máxima durante la fase de inicialización; la
y
bandera se propaga hacia atrás para actualizar lasp
celdas en consecuencia.Hay una
-1
celda a la izquierda de los nodos para facilitar la navegación, y hay una celda a la derecha de los nodos que realiza un seguimiento de si ya hemos impreso la última fila.fuente
PHP + HTML, no compite (
170141135130 bytes)guardado 29 bytes inspirados en SteeveDroz
no compite porque no es una salida ASCII y porque dejo que el navegador haga todo el trabajo interesante
fuente
<b>
etiquetas en lugar de<div>
y no necesita especificar el color de laborder
. (Ahorro de 9 bytes)<b>
, también puedo eliminar elwhite-space
atributo, ahorrando otros 19 bytes. ¡Excelente! Y puedo reemplazarpadding
conmargin
JavaScript (ES6), 221
Una función no recursiva que devuelve una matriz de cadenas (aún utilizando una subfunción recursiva en el interior)
Esto funciona en 2 pasos.
Paso 1: construya recursivamente una representación de cadena de la matriz de entrada anidada. Ejemplo:
[[[1, 2, 3], [],[4, 5]], [6, 7, 8]]
->"OOO1 2 3,,4 5C,6 7 8CC"
O
yC
marque subarreglos de apertura y cierre. Las submatrices numéricas simples se representan con los elementos separados por espacio, mientras que si los miembros de la matriz son submatrices, se separan por comas. Esta cadena no pierde de vista la estructura de varios niveles de la matriz de entrada, mientras que yo puedo conseguir la fila del medio de la salida sólo la sustituciónOC,
con|
. Mientras construyo recursivamente esta cadena temporal, también encuentro el nivel de profundidad máxima e inicializo una matriz de cadenas vacías que contendrán la mitad de la parte superior de la salida.Nota: el cuadro externo es complicado, anido la entrada dentro de otra matriz externa, luego dejo caer la primera fila de salida que no es necesaria
Paso 2: escanee la cadena temporal y cree la salida
Ahora tengo una serie de cadenas vacías, una para cada nivel. Escaneo la cadena temporal, haciendo un seguimiento del nivel actual, que aumenta para cada uno
O
y disminuye para cada unoC
. Visualizo esto así:El plus sube y baja siguiendo el nivel actual
Para cada carácter, agrego un carácter a cada fila de salida, siguiendo las reglas:
- si es un dígito o un espacio, ponga un '-' en el nivel actual y debajo, ponga un espacio arriba
- de lo contrario, ponga un '+' en el nivel actual, ponga un '-' si está debajo y ponga un '|' si arriba
Durante el escaneo temporal, también construyo la fila del medio reemplazando
OC,
con|
Al final de este paso, tengo la mitad superior y la fila central, solo tengo que reflejar la parte superior para obtener la mitad inferior y he terminado
Menos comentado, código comentado
)
Prueba
fuente
Ruby,
245241 bytesLa sobrecarga necesaria para envolver todo en cajas y alinear todo es bastante pesada ...
Emite conjuntos de cadenas, con una cadena por línea, según la especificación. Casos de prueba de alineación inferior en lugar de alineación superior porque ahorra 1 byte.
Pruébalo en línea!
fuente
PHP, 404 bytes
Todas las soluciones funcionan con una profundidad máxima de la matriz menor que 10. para valores mayores, la profundidad debe almacenarse en una matriz y no en una cadena.
Expandido
por 425 Bytes podemos hacer esto con REGEX
Expandido
455 bytes para una solución recursiva
Expandido
fuente
$j!="]"?:$c--;
->$c-=$j=="]";
(-2). 2)($l=="]"?"":" ")
->" "[$l==$j]
(-5). Probablemente sustituciones similares en el segundo bucle. 3)if($r!=""){$n.=$r;$d.=+$c;}
->$n.=$r;if($r>"")$d.=+$c;
(-3). 4)$l=$j;$j!="["?:$c++;
->$c+="["==$l=$j;
(-5). 5)$x=0
no es necesario (-4). 6)for($y=0;$y<$m;$y++)
->for($y=$m;$y--;)
(-4). 7)join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));
->join("\n",array_merge($z,[$n],array_reverse($z)));
(-4) 8) espacios en blanco innecesarios:foreach($e[0]as$f)
(-1)($j==",")
(-2). 10)if($r>"")$d.=+$c;
->$d.=$r>""?+$c:"";
(-0)$d.=$l?$t;
está obsoleta (-10) 2)$s.=$l?"|":"";return$s;
->return$s."|"[$l];
(-6). 3) llaves obsoletas{$e=v($v,$t+1,$k+1==$c);}
(-2). 4){$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}
->$d.=str_pad("",strlen($e=$v." "[$k+1==$c]),$t+1);
(-5).