Alinee las diagonales de una cuadrícula de texto

15

Dada una cuadrícula de texto rectangular, alinee las diagonales que van desde la esquina superior izquierda a la inferior derecha en columnas de modo que los caracteres más bajos y más a la derecha de todas las diagonales estén en un nivel. Use espacios para sangrar.

Por ejemplo, si la cuadrícula de entrada de texto es

abcd
1234
WXYZ

entonces lo que se alinean las diagonales W, 1X, a2Y, b3z, c4, y den las columnas que dan este resultado:

  ab
 123c
WXYZ4d

Tenga en cuenta que los caracteres más bajos más a la derecha de todas las diagonales WXYZ4d, están en el mismo nivel.

Detalles

  • La cuadrícula de entrada de texto tendrá un tamaño mínimo de 1 × 1 y todas las líneas tendrán la misma longitud.

  • Puede tomar la cuadrícula de entrada como una cadena de varias líneas o como una lista de cadenas de una sola línea.

  • La cuadrícula de entrada solo contendrá caracteres ASCII imprimibles (incluye espacio).

  • La salida puede tener opcionalmente una nueva línea final, pero no debe haber otras líneas vacías.

  • Las líneas de la salida pueden tener opcionalmente espacios finales pero no deben tener espacios iniciales innecesarios.

Otros ejemplos

Las líneas vacías separan ejemplos. Cada entrada es seguida directamente por su salida.

123
456
789

  1
 452
78963

123.?!
456??!
789!!!

  123.
 456???
789!!!!!

**@
@  

 **
@  @


/\/\
\/ /
/ /\
\/\/

   /
  \/\
 / / /
\/\/\/\

12
34
56
78
90

 7531
908642

Code

Code

G
O
L
F

FLOG

~

~

Puntuación

El código más corto en bytes gana.

Pasatiempos de Calvin
fuente
¿Puede la entrada ser una matriz de caracteres 2D (una matriz de caracteres)?
Luis Mendo
¿Puede la primera columna de la entrada contener espacios?
Kritixi Lithos
@LuisMendo Eso suena bien.
Hobbies de Calvin
@KritixiLithos Sí, podría ser.
Hobbies de Calvin

Respuestas:

4

J , 12 bytes

|./.&.|:&.|.

Define un verbo anónimo. Pruébalo en línea!

Explicación

|./.&.|:&.|.
|.            Reversed
  /.          anti-diagonals
    &.        under
      |:      transpose
        &.    under
          |.  reversal

En J, u &. v(léase: udebajo v) significa "v, luego u, luego inverso de v". La inversión y la transposición son auto-inversas, por lo que el programa realmente significa "revertir, transponer, extraer anti-diagonales invertidas, transponer, revertir".

Con entrada de ejemplo:

abcd
1234
WXYZ

Marcha atrás:

WXYZ
1234
abcd

Transponer:

W1a
X2b
Y3c
Z4d

Extraer antiagoniales invertidos (y almohadilla con espacios):

W  
X1 
Y2a
Z3b
4c 
d  

Transponer:

WXYZ4d
 123c 
  ab  

Marcha atrás:

  ab  
 123c 
WXYZ4d
Zgarb
fuente
2
Excelente demostración del poder de los adverbios
millas del
2
Desperté y recordé que en realidad eran conjunciones.
millas
2

Gelatina , 11 o 10 bytes

ZŒDṙLUz⁶ṚUY

Pruébalo en línea!

Un algoritmo bastante diferente de mi otra solución; este usa un incorporado para llegar a las diagonales, en lugar de hacer las cosas manualmente.

Explicación:

ZŒDṙLUz⁶ṚUY
Z           transpose
 ŒD         diagonals, main diagonal first
    L       number of lines in the original array
   ṙ        rotate list (i.e. placing the short diagonal first)
     U      reverse inside lines
      z⁶    transpose, padding with spaces
        ṚU  rotate matrix 180 degrees
          Y (possibly unnecessary) join on newlines

Las diagonales salen posiblemente en la peor orientación posible (que requieren transposiciones, reversiones y rotaciones repetidas), y en el orden incorrecto (Jelly genera primero la diagonal principal, por lo que debemos mover algunas diagonales desde el final hasta el comienzo para obtenerlas en orden). Sin embargo, esto todavía sale más corto que mi otra solución Jelly.


fuente
2

CJam , 29 bytes

qN/{)\z}h]2/{~W%+}%eeSf.*W%N*

Pruébalo en línea!

Explicación

En lugar de extraer las diagonales, quitamos las capas del extremo, alternando izquierda y derecha. Considere la siguiente entrada:

GFDB
EEDB
CCCB
AAAA

Si escribimos las diagonales como lo requiere el desafío, obtenemos:

   G
  EEF
 CCCDD
AAAABBB

Tenga en cuenta que esto es simplemente (de abajo hacia arriba), la fila más inferior, concatenada con la columna más a la derecha. Esta definición también funciona si la entrada es rectangular.

{      e# Run this loop while there are still lines left in the input.
  )    e#   Pull off the bottom-most row.
  \    e#   Swap with the remaining rows.
  z    e#   Transpose the grid so that the next iteration pulls off the last
       e#   column instead. However, it should be noted that transposing
       e#   effectively reverses the column, so the second half of each output
       e#   line will be the wrong way around. We'll fix that later.
}h     e# When the loop is done, we'll have all the individual layers on the
       e# stack from bottom to top, alternating between horizontal and vertical
       e# layers. There will be an empty string on top.
]      e# Wrap all those strings in a list.
2/     e# Split into pairs. There may or may not be a trailing single-element
       e# list with the empty string.
{      e# Map this block over each pair...
  ~    e#   Dump the pair on the stack.
  W%   e#   Reverse the second element.
  +    e#   Append to first element.
       e#   If there was a trailing single-element list, this will simply
       e#   add the empty string to the previous pair, which just removes
       e#   the empty string.
}%
ee     e# Enumerate the list, which pairs each string (now containing both halves)
       e# of an output line from bottom to top) with its index.
Sf.*   e# Turn those indices X into strings of X spaces, to get the correct
       e# indentation.
W%     e# Reverse the list of strings so the longest line ends up on the bottom.
Martin Ender
fuente
¡Cuidado, eso ]envolverá toda la pila! Creo que las funciones deberían funcionar independientemente del contenido de la pila debajo de la entrada, y parece estar de acuerdo ^^
Lynn
@Lynn whoops, olvidé que estaba usando ]cuando lo cambié a una función.
Martin Ender
Creo que podrías hacer [{)\z}h]y mantener una función, para 27 bytes.
Lynn
2

JavaScript, 116101 bytes

f=(s,r='$&',l='',z=s.replace(/.$|\n?(?!.*\n)..+/gm,x=>(l=x+l,'')))=>l?f(z,r+' ')+l.replace(/\n?/,r):l


G.onclick=()=>O.textContent=f(I.value);
<textarea id=I style=height:100px>/\/\
\/ /
/ /\
\/\/</textarea><button id=G>Go</button><pre id=O></pre>

Solo quería usar esta /.$|\n?(?!.*\n)..+/gmidea de patrón de expresiones regulares . ( https://regex101.com/r/mjMz9i/2 )

El sabor de JavaScript regex es decepcionante, tuve que usarlo (?!.*\n)porque no se ha \Zimplementado, y de alguna manera no pude usarlo \0.

  • 15 bytes de descuento gracias @Neil.
Washington Guedes
fuente
Me encanta este enfoque, pero puede usarlo en .lugar de hacerlo, [^]ya que solo necesita omitir caracteres que no sean de nueva línea para encontrar una nueva línea, lo que ahorra 2 bytes.
Neil
No creo que ^sea ​​necesario en la expresión regular final, porque de todos \nmodos ya está al comienzo de la cadena, por lo que se guarda otro byte.
Neil
He encontrado una manera de jugar al golf '$&'+' '.repeat(n). Básicamente, esa expresión es justa $&pero con un espacio agregado a cada llamada, que es trivial de implementar de forma recursiva: reemplace n=0con r='$&'y f(z,n+1)con f(z,r+' ')y luego res la cadena de reemplazo deseada. Si he contado correctamente, eso ahorra 12 bytes.
Neil
@Neil. ¡Eso es increíble! Gracias
Washington Guedes
1

Gelatina , 15 o 14 bytes

L’⁶x;\Ṛ;"µZUZṚY

Pruébalo en línea!

Este es un algoritmo que no utiliza el Jelly incorporado para diagonales. Hacer eso podría hacerlo más corto; Bien podría intentar eso a continuación.

Así es como funciona el algoritmo. Comencemos con esta entrada:

["abc",
 "def",
 "ghi"]

Comenzamos con L’⁶x;\. L’nos da la longitud de la entrada menos 1 (en este caso, 2). Luego ⁶xnos da una cadena de espacios de esa longitud ( " "en este caso); y ;\nos da los resultados acumulativos al concatenarlo (un triángulo de espacios). Luego invertimos el triángulo y lo concatenamos al lado izquierdo del original ( ;"concatena los elementos correspondientes de las listas, µprovoca un corte forzado en el análisis y, por lo tanto, usa la entrada original como la segunda lista por defecto), dándonos esto:

["  abc",
 " def",
 "ghi"]

Esta es casi la solución que queremos, pero necesitamos mover los elementos hacia abajo para estar alineados con la última cadena. Se trata de transponer ( Z), invertir dentro de cada línea ( U), transponer nuevamente ( Z) e invertir las líneas ( ):

["  abc",
 " def",
 "ghi"]

transponer

["  g",
 " dh",
 "aei",
 "bf",
 "c"]

invertir dentro de filas

["g  ",
 "hd ",
 "iea",
 "fb",
 "c"]

transponer

["ghifc",
 " deb",
 "  a"]

invertir las filas

["  a",
 " deb",
 "ghifc"]

Finalmente, se Yune a las nuevas líneas. No me queda claro si esto se requiere o no para cumplir con la especificación (que permite la entrada como una lista de cadenas, pero no dice lo mismo sobre la salida), por lo que el recuento de bytes exacto depende de si está incluido u omitido.


fuente
1

Pyth, 16 bytes

j_.t_M.Tm+*;l=tQ

Big Pyth :

join-on-newline
reverse transpose-and-fill-with-spaces reverse func-map transpose-justified
map
  plus
    times innermost-var
      length assign tail input
    implicit-innermost-var
  implicit-input

Como la gente dice que los idiomas de golf son difíciles de leer, he diseñado Big Pyth, que es fácil de leer y traducir a Pyth. El archivo vinculado traduce una secuencia de entrada de Big Pyth a Pyth. Cada token Big Pyth separado por espacios en blanco corresponde a un token Pyth, ya sea un personaje o .seguido de un personaje. Las excepciones son los implicittokens, que están implícitos en el código Pyth.

Quiero ver qué tan bueno es el formato explicativo Big Pyth, así que no voy a dar ninguna otra explicación. Pregúntame si quieres que te expliquen algo, sin embargo.

isaacg
fuente
0

JavaScript (ES6), 140 bytes

a=>[...Array(m=(h=a.length)<(w=a[0].length)?h:w)].map((_,i)=>[...Array(h+w-1)].map((_,j)=>(a[x=i+h-m-(++j>w&&j-w)]||``)[x+j-h]||` `).join``)

Toma entrada y salida como matrices de cadenas. También acepta una entrada de matriz de caracteres bidimensional y guarda 7 bytes si se acepta una salida de matriz de caracteres bidimensional. Explicación: La altura del resultado mes el mínimo de la altura hy el ancho wde la matriz original, mientras que el ancho es simplemente uno menos que la suma de la altura y el ancho de la matriz original. La fila de origen para los caracteres en la parte principal del resultado proviene directamente de la fila apropiada de la matriz original, contando hacia arriba desde la parte inferior, mientras que en la parte adicional del resultado, la fila de origen se mueve una fila hacia arriba por cada columna adicional. La columna de origen para ambas mitades del resultado resulta ser igual a la columna de destino movida una columna a la izquierda para cada fila de origen sobre la parte inferior.

Neil
fuente
0

Octava, 57 bytes

@(A){B=spdiags(A),C=B>0,D='  '(C+1),D(sort(C))=B(C),D}{5}
Rainer P.
fuente
0

Python 3, 247 bytes

def a(s):
 s=s.split('\n')
 for i,l in enumerate(s):r=len(s)-i-1;s[i]=' '*r+l+' '*(len(s)-r-1)
 print(*[''.join(i) for i in list(zip(*[''.join(a).rstrip([::-1].ljust(min(len(s),len(s[0])))for a in zip(*[list(i)for i in s])]))[::-1]],sep='\n')`
Cormac
fuente
Espacio en blanco inútil en join(i) for.
Yytsi
0

Python 2, 150 bytes

def f(l):w=len(l[0]);h=len(l);J=''.join;R=range;print'\n'.join(map(J,zip(*['%%-%ds'%h%J(l[h+~i][j-i]for i in R(h)if-w<i-j<1)for j in R(h-~w)]))[::-1])

Toma la entrada como una lista de cadenas.

Arfie
fuente
0

Clojure, 194 bytes

Implementado de la manera difícil agrupando caracteres Gy luego generando líneas.

#(let[n(count %)m(count(% 0))G(group-by first(for[i(range n)j(range m)][(min(- n i)(- m j))((% i)j)]))](apply str(flatten(for[k(reverse(sort(keys G)))][(repeat(dec k)" ")(map last(G k))"\n"]))))

Toma entrada como una vecde vecs like [[\a \b \c \d] [\1 \2 \3 \4] [\W \X \Y \Z]]. Ejemplo:

(def f #( ... ))
(print (str "\n" (f (mapv vec(re-seq #".+" "abcd\n1234\nWXYZ")))))

  ab
 c123
d4WXYZ
NikoNyrh
fuente