Converti n stringhe di lunghezza m in stringhe m di lunghezza n


16

Scrivi un programma che, dato qualsiasi numero 'n' di stringhe di lunghezza 'm', restituisca 'm' numero di stringhe 'n' lunghezza, con questa condizione:

Ogni nuova stringa dovrebbe contenere le lettere nello stesso indice delle altre stringhe

Ad esempio, la prima stringa di output deve contenere la prima lettera di tutte le stringhe di input, la seconda stringa di output deve contenere la seconda lettera di tutte le stringhe di input e così via.

Esempi (i numeri sotto le lettere sono gli indici delle stringhe):

input: "car", "dog", "man", "yay"
        012    012    012    012
output: "cdmy", "aoaa", "rgny"
         0000    1111    2222

input: "money", "taken", "trust"
        01234    01234    01234
output: "mtt", "oar", "nku", "ees", "ynt"
         000    111    222    333    444

Supponiamo che l'input sia corretto ogni volta

Il codice byte più breve vince!

Modificare:

Poiché esistono molti linguaggi di programmazione e potrebbero esserci molte soluzioni possibili per ciascuno di essi, posterò la soluzione più breve per ciascun linguaggio di programmazione e l'utente che lo ha fornito. Continua a programmare!

Re-Edit:

Grazie all'utente Dennis ho inserito uno snippet per le classifiche.


2
Abbiamo uno snippet di classifica che puoi aggiungere al tuo corpo di domanda. Non è necessario farlo a mano.
Dennis,


Mi dispiace, non sapevo che si chiamasse "trasposizione"
Inserisci il nome qui il

6
Non credo che queste sfide siano duplicate, a causa delle differenze che coinvolgono trasposizione irregolare e qualche strana gestione degli spazi bianchi nell'altra domanda. Mentre in alcune lingue le risposte potrebbero essere molto simili, penso che nella maggior parte dei casi saranno abbastanza diverse da non essere un duplicato.
FryAmTheEggman,

Risposte:



9

Python, 36 29 byte

zip(*s) restituisce un elenco di tuple di ciascun personaggio, trasposte.

lambda s:map(''.join,zip(*s))

Provalo online


L'output dice "cdmy", "aoaa", "rgny", che è un elenco ["cdmy", "aoaa", "rgny"]o una tupla("cdmy", "aoaa", "rgny")
mbomb007,

map(''.join,zip(*s))funziona anche per la conversione di stringhe (solo Python 2) e per Python 3, [*map(''.join,zip(*s))]funziona afaik
Value Ink

@ KevinLau-notKenny map(''.join,zip(*s))è valido anche per Python 3: per impostazione predefinita, consentiamo iteratori / generatori al posto degli elenchi.
Mego,



7

PowerShell v2 +, 66 54 byte

param($n)for($x=0;$n[0][$x];$x++){-join($n|%{$_[$x]})}

Yo ... no map, no zip, no transpose, ecc., Quindi possiamo farcela da soli. Grandi oggetti di scena su @DarthTwon per il golf a 12 byte.

Accetta input $n, imposta un forloop. Set di inizializzazione$x su0 , il test è se abbiamo ancora lettere nella nostra parola $n[0][$x]e incrementiamo $x++ogni iterazione.

All'interno del loop, prendiamo il nostro array di stringhe, lo instradiamo in un loop interno che sputa il carattere appropriato da ogni parola. Questo è incapsulato in a -joinper formare una stringa e quella stringa viene lasciata sulla pipeline. Alla fine dell'esecuzione, le stringhe sulla pipeline vengono stampate implicitamente.

PS C:\Tools\Scripts\golfing> .\convert-n-strings.ps1 "Darth","-Twon","Rocks"
D-R
aTo
rwc
tok
hns

1
Bello, questo è il tipo di risposte che volevo vedere;) Scrivere è troppo semplice ,piuttosto che pensare alla risposta
Inserisci qui il nome

Utilizzando un ciclo while può pare, inoltre, che in basso: param($n)$x=0;while($n[0][$x]){-join($n|%{$_[$x]});$x++}. E nessun errore qui: D
ThePoShWolf,

@DarthTwon Excellent. In alternativa, utilizzare un forloop per altri due. ;-)
AdmBorkBork,

Hmm ... ci ho provato, ma non dopo aver veramente ridotto il mio whileciclo. Ottimo lavoro signore!
ThePoShWolf,

Puoi usare Linq in Powershell?
aloisdg si trasferisce su codidact.com il

7

Vim, 37 36 battute

Tutte le altre risposte sono noiose e utilizzano noiosi built-in a byte singolo. Ecco una risposta caotica che fa tutto manualmente, in qualcosa che non è nemmeno un linguaggio di programmazione:

Gmaqqgg:s/./&<cr>d<C-v>`aGo<esc>pvGgJ@qq@q`adgg

Spiegazione:

G                                   "move to the end of this line
     ma                             "And leave mark 'a' here
       qq                           "Start recording in register 'q'
         gg                         "Move to the beginning
           :s/./&<cr>               "Assert that there is atleast one character on this line
                      d             "Delete
                       <C-v>        "Blockwise
                            `a      "Until mark 'a'

    G                               "Move to the end of the buffer
     o<esc>                         "Open a newline below us
           p                        "And paste what we deleted
            vG                      "Visually select everything until the end
              gJ                    "And join these without spaces
                @q                  "Call macro 'q'. The first time, this will do nothing,
                                    "The second time, it will cause recursion.
                  q                 "Stop recording
                   @q               "Call macro 'q' to start it all

Ora è tutto a posto, ma nel buffer è rimasto del testo aggiuntivo. Quindi dobbiamo:

`a                              "Move to mark 'a'
  dgg                           "And delete everything until the first line

5

CJam, 6 5 byte

Salvato 1 byte grazie a Luis Mendo.

qS%zp

Provalo online!

q      e# Get all input
 S%    e# Split it on spaces
   z   e# Take the transpose
    p  e# Print it as an array


4

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>.)+.


4

codice macchina x86, 19 byte

In esadecimale:

fc89d35651a401dee2fb91aa595e464a75f1c3

Input:: ECX# di stringhe (n) EDX,: lunghezza della stringa individuale (m) ESI,: array di stringhe di input,: EDIbuffer di output che riceve array di stringhe. Si presume che l'array sia definito come char src[n][m+1]per l'input e char dst[m][n+1]per l'output e tutte le stringhe sono terminate NULL.

0:  fc                  cld
1:  89 d3               mov ebx,edx   ;EDX is the counter for the outer loop
_outer:
3:  56                  push esi
4:  51                  push ecx
_inner:
5:  a4                  movsb         ;[EDI++]=[ESI++]
6:  01 de               add esi,ebx   ;Same char, next string
8:  e2 fb               loop _inner   ;--ECX==0 => break
a:  91                  xchg eax,ecx  ;EAX=0
b:  aa                  stosb         ;NULL-terminate just completed string
c:  59                  pop ecx
d:  5e                  pop esi       ;First string,
e:  46                  inc esi       ;...next char
f:  4a                  dec edx
10: 75 f1               jnz _outer
12: c3                  ret

3

Brachylog , 5 byte

z:ca.

Si aspetta un elenco di stringhe come input, ad es run_from_atom('z:ca.',["money":"taken":"trust"],Output).

Spiegazione

z       Zip the strings in the Input list
 :ca.   output is the application of concatenation to each element of the zip

3

05AB1E, 3 byte

ø€J

spiegato

     # implicit input, eg: ['car', 'dog', 'man', 'yay']
ø    # zip, producing [['c', 'd', 'm', 'y'], ['a', 'o', 'a', 'a'], ['r', 'g', 'n', 'y']]
 €J  # map join, resulting in ['cdmy', 'aoaa', 'rgny']

Provalo online



2

JavaScript ES6, 48 46 byte

a=>[...a[0]].map((n,x)=>a.map(a=>a[x]).join``)

Mi sento escluso, non abbiamo una funzione zip integrata. Grazie Nicea per aver segnalato il mio errore di tipo.

uso

(a=>[...a[0]].map((n,x)=>a.map(a=>a[x])))(["asd","dsa"]); //or whatever is above, might change due to edits

ritorna

["ad","ss","da"]

Eccezione: TypeError: a [0] .map non è una funzione
edc65

1
È necessario [...a[0]].map, poiché a[0]non è un array.
nicael,

@nicael grazie. incasinato i tipi. questo dimostra perché non dovrei giocare a golf così presto la mattina.
charredgrass,

@nicael .joinli ho editati per risolvere quel problema.
charredgrass,

1
join`` invece di join('')salvare 2 byte. Downvote ritirato
edc65

2

Utilità Bash + BSD, 27

sed s/./\&:/g|rs -c: -g0 -T

I / O tramite stringhe separate da nuova riga STDIN / STDOUT.

Potrebbe essere necessario installare rscon sudo apt install rso simili. Funziona immediatamente su OS X.

L' -Topzione per eseguire rsil sollevamento pesante della trasposizione. Il resto è solo formattazione:

  • Il sedcomando si inserisce semplicemente :dopo ogni carattere
  • -c:specifica che le colonne di input sono :separate
  • -g0 specifica che le colonne di output hanno una separazione di larghezza zero

Se la mia lettura della rsmanpage è corretta, allora quanto segue dovrebbe funzionare per un punteggio di 12, ma sfortunatamente non funziona - vedi nota sotto:

rs -E -g0 -T

Esempio di output:

$ printf "%s\n" car dog man yay |sed s/./\&:/g|rs -c: -g0 -T
cdmy
aoaa
rgny
$

Se si prevede che l'input sia tutto ASCII stampabile, è :possibile sostituirlo con un carattere non stampabile, ad esempio 0x7 BEL.


Nota

Volevo capire perché non riuscivo a far funzionare l' -Eopzione e liberarmi della sedpreelaborazione. Ho trovato il rscodice sorgente qui . Come puoi vedere, dare questa opzione imposta la ONEPERCHARbandiera. Tuttavia, non c'è nulla nel codice che controlla effettivamente lo stato di questo flag. Quindi penso che possiamo dire che nonostante l'opzione sia documentata, non è implementata.

In effetti, questa opzione è documentata nella rsmanpage di Linux :

-E Considera ogni carattere di input come una voce di array.

ma non la versione di OS X.


2

PHP, 82 byte

function f($a){foreach($a as$s)foreach(str_split($s)as$i=>$c)$y[$i].=$c;return$y;}

prende e restituisce una matrice di stringhe

abbattersi

function f($a)
{
    foreach($a as$s)                    // loop through array $a
        foreach(str_split($s)as$i=>$c)  // split string to array, loop through characters
            $y[$i].=$c;                 // append character to $i-th result string
    return$y;
}

esempi

$samples=[
    ["asd","dsa"], ["ad","ss","da"],
    ["car", "dog", "man", "yay"], ["cdmy", "aoaa", "rgny"],
    ["money", "taken", "trust"], ["mtt", "oar", "nku", "ees", "ynt"]
];
echo '<pre>';
while ($samples)
{
    echo '<b>in:</b> ';         print_r($x=array_shift($samples));
    echo '<b>out:</b> ';        print_r(f($x));
    echo '<b>expected:</b> ';   print_r(array_shift($samples));
    echo '<hr>';
}

2

APL, 3 byte

↓⍉↑

prende le stringhe di input e le trasforma in una matrice di caratteri. traspone la matrice. divide le righe della matrice risultante in stringhe.



1

Mathematica, 26 bytes

""<>#&/@(Characters@#)&

Anonymous function. Takes a string list as input and returns a string list as output. The Unicode character is U+F3C7, representing \[Transpose]. Works by converting to a character matrix, transposing, and converting back to a string list. If the input/output format was stretched, then a simple 5-byte transpose would work:

#&

+1 you beat me to the punch! (But I wasn't able to use the Transpose symbol.) By the way, why doesn't the T show up on screen? (It is there when I copy your code to Mathematica).
DavidC

@DavidC The Unicode character is in the Private Use Area, which is marked as a section for proprietary characters and is therefore neither officially assigned a glyph nor rendered at all in most fonts. Mathematica's font just happens to render this character as a supserscript T and interpret it as a \[Transpose].
LegionMammal978

@DavidC Why don't they use ?
Adám

@Adám IDK, you'd have to ask Wolfram Research about that, not me
LegionMammal978

@LegionMammal978 Nah, I'm happy as long as I have APL's obvious .
Adám

1

MATLAB / Octave, 4 bytes

@(x)x'

This defines an anonymous function. Input format is ['car'; 'dog'; 'man'; 'yay'].

Try it here.


What format is the input for this solution? I don't think it will work with the way Matlab handles strings if you try to input them in a Matlabby way, e.g. f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}]) outputs ans = 'abcd' 'abcd' 'abcd'
sintax

@sintax Input format should be a 2D char array, as in the example linked in the answer. You are using a cell array of strings (obtained by concatenating singleton cell arrays). It should be: f(['abcd';'abcd';'abcd']). I've edited the answer to specify the input format
Luis Mendo

1

Haskell, 41 bytes

f l=zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0

Or with a bit more air:

f l = zipWith ($) [map (!! n) | n <- [0..]] $
                  l <$ (l !! 0)

The second list is the list of words repeated “the length of a word” time. On each list of words, we select the n-th letter of each word, giving the result.


1
There's no need for a full program, because "program" means "program or function", so a function is enough. You can pass and return a list of strings and therefore omit wordsand unwords. Further, map(\_->l)(l!!0) is l<*l!!0, so it boils down to \l->zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0.
nimi

Oh, good thanks :) I'm updating.
villou24

Oops, typo: it's l<$l!!0 (first time wrong, second time right), but you got it right anyway.
nimi

1

Common Lisp, 62 bytes

(lambda(s)(apply'map'list(lambda(&rest x)(coerce x'string))s))

The map function takes a result type (here list), a function f to apply and one or more sequences s1, ..., sn. All sequences are iterated in parallel. For each tuple of elements (e1,...,en) taken from those sequences, we call (f e1 ... en) and the result is accumulated in a sequence of the desired type.

We take a list of strings, say ("car" "dog" "man" "yay"), and use apply to call map. We have to do this so that the input list is used as more arguments to map. More precisely, this:

(apply #'map 'list fn '("car" "dog" "man" "yay"))

... is equivalent to:

(map 'list f "car" "dog" "man" "yay")

And since strings are sequences, we iterate in parallel over all first characters, then all second characters, etc... For example, the first iteration calls f as follows:

(f #\c #\d #\m #\y)

The anonymous lambda takes the list of arguments given to it and coerces it back to a string.


1

Perl, 91 bytes

So lengthy one..

$l=<>;$p=index($l," ")+1;@i=split//,$l;for$a(0..$p-1){print$i[$a+$_*$p]for(0..$p);print" "}

Try it here!


0

Ruby, 46 bytes

Probably the first time that "Ruby strings aren't Enumerables" is actually biting me hard since I had to map the strings into arrays before processing. (Normally having to use String#chars isn't enough of a byte loss to matter, but since I need to map them, it stings a lot more)

->s{s.map!(&:chars).shift.zip(*s).map &:join}

0

Clojure, 68 bytes

#(map(fn[g](reduce(fn[a b](str a(nth b g)))""%))(range(count(% 0))))

Maps a function which is just reduce (goes on elements of the list one by one and joins nth character of the string) on the range from 0 to length of the first string.

See it online: https://ideone.com/pwhZ8e


0

C#, 53 bytes

t=>t[0].Select((_,i)=>t.Aggregate("",(a,b)=>a+b[i]));

C# lambda (Func) where the output is IList<string> and the output is IEnumerable<string>. I dont know how work zip in other language but I can't find a way to use the C#'s one here. Aggregate fit the need well. No transpose in C#, there is one in Excel but I wont use it.

Try it online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.