Konvertiere n Strings von m Länge in m Strings von n Länge


16

Schreiben Sie ein Programm, das bei einer gegebenen Anzahl von 'n' Zeichenfolgen mit 'm' Länge 'm' Anzahl von 'n' Zeichenfolgen mit folgender Bedingung zurückgibt:

Jede neue Zeichenfolge sollte die Buchstaben am selben Index wie die anderen Zeichenfolgen enthalten

Beispielsweise muss die erste Ausgabezeichenfolge den ersten Buchstaben aller Eingabezeichenfolgen enthalten, die zweite Ausgabezeichenfolge muss den zweiten Buchstaben aller Eingabezeichenfolgen enthalten und so weiter.

Beispiele (die Zahlen unter den Buchstaben sind die Indizes der Zeichenfolgen):

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

Angenommen, die Eingabe ist immer korrekt

Kürzester Byte-Code gewinnt!

Bearbeiten:

Da es viele Programmiersprachen gibt und es für jede davon viele mögliche Lösungen geben könnte, werde ich die kürzeste Lösung für jede Programmiersprache und den Benutzer, der sie bereitgestellt hat, veröffentlichen. Kodierung beibehalten!

Neu bearbeiten:

Dank Benutzer Dennis habe ich ein Snippet für die Bestenlisten eingefügt.


2
Wir haben ein Leaderboard-Snippet , das Sie Ihrem Fragenkörper hinzufügen können. Das muss nicht von Hand gemacht werden.
Dennis


Es tut mir leid, ich wusste nicht, dass es "transponieren" heißt
Name hier

6
Ich glaube nicht, dass es sich bei diesen Herausforderungen um Duplikate handelt, da die Umsetzung uneinheitlich ist und die andere Frage ein komisches Leerzeichen enthält. Während in einigen Sprachen die Antworten sehr ähnlich sein könnten, denke ich, dass sie in den meisten Sprachen so unterschiedlich sind, dass dies kein Duplikat sein sollte.
FryAmTheEggman

Antworten:



9

Python, 36 29 Bytes

zip(*s) gibt eine Liste von Tupeln jedes Zeichens zurück, transponiert.

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

Probieren Sie es online aus


Die Ausgabe sagt "cdmy", "aoaa", "rgny", das ist eine Liste ["cdmy", "aoaa", "rgny"]oder ein Tupel("cdmy", "aoaa", "rgny")
mbomb007

map(''.join,zip(*s))funktioniert auch für die String-Konvertierung (nur Python 2), und für Python 3 [*map(''.join,zip(*s))]funktioniert afaik
Value Ink

@ KevinLau-notKenny map(''.join,zip(*s))gilt auch für Python 3 - wir erlauben standardmäßig Iteratoren / Generatoren anstelle von Listen.
Mego



7

PowerShell v2 +, 66 54 Bytes

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

Yo ... nein map, nein zip, nein transpose, usw., also können wir unsere eigenen rollen. Große Requisiten an @DarthTwon für das 12-Byte-Golf.

Nimmt Eingaben auf $n, richtet eine forSchleife ein. Die Initialisierung setzt $xauf 0, der Test ist , ob wir noch Briefe in unserem Wort haben $n[0][$x], und wir erhöhen bei $x++jeder Iteration.

Innerhalb der Schleife nehmen wir unser String-Array und leiten es zu einer inneren Schleife, die aus jedem Wort das entsprechende Zeichen ausspuckt. Das wird in a gekapselt -join, um eine Zeichenfolge zu bilden, und diese Zeichenfolge verbleibt in der Pipeline. Am Ende der Ausführung werden die Zeichenfolgen in der Pipeline implizit gedruckt.

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

1
Schön, das ist die Art der Antworten, die ich sehen wollte;) Es ist zu einfach zu schreiben , anstatt über die Antwort nachzudenken
Name hier

Eine while - Schleife verwenden , kann ferner , dass die nach unten pare: param($n)$x=0;while($n[0][$x]){-join($n|%{$_[$x]});$x++}. Und hier keine Fehler: D
ThePoShWolf

@DarthTwon Ausgezeichnet. Oder verwenden Sie eine forSchleife für zwei weitere. ;-)
AdmBorkBork

Hmm ... das habe ich versucht, aber nicht, nachdem ich meine whileSchleife wirklich abgespeckt habe . Gute Arbeit, Sir!
ThePoShWolf

Kann man Linq in Powershell verwenden?
Aloisdg sagt Reinstate Monica

7

Vim, 37 36 Tastenanschläge

Alle anderen Antworten sind langweilig und verwenden langweilige Single-Byte-Builtins. Hier ist eine knifflige Antwort, die das Ganze manuell erledigt, in etwas, das nicht einmal eine Programmiersprache ist:

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

Erläuterung:

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

Jetzt ist alles in Ordnung, aber der Puffer enthält noch zusätzlichen Text. Also müssen wir:

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



4

Retina , 45 43 Bytes

Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus.

O$#`.(?<=(.+))|¶
$.1
!`(?<=(¶)+.*)(?<-1>.)+

Der Zeilenvorschub ist signifikant. Eingabe und Ausgabe sind Zeilenvorschub-terminierte Listen druckbarer ASCII-Zeichenfolgen (beachten Sie, dass beide einen einzelnen nachgestellten Zeilenvorschub haben).

Probieren Sie es online!

Ich wusste für eine Weile, dass das Transponieren von rechteckigen Blöcken eine Belastung für die Netzhaut sein würde (wohingegen das Transponieren von Quadraten nicht allzu schlimm ist), habe es aber nie wirklich versucht. Die erste Lösung war in der Tat satte 110 Bytes lang, aber nach einigen wesentlichen Änderungen im Ansatz sind die resultierenden 45 Bytes bei weitem nicht so schlecht, wie ich vermutet habe (aber immer noch ...). Erklärung folgt morgen.

Erläuterung

Stufe 1: Sortieren

O$#`.(?<=(.+))|¶
$.1

Dies erledigt die Hauptarbeit des Neuordnens der Zeichen in der Eingabe, führt jedoch dazu, dass die Trennung in Zeilen durcheinander gebracht wird. Interessanterweise, wenn wir die entfernen , den Code, der erforderlich ist, um eine Quadrateingabe zu transponieren.

Sortierphasen (gekennzeichnet durch O) funktionieren wie folgt: Sie finden alle Übereinstimmungen des angegebenen regulären Ausdrucks (das Ding nach dem `), sortieren diese Übereinstimmungen und fügen sie erneut an den Stellen ein, an denen die Übereinstimmungen gefunden wurden. Dieser reguläre Ausdruck entspricht zufällig jedem einzelnen Zeichen: Nicht-Zeilenvorschub über die .(?<=(.*))Alternative und Zeilenvorschub über die . Daher werden alle Zeichen in der Eingabe sortiert. Der interessantere Teil ist, was sie sortiert sind durch .

Die $Option aktiviert einen "Sortieren nach" -Modus, in dem jede Übereinstimmung durch das Substitutionsmuster in der zweiten Zeile ersetzt wird, das dann zum Vergleichen der Übereinstimmungen verwendet wird. Darüber hinaus ist die# weist Retina an, das Ergebnis der Ersetzung in eine Ganzzahl umzuwandeln und diese Ganzzahlen zu vergleichen (anstatt sie als Zeichenfolgen zu behandeln).

Schließlich müssen wir uns den regulären Ausdruck und die Substitution ansehen. Wenn die erste Alternative zutrifft (dh wir haben ein Zeichen in einer der Zeilen gefunden), (?<=(.*))fängt das Programm alles bis zu diesem Zeichen in dieser Zeile in Gruppen ein 1. Das $.1in dem Substitutionsmuster ersetzt dies durch die Länge der Gruppe 1. Daher wird das erste Zeichen in jeder Zeichenfolge 1, das zweite wird2 das dritte 3und so weiter. Es sollte jetzt klar sein, wie dies eine Quadrateingabe transponiert: Alle ersten Zeichen der Zeilen kommen zuerst und landen alle in der obersten Zeile, dann enden alle zweiten Zeichen in der zweiten Zeile und so weiter. Für diese rechteckigen Eingänge passen wir jedoch auch die Zeilenvorschübe an. Seit Gruppe1Wird in diesem Fall nicht verwendet, ist die Ersetzung leer, dies wird jedoch für die Zwecke der #Option berücksichtigt 0. Das heißt, alle Zeilenvorschübe werden nach vorne sortiert.

Jetzt haben wir also die Zeichen in der ersten Reihenfolge (erstes Zeichen jeder Zeichenfolge, zweites Zeichen jeder Zeichenfolge usw.) und alle Zeilenvorschübe am Anfang.

Stufe 2: Match

!`(?<=(¶)+.*)(?<-1>.)+

Wir müssen jetzt die Zeichen in Zeilen der richtigen Länge aufteilen. Diese Länge entspricht der Anzahl der Zeilen in der ursprünglichen Eingabe, die der Anzahl der Zeilenvorschübe entspricht, die wir am Anfang der Zeichenfolge haben.

Die Aufteilung erfolgt hier mit Hilfe einer Match-Phase, die einfach alle Übereinstimmungen des angegebenen Regex findet und die !Option verwendet, um diese Übereinstimmungen auszudrucken (standardmäßig werden sie stattdessen gezählt). Das Ziel des regulären Ausdrucks besteht also darin, jeweils eine Zeile abzugleichen.

Wir beginnen mit dem "Zählen" der Zahl mit dem Lookbehind (?<=(¶)*.*). Es wird eine Erfassung in der Gruppe 1für jeden Zeilenvorschub an der Vorderseite generiert .

Dann ordnen wir für jede dieser Erfassungen ein einzelnes Zeichen zu (?<-1>.)+.


4

x86-Maschinencode, 19 Byte

In hex:

fc89d35651a401dee2fb91aa595e464a75f1c3

Eingabe:: Anzahl ECXder Zeichenfolgen (n) EDX,: Länge der einzelnen Zeichenfolgen (m) ESI,: Array von Eingabezeichenfolgen,: EDIAusgabepuffer, der ein Array von Zeichenfolgen empfängt. Es wird davon ausgegangen, dass das Array sowohl char src[n][m+1]für die Eingabe als auch char dst[m][n+1]für die Ausgabe definiert ist und alle Zeichenfolgen mit NULL-Abschluss versehen sind.

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 Bytes

z:ca.

Erwartet eine Liste von Zeichenfolgen als Eingabe, z run_from_atom('z:ca.',["money":"taken":"trust"],Output).

Erläuterung

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

3

05AB1E, 3 Bytes

ø€J

Erklärt

     # 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']

Probieren Sie es online aus



2

JavaScript ES6, 48 46 Bytes

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

Ich fühle mich ausgeschlossen, wir haben keine eingebaute Zip-Funktion. Danke nicael für den hinweis auf meinen typenfehler.

Verwendung

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

kehrt zurück

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

Ausnahme: TypeError: a [0] .map ist keine Funktion
edc65

1
Sie brauchen [...a[0]].map, da a[0]kein Array ist.
Nicael

@nicael danke. die Typen versaut. das beweist, warum ich so früh morgens nicht golfen sollte.
Charredgrass

@nicael Ich habe .joinsie bearbeitet , um dieses Problem zu beheben.
Charredgrass

1
join`` anstatt join('')2 Bytes zu speichern. Downvote zurückgezogen
edc65

2

Bash + BSD-Dienstprogramme, 27

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

E / A über durch STDIN / STDOUT durch Zeilenumbrüche getrennte Zeichenfolgen.

Möglicherweise müssen Sie rsmit sudo apt install rsoder ähnlich installieren . Funktioniert sofort unter OS X.

Die -TOption, um rsdas schwere Heben der Umsetzung zu tun. Der Rest ist nur die Formatierung:

  • Das sed Befehl wird einfach :nach jedem Zeichen eingefügt
  • -c: Gibt an, dass Eingabespalten sind : getrennt werden
  • -g0 Gibt an, dass Ausgabespalten eine Breite von Null haben

Wenn meine Lektüre der rsmanpage richtig ist, dann folgende sollte für eine Punktzahl von 12 arbeiten, aber leider funktioniert es nicht - siehe Anmerkung unten:

rs -E -g0 -T

Beispielausgabe:

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

Wenn erwartet wird, dass die Eingabe vollständig druckbares ASCII ist, wird das :möglicherweise durch ein nicht druckbares Zeichen ersetzt, z. B. 0x7BEL . .


Hinweis

Ich wollte verstehen, warum ich nicht die -EMöglichkeit hatte zu arbeiten und die sedVorverarbeitung loszuwerden . Ich habe den rsQuellcode hier gefunden . Wie Sie sehen können, setzt die Angabe dieser Option dasONEPERCHAR Flag. Der Code enthält jedoch nichts, was den Status dieses Flags überprüft. Wir können also sagen, dass diese Option, obwohl sie dokumentiert ist, nicht implementiert ist.

Tatsächlich ist diese Option in der Linux- rsManpage dokumentiert:

-E Betrachte jedes Zeichen der Eingabe als einen Array-Eintrag.

aber nicht die OS X-Version.


2

PHP, 82 Bytes

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

nimmt und gibt ein Array von Strings zurück

Nervenzusammenbruch

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;
}

Beispiele

$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 Bytes

↓⍉↑

Nimmt die Eingabezeichenfolgen und verwandelt sie in eine Zeichenmatrix. transponiert die Matrix. Teilt die Zeilen der resultierenden Matrix in Strings auf.



1

Mathematica, 26 Bytes

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

Anonyme Funktion. Nimmt eine Stringliste als Eingabe und gibt eine Stringliste als Ausgabe zurück. Das Unicode-Zeichen ist U + F3C7 und steht für \[Transpose]. Konvertiert in eine Zeichenmatrix, transponiert und konvertiert zurück in eine Zeichenfolgenliste. Wenn das Eingabe- / Ausgabeformat gestreckt wäre, würde eine einfache 5-Byte-Transponierung funktionieren:

#&

+1 Du hast mich geschlagen! (Aber ich konnte das Transponierungssymbol nicht verwenden.) Warum wird das T übrigens nicht auf dem Bildschirm angezeigt? (Es ist da, wenn ich Ihren Code nach Mathematica kopiere).
DavidC

@DavidC Das Unicode-Zeichen befindet sich im Bereich für den privaten Gebrauch, der als Abschnitt für proprietäre Zeichen gekennzeichnet ist und daher in den meisten Schriftarten weder offiziell als Glyphe zugewiesen noch gerendert wird. Die Schriftart von Mathematica gibt dieses Zeichen einfach als hochgestelltes T wieder und interpretiert es als \[Transpose].
LegionMammal978

@DavidC Warum verwenden sie nicht ?
Adám

@ Adám IDK, Sie
müssten

@ LegionMammal978 Nee, ich bin glücklich, solange ich APL's offensichtlich habe .
Adám

1

MATLAB / Octave, 4 Bytes

@(x)x'

Dies definiert eine anonyme Funktion. Eingabeformat ist ['car'; 'dog'; 'man'; 'yay'].

Probieren Sie es hier aus .


Welches Format hat die Eingabe für diese Lösung? Ich glaube nicht , es mit der Art , wie Matlab Griffe Strings arbeiten, wenn Sie zur Eingabe von ihnen in einer Matlabby Art und Weise versuchen, zum Beispiel f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}])gibt am = ‚abcd‘ ‚abcd‘ ‚abcd‘
sintax

@sintax Das Eingabeformat sollte ein 2D-Zeichen-Array sein, wie im in der Antwort verknüpften Beispiel. Sie verwenden ein Zellenarray von Zeichenfolgen (erhalten durch Verketten von Singleton-Zellenarrays). Es sollte sein: f(['abcd';'abcd';'abcd']). Ich habe die Antwort bearbeitet, um das Eingabeformat anzugeben
Luis Mendo

1

Haskell, 41 Bytes

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

Oder mit etwas mehr Luft:

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

Die zweite Liste ist die Liste von Wörtern, die sich "die Länge eines Wortes" Mal wiederholen. In jeder Liste von Wörtern wählen wir den n-ten Buchstaben jedes Wortes aus und geben das Ergebnis an.


1
Ein vollständiges Programm ist nicht erforderlich, da "Programm" "Programm oder Funktion" bedeutet . Eine Funktion ist also ausreichend. Sie können eine Liste von Zeichenfolgen übergeben und zurückgeben und daher wordsund weglassen unwords. Weiter map(\_->l)(l!!0)ist l<*l!!0, so läuft es auf \l->zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0.
Nimi

Oh, gut, danke :) Ich aktualisiere.
villou24

Hoppla, Tippfehler: Es ist l<$l!!0(das erste Mal falsch, das zweite Mal richtig), aber Sie haben es trotzdem richtig verstanden.
Nimi

1

Common Lisp, 62 Bytes

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

Die mapFunktion nimmt einen Ergebnistyp (hier list), eine anzuwendende Funktion f und eine oder mehrere Folgen s1 , ..., sn . Alle Sequenzen werden parallel durchlaufen. Für jedes Tupel von Elementen (e1, ..., en), die aus diesen Sequenzen entnommen wurden, rufen wir (fe1 ... en) auf und das Ergebnis wird in einer Sequenz des gewünschten Typs akkumuliert.

Wir nehmen eine Liste von Strings, sagen wir ("car" "dog" "man" "yay"), und verwenden sie, applyum anzurufen map. Wir müssen dies tun, damit die Eingabeliste als Argument für mehr verwendet wird map. Genauer gesagt:

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

... ist äquivalent zu:

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

Und da Strings Sequenzen sind, iterieren wir parallel über alle ersten Zeichen, dann über alle zweiten Zeichen usw. Die erste Iteration ruft beispielsweise f wie folgt auf:

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

Das anonyme Lambda nimmt die Liste der Argumente und zwingt sie zu einer Zeichenfolge zurück.



0

Ruby, 46 Bytes

Wahrscheinlich ist das erste Mal, dass "Ruby-Strings keine Enumerables" sind, ein heftiger Biss für mich, da ich die Strings vor der Verarbeitung in Arrays abbilden musste. (Normalerweise String#charsreicht es nicht aus, Byteverluste zu verwenden , um eine Rolle zu spielen, aber da ich sie abbilden muss, sticht es viel mehr)

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

Ordnet eine Funktion zu, die gerecht ist reduce im Bereich von 0 bis zur Länge der ersten Zeichenfolge (geht nacheinander auf Elemente der Liste und verbindet das n-te Zeichen der Zeichenfolge).

Sehen Sie es online: https://ideone.com/pwhZ8e


0

C #, 53 Bytes

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

C # lambda ( Func) wo die Ausgabe ist IList<string>und die Ausgabe ist IEnumerable<string>. Ich weiß nicht, wie man zipin einer anderen Sprache arbeitet, aber ich kann hier keinen Weg finden, das C # zu benutzen . Aggregatepassen die Notwendigkeit gut. Keine Transponierung in C #, es gibt eine in Excel, aber ich verwende sie nicht.

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.