Retina , 45 43 bytes
El recuento de bytes asume la codificación ISO 8859-1.
O$#`.(?<=(.+))|¶
$.1
!`(?<=(¶)+.*)(?<-1>.)+
El avance de línea principal es significativo. La entrada y la salida son listas terminadas en salto de línea de cadenas ASCII imprimibles (tenga en cuenta que ambas tienen un solo salto de línea final).
Pruébalo en línea!
Sabía por un tiempo que transponer bloques rectangulares sería un dolor en Retina (mientras que transponer cuadrados no es tan malo), pero en realidad nunca lo intenté. La primera solución fue de hecho la friolera de 110 bytes, pero después de varios cambios sustanciales en el enfoque, los 45 bytes resultantes no son tan malos como sospechaba (pero aún así ...). La explicación seguirá mañana.
Explicación
Etapa 1: ordenar
O$#`.(?<=(.+))|¶
$.1
Esto hace el trabajo principal de reordenar los caracteres en la entrada, pero termina desordenando la separación en líneas. Curiosamente, si eliminamos el |¶, obtenemos el código requerido para transponer una entrada cuadrada.
Las etapas de clasificación (denotadas por O) funcionan de la siguiente manera: encuentran todas las coincidencias de la expresión regular dada (la que está después de la `), y luego clasifican esas coincidencias y las vuelven a insertar en los lugares donde se encontraron las coincidencias. Como sucede, esta expresión regular coincide con todos los caracteres: sin saltos de línea a través de la .(?<=(.*))alternativa y saltos de línea a través de ¶. Por lo tanto, ordena todos los caracteres en la entrada. La parte más interesante es lo que están ordenados por .
La $opción activa un modo de "ordenar por", donde cada coincidencia se reemplaza con el patrón de sustitución en la segunda línea, que luego se utiliza para comparar las coincidencias. Además, #le dice a Retina que convierta el resultado de la sustitución en un entero y compare esos enteros (en lugar de tratarlos como cadenas).
Entonces, finalmente, tenemos que mirar la expresión regular y la sustitución. Si la primera alternativa coincide (es decir, hemos emparejado cualquier carácter dentro de una de las líneas), entonces (?<=(.*))captura todo hasta ese personaje en esa línea en grupo 1. El $.1patrón en la sustitución reemplaza esto con la longitud del grupo 1. Por lo tanto, el primer carácter en cada cadena se convierte 1, el segundo se convierte 2, el tercero se convierte 3y así sucesivamente. Ahora debería quedar claro cómo esto transpone una entrada cuadrada: todos los primeros caracteres de las líneas aparecen primero y todos terminan en la línea superior, luego todos los segundos caracteres terminan en la segunda línea y así sucesivamente. Pero para estas entradas rectangulares, también estamos haciendo coincidir los avances de línea. Desde grupo1no se utiliza en este caso, la sustitución está vacía, pero a los efectos de la #opción, esto se considera 0. Eso significa que todos los avances de línea están ordenados al frente.
Así que ahora tenemos los caracteres en el primer orden (primer carácter de cada cadena, segundo carácter de cada cadena, etc.) y todos los avances de línea al principio.
Etapa 2: partido
!`(?<=(¶)+.*)(?<-1>.)+
Ahora necesitamos dividir los caracteres en líneas de la longitud correcta. Esta longitud corresponde al número de líneas en la entrada original, que corresponde al número de avances de línea que tenemos al comienzo de la cadena.
La división se realiza aquí con la ayuda de una etapa de coincidencia, que simplemente encuentra todas las coincidencias de la expresión regular dada y usa la !opción para imprimir esas coincidencias (lo predeterminado sería contarlas en su lugar). Entonces, el objetivo de la expresión regular es hacer coincidir una línea a la vez.
Comenzamos "contando" el número con el lookbehind (?<=(¶)*.*). Genera una captura en grupo 1por cada salto de línea en el frente.
Luego, para cada una de esas capturas, hacemos coincidir un solo personaje con (?<-1>.)+.