Retina , 45 43 byte
Il conteggio dei byte presuppone la codifica ISO 8859-1.
O$#`.(?<=(.+))|¶
$.1
!`(?<=(¶)+.*)(?<-1>.)+
L'alimentazione principale è significativa. L'input e l'output sono elenchi terminati con linefeed di stringhe ASCII stampabili (si noti che entrambi hanno un singolo feed di riga finale).
Provalo online!
Per un po 'ho saputo che trasporre blocchi rettangolari sarebbe stato un dolore in Retina (mentre trasporre i quadrati non è poi così male), ma non ci ho mai provato. La prima soluzione era davvero lunga 110 byte, ma dopo diversi cambiamenti sostanziali nell'approccio, i 45 byte risultanti non sono di gran lunga cattivi come sospettavo (ma comunque ...). La spiegazione seguirà domani.
Spiegazione
Fase 1: ordinamento
O$#`.(?<=(.+))|¶
$.1
Questo svolge il compito principale di riordinare i caratteri nell'input, ma finisce per rovinare la separazione in linee. È interessante notare che se rimuoviamo il file|¶ , otteniamo il codice richiesto per trasporre un input quadrato.
Le fasi di ordinamento (indicate con O) funzionano in questo modo: trovano tutte le corrispondenze della regex data (la cosa dopo la `), quindi ordinano quelle corrispondenze e le inseriscono nuovamente nei punti in cui sono state trovate le corrispondenze. In questo caso, questa regex corrisponde a ogni singolo carattere: non linefeed tramite l' .(?<=(.*))alternativa e linefeed tramite il ¶. Quindi, ordina tutti i caratteri nell'input. La parte più interessante è ciò che sono ordinati per .
Il $ opzione attiva una modalità "ordina per", in cui ogni corrispondenza viene sostituita con il modello di sostituzione sulla seconda riga, che viene quindi utilizzato per confrontare le corrispondenze. Inoltre, #dice a Retina di convertire il risultato della sostituzione in un numero intero e di confrontare tali numeri interi (anziché trattarli come stringhe).
Quindi, alla fine, dobbiamo guardare alla regex e alla sostituzione. Se la prima alternativa corrisponde (cioè abbiamo abbinato qualsiasi personaggio all'interno di una delle linee), allora (?<=(.*))cattura tutto il gruppo fino a quel personaggio su quella linea in gruppo 1. Il $.1modello di sostituzione sostituisce questo con la lunghezza del gruppo 1. Quindi, il primo carattere in ogni stringa diventa 1, il secondo diventa inutilizzato in questo caso, la sostituzione è vuota, ma ai fini dell'opzione, questo viene considerato . Ciò significa che tutti gli avanzamenti di riga sono ordinati in primo piano.2 , il terzo diventa 3e così via. Ora dovrebbe essere chiaro come questo traspone un input quadrato: tutti i primi caratteri delle righe vengono prima e finiscono tutti nella riga più in alto, quindi tutti i secondi caratteri finiscono nella seconda riga e così via. Ma per questi ingressi rettangolari, stiamo anche abbinando gli avanzamenti di linea. Dal gruppo1#0
Quindi ora abbiamo i caratteri nel primo ordine (primo carattere di ogni stringa, secondo carattere di ogni stringa, ecc.) E tutti gli avanzamenti di riga all'inizio.
Fase 2: incontro
!`(?<=(¶)+.*)(?<-1>.)+
Ora dobbiamo dividere i caratteri in linee della lunghezza corretta. Questa lunghezza corrisponde al numero di righe nell'input originale, che corrisponde al numero di avanzamenti di riga che abbiamo all'inizio della stringa.
La suddivisione viene eseguita qui con l'aiuto di una fase della partita, che trova semplicemente tutte le partite della regex data e usa il ! opzione per stampare quelle corrispondenze (l'impostazione predefinita sarebbe invece contarle). Quindi l'obiettivo del regex è quello di abbinare una riga alla volta.
Iniziamo "contando" il numero con il lookbehind (?<=(¶)*.*). Genera una cattura in gruppo 1per ogni avanzamento di riga nella parte anteriore.
Quindi, per ognuna di quelle catture, abbiniamo un singolo personaggio con (?<-1>.)+.