Konwertuj n ciągów o długości m na m ciągów o długości n

16

Napisz program, który, biorąc pod uwagę dowolną liczbę ciągów „n” o długości „m”, zwraca liczbę „ciągów” o długości „n”, pod warunkiem:

Każdy nowy ciąg powinien zawierać litery o tym samym indeksie co pozostałe ciągi

Na przykład pierwszy ciąg wyjściowy musi zawierać pierwszą literę wszystkich ciągów wejściowych, drugi ciąg wyjściowy musi zawierać drugą literę wszystkich ciągów wejściowych i tak dalej.

Przykłady (cyfry pod literami to indeksy ciągów znaków):

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

Załóż, że dane wejściowe są poprawne za każdym razem

Wygrywa kod najkrótszego bajtu!

Edytować:

Ponieważ istnieje wiele języków programowania i dla każdego z nich może istnieć wiele możliwych rozwiązań, opublikuję najkrótsze rozwiązanie dla każdego języka programowania i użytkownika, który go dostarczył. Koduj dalej!

Ponowna edycja:

Dzięki użytkownikowi Dennis wstawiłem fragment tabeli wyników.

Tutaj wpisz nazwę
źródło
2
Mamy fragment tabeli wyników , który możesz dodać do swojego pytania. Nie musisz tego robić ręcznie.
Dennis
Przepraszam, nie wiedziałem, że to się nazywa „transponowanie”
wprowadź nazwę tutaj
6
Nie wierzę, że te wyzwania są duplikatami, ze względu na różnice dotyczące nierównej transpozycji i dziwnego traktowania białych znaków w innym pytaniu. Podczas gdy w niektórych językach odpowiedzi mogą być bardzo podobne, myślę, że w większości będą na tyle różne, że nie powinien to być duplikat.
FryAmTheEggman
Powiązane , powiązane
FlipTack

Odpowiedzi:

21

Pyth, 1 bajt

C

Wypróbuj tutaj

Kolejna wbudowana transpozycja

niebieski
źródło
5
Jak to w ogóle jest możliwe?!
DavidC
Na pewno żartujesz!
Vincent
Pyth to nowa Mathematica!
Loovjo,
9

Python, 36 29 bajtów

zip(*s) zwraca listę krotek każdego znaku, transponowanych.

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

Wypróbuj online

mbomb007
źródło
Wyjście mówi "cdmy", "aoaa", "rgny", która jest listą ["cdmy", "aoaa", "rgny"]lub krotką("cdmy", "aoaa", "rgny")
mbomb007
map(''.join,zip(*s))działa również w przypadku konwersji ciągów (tylko Python 2), a w przypadku Python 3 [*map(''.join,zip(*s))]afaik działa
Value Ink
@ KevinLau-notKenny map(''.join,zip(*s))działa również w Pythonie 3 - domyślnie zezwalamy na iteratory / generatory zamiast list.
Mego,
7

MATL , 1 bajt

!

Wypróbuj online!

Pobiera dane niejawnie, transponuje, wyświetla dane niejawnie.

Luis Mendo
źródło
7

PowerShell v2 +, 66 54 bajtów

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

Yo ... nie map, nie zip, nie transposeitd., Więc możemy sami rzucić. Wielkie rekwizyty dla @DarthTwon dla 12-bajtowego golfa.

Pobiera dane wejściowe $n, tworzy forpętlę. Inicjalizacja ustawia się $xna 0, test polega na tym, czy nadal mamy litery w naszym słowie $n[0][$x]i zwiększamy $x++każdą iterację.

Wewnątrz pętli bierzemy naszą tablicę ciągów, prowadzimy ją do wewnętrznej pętli, która wydziela odpowiedni znak z każdego słowa. To jest zamknięte w a, -joinaby utworzyć ciąg, a ten ciąg zostaje pozostawiony w potoku. Pod koniec wykonywania ciągi w potoku są domyślnie drukowane.

PS C:\Tools\Scripts\golfing> .\convert-n-strings.ps1 "Darth","-Twon","Rocks"
D-R
aTo
rwc
tok
hns
AdmBorkBork
źródło
1
Fajnie, tego rodzaju odpowiedzi chciałem zobaczyć;) To jest zbyt proste pisanie ,, niż myślenie o odpowiedzi
Wpisz nazwę tutaj
Korzystanie z pętli while może dodatkowo pare to sobie: param($n)$x=0;while($n[0][$x]){-join($n|%{$_[$x]});$x++}. I żadnych błędów tutaj: D
ThePoShWolf
@DarthTwon Excellent. Lub użyj forpętli dla kolejnych dwóch. ;-)
AdmBorkBork
Hmm ... Próbowałem tego, ale nie po naprawdę sparaliżowaniu mojej whilepętli. Dobra robota!
ThePoShWolf
Czy możesz używać Linq w PowerShell?
aloisdg przenosi się do codidact.com
7

Vim, 37 36 naciśnięć klawiszy

Wszystkie pozostałe odpowiedzi są nudne i wykorzystują nudne wbudowane bajty. Oto odważna odpowiedź, która robi wszystko ręcznie, w czymś, co nie jest nawet językiem programowania:

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

Wyjaśnienie:

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

Teraz wszystko jest w porządku, ale w buforze pozostało trochę tekstu. Więc musimy:

`a                              "Move to mark 'a'
  dgg                           "And delete everything until the first line
DJMcMayhem
źródło
5

CJam, 6 5 bajtów

Zaoszczędzono 1 bajt dzięki Luisowi Mendo.

qS%zp

Wypróbuj online!

q      e# Get all input
 S%    e# Split it on spaces
   z   e# Take the transpose
    p  e# Print it as an array
Business Cat
źródło
4

Pyke, 1 bajt

,

Wypróbuj tutaj!

Transponować.

niebieski
źródło
1
Och ... Nie sądziłem, że byłoby to takie proste: /
Wprowadź nazwę tutaj
1
Tak, nie mogę znaleźć duplikatu, szukając 60 sekund
Blue
4

Siatkówka , 45 43 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

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

Wiodące podawanie linii jest znaczące. Dane wejściowe i wyjściowe są zakończonymi podawaniem linii listami drukowalnych ciągów ASCII (zauważ, że oba mają jedno końcowe podawanie wiersza).

Wypróbuj online!

Przez jakiś czas wiedziałem, że transpozycja prostokątnych bloków byłaby uciążliwa dla siatkówki (podczas gdy transponowanie kwadratów nie jest takie złe), ale tak naprawdę nigdy nie próbowałem. Pierwsze rozwiązanie rzeczywiście miało aż 110 bajtów długości, ale po kilku istotnych zmianach w podejściu powstałe 45 bajtów nie jest tak złe, jak się spodziewałem (ale nadal ...). Wyjaśnienie nastąpi jutro.

Wyjaśnienie

Etap 1: Sortuj

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

Wykonuje to główną pracę polegającą na zmianie kolejności znaków na wejściu, ale ostatecznie psuje podział na linie. Co ciekawe, jeśli usuniemy , otrzymamy kod wymagany do transponowania kwadratowego wejścia.

Etapy sortowania (oznaczone przez O) działają w ten sposób: znajdują wszystkie dopasowania podanego wyrażenia regularnego (rzecz po `), a następnie sortują te dopasowania i umieszczają je ponownie w miejscach, w których znaleziono dopasowania. Tak się składa, że ​​wyrażenie regularne dopasowuje każdy pojedynczy znak: nieliniowe poprzez .(?<=(.*))alternatywę i liniowe przez . Dlatego sortuje wszystkie znaki na wejściu. Im bardziej interesujące jest to, co oni są klasyfikowane wg .

The $Opcja aktywuje „sortowania o trybie”, gdzie każda odpowiedź jest zastąpiony przez wzorzec podstawienia w drugiej linii, który jest następnie wykorzystywany do porównywania wyników. Ponadto #mówi Retinie, aby przekonwertowała wynik podstawienia na liczbę całkowitą i porównała te liczby całkowite (zamiast traktować je jak łańcuchy).

Wreszcie musimy przyjrzeć się wyrażeniu regularnemu i podstawieniu. Jeśli pierwsze alternatywne dopasowania (tzn. Dopasowaliśmy dowolny znak w jednej z linii), wówczas (?<=(.*))przechwytuje wszystko do tego znaku w tej linii w grupie 1. $.1We wzorcu podstawienia zastępuje to z długość grupy 1. Dlatego pierwszy znak w każdym ciągu staje1 , drugi staje się 2, trzeci staje się 3itd. Teraz powinno być jasne, jak to transponuje kwadratowe wejście: wszystkie pierwsze znaki linii są pierwsze i wszystkie kończą się na najwyższej linii, a następnie wszystkie drugie znaki kończą się w drugiej linii i tak dalej. Ale w przypadku tych prostokątnych danych wejściowych dopasowujemy również linie. Od grupy1nie jest używane w tym przypadku, podstawienie jest puste, ale dla celów #opcji jest to brane pod uwagę 0. Oznacza to, że wszystkie linie są sortowane do przodu.

Mamy teraz znaki w pierwszej kolejności (pierwszy znak każdego łańcucha, drugi znak każdego łańcucha itp.) I wszystkie linie na początku.

Etap 2: Mecz

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

Teraz musimy podzielić znaki na wiersze o odpowiedniej długości. Ta długość odpowiada liczbie linii na oryginalnym wejściu, co odpowiada liczbie linii, jakie mamy na początku łańcucha.

Podział odbywa się tutaj za pomocą etapu dopasowania, który po prostu wyszukuje wszystkie dopasowania podanego wyrażenia regularnego i używa !opcji drukowania tych dopasowań (domyślnie zamiast nich je policzymy). Zatem celem wyrażenia regularnego jest dopasowanie jednej linii na raz.

Zaczynamy od „liczenia” liczby za pomocą lookbehind (?<=(¶)*.*). Generuje jedno przechwytywanie w grupie 1dla każdego wysuwu linii z przodu.

Następnie dla każdego z tych ujęć dopasowujemy jedną postać (?<-1>.)+.

Martin Ender
źródło
4

kod maszynowy x86, 19 bajtów

W hex:

fc89d35651a401dee2fb91aa595e464a75f1c3

Dane wejściowe:: ECXliczba ciągów (n) EDX,: długość pojedynczego ciągu (m) ESI,: tablica ciągów wejściowych,: EDIbufor wyjściowy odbierający tablicę ciągów. Zakłada się, że tablica jest zdefiniowana jako char src[n][m+1]dla danych wejściowych i char dst[m][n+1]wyjściowych, a wszystkie łańcuchy są zakończone wartością 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
meden
źródło
3

Brachylog , 5 bajtów

z:ca.

Oczekuje listy ciągów jako danych wejściowych, np run_from_atom('z:ca.',["money":"taken":"trust"],Output).

Wyjaśnienie

z       Zip the strings in the Input list
 :ca.   output is the application of concatenation to each element of the zip
Fatalizować
źródło
3

05AB1E, 3 bajty

ø€J

Wyjaśniono

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

Wypróbuj online

Emigna
źródło
2

CJam , 3 bajty

{z}

Jest to blok kodu (równoważny funkcji; domyślnie dozwolony ), który oczekuje danych wejściowych na stosie i pozostawia dane wyjściowe na stosie.

Wypróbuj online!

Luis Mendo
źródło
Pewny tego?
DJMcMayhem
1
@Drgreeneggsandironman Cóż, odpowiedź z większą liczbą głosów mówi, że domyślnie powinny to być „programy lub funkcje”
Luis Mendo
2

JavaScript ES6, 48 46 bajtów

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

Czuję się pominięty, nie mamy wbudowanej funkcji zip. Dzięki nicael za wskazanie mojego błędu typu.

Stosowanie

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

zwroty

["ad","ss","da"]
charredgrass
źródło
Wyjątek: TypeError: a [0] .map nie jest funkcją
edc65
1
Potrzebujesz [...a[0]].map, ponieważ a[0]nie jest tablicą.
nicael
@nicael dzięki. pomieszane typy. to pokazuje, dlaczego nie powinienem grać w golfa tak wcześnie rano.
charredgrass,
@nicael Edytujełem .joinje, aby rozwiązać ten problem.
charredgrass
1
join`` zamiast join('')zapisać 2 bajty. Downvote wycofane
edc65
2

Narzędzia Bash + BSD, 27

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

I / O poprzez STDIN / STDOUT ciągi rozdzielone znakiem nowej linii.

Może być konieczne zainstalowanie za rspomocą sudo apt install rslub podobnego. Działa od razu w systemie OS X.

-TOpcja rsrobi dźwiganie ciężarów transpozycji. Reszta to po prostu formatowanie:

  • The sedPolecenie po prostu wstawia :po każdej postaci
  • -c:określa, że ​​kolumny wejściowe są :rozdzielone
  • -g0 określa, że ​​kolumny wyjściowe mają zerową szerokość separacji

Jeśli moje odczytanie strony rspodręcznika jest prawidłowe, poniższe wyniki powinny zadziałać dla wyniku 12, ale niestety nie działa - patrz uwaga poniżej:

rs -E -g0 -T

Przykładowe dane wyjściowe:

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

Jeśli oczekuje się, że wejście będzie w całości drukowalnym kodem ASCII, wówczas :można je zastąpić jakimś niedrukowalnym znakiem, np BEL. 0x7 .


Uwaga

Chciałem zrozumieć, dlaczego nie mogłem dostać -Eopcji pracy i pozbyć się sedwstępnego przetwarzania. Znalazłem rstutaj kod źródłowy . Jak widać, podanie tej opcji powoduje ustawienieONEPERCHAR flagi. Jednak w kodzie nie ma niczego, co faktycznie sprawdzałoby stan tej flagi. Myślę więc, że możemy powiedzieć, że pomimo tego, że opcja jest udokumentowana, nie została wdrożona.

W rzeczywistości ta opcja jest udokumentowana na stronie Linux rs:

-E Traktuj każdy znak wejściowy jako pozycję tablicy.

ale nie wersja OS X.

Cyfrowa trauma
źródło
2

PHP, 82 bajty

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

pobiera i zwraca tablicę ciągów

awaria

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

przykłady

$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>';
}
Tytus
źródło
2

APL, 3 bajty

↓⍉↑

pobiera ciągi wejściowe i przekształca je w macierz znaków. transponuje macierz. dzieli wiersze wynikowej macierzy na łańcuchy.

lstefano
źródło
1

Mathematica, 26 bajtów

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

Funkcja anonimowa. Pobiera listę ciągów jako dane wejściowe i zwraca listę ciągów jako dane wyjściowe. Znak Unicode to U + F3C7, reprezentujący \[Transpose]. Działa poprzez konwersję do matrycy znaków, transponowanie i konwersję z powrotem do listy ciągów. Gdyby format wejściowy / wyjściowy był rozciągnięty, działałaby prosta 5-bajtowa transpozycja:

#&
LegionMammal978
źródło
+1 pokonałeś mnie do bicia! (Ale nie mogłem użyć symbolu transpozycji.) A tak przy okazji, dlaczego T nie pojawia się na ekranie? (Jest tam, kiedy kopiuję twój kod do Mathematica).
DavidC
@DavidC Znak Unicode znajduje się w obszarze prywatnego użytku, który jest oznaczony jako sekcja dla znaków zastrzeżonych i dlatego nie jest oficjalnie przypisany glifowi ani w ogóle renderowany w większości czcionek. Czcionka Mathematiki po prostu renderuje ten znak jako indeks górny T i interpretuje go jako \[Transpose].
LegionMammal978
@DavidC Dlaczego nie używają ?
Adám
@ Adám IDK, musisz zapytać o to Wolfram Research, nie ja
LegionMammal978,
@ LegionMammal978 Nie, cieszę się, dopóki mam oczywiste APL-y .
Adám
1

MATLAB / Octave, 4 bajty

@(x)x'

Definiuje to anonimową funkcję. Format wejściowy to ['car'; 'dog'; 'man'; 'yay'].

Wypróbuj tutaj .

Luis Mendo
źródło
Jaki format ma dane wejściowe dla tego rozwiązania? Nie sądzę, że to będzie działać ze sposobu Matlab uchwyty ciągów jeśli spróbujesz wprowadzić je w sposób Matlabby, np f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}])wyjścia ans = „abcd” „abcd” „abcd”
sintax
@sintax Format wejściowy powinien być tablicą znaków 2D, jak w przykładzie podanym w odpowiedzi. Używasz tablic komórek ciągów (uzyskanych przez połączenie tablic komórek singletonów). Powinno być: f(['abcd';'abcd';'abcd']). Zredagowałem odpowiedź, aby określić format wejściowy
Luis Mendo
1

Haskell, 41 bajtów

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

Lub z odrobiną powietrza:

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

Druga lista to lista słów powtórzonych „długość słowa”. Na każdej liście słów wybieramy n-tą literę każdego słowa, podając wynik.

villou24
źródło
1
Pełny program nie jest potrzebny, ponieważ „program” oznacza „program lub funkcję” , więc funkcja wystarczy. Możesz przekazać i zwrócić listę ciągów, a zatem pomiń wordsi unwords. Ponadto map(\_->l)(l!!0)jest l<*l!!0, więc sprowadza się do \l->zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0.
nimi
Och, dziękuję :) Aktualizuję.
villou24
Ups, literówka: to l<$l!!0(pierwszy raz źle, drugi raz dobrze), ale i tak masz rację.
nimi
1

Common Lisp, 62 bajty

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

mapFunkcja przyjmuje typ wynik (tutaj list), to funkcja f stosowania i jedną lub więcej sekwencji s1 , ..., sn . Wszystkie sekwencje są iterowane równolegle. Dla każdej krotki elementów (e1, ..., en) pobranych z tych sekwencji wywołujemy (f e1 ... en) a wynik jest kumulowany w sekwencji pożądanego typu.

Bierzemy listę ciągów, powiedzmy ("car" "dog" "man" "yay"), i używamy applydo wywołania map. Musimy to zrobić, aby lista wejściowa była używana jako więcej argumentów map. Dokładniej:

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

... jest równa:

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

A ponieważ ciągi znaków są sekwencjami, iterujemy równolegle wszystkie pierwsze znaki, a następnie wszystkie drugie znaki itp. Na przykład pierwsza iteracja wywołuje f w następujący sposób:

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

Anonimowa lambda bierze listę podanych argumentów i zmusza ją z powrotem do łańcucha.

rdzeń rdzeniowy
źródło
1

Perl, 91 bajtów

Taki długi ...

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

Wypróbuj tutaj!

Swadhikar C.
źródło
0

Rubinowy, 46 bajtów

Prawdopodobnie po raz pierwszy „Rubinowe ciągi nie są Wyliczalne” w rzeczywistości mnie mocno gryzą, ponieważ przed przetworzeniem musiałem odwzorować ciągi na tablice. (Zwykle konieczność użycia String#charsnie wystarcza na utratę bajtu, żeby mieć znaczenie, ale ponieważ muszę je zmapować, to kłuje o wiele więcej)

->s{s.map!(&:chars).shift.zip(*s).map &:join}
Wartość tuszu
źródło
0

Clojure, 68 bajtów

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

Odwzorowuje funkcję, która po prostu reduce(przenosi elementy listy jeden po drugim i łączy n-ty znak ciągu) w zakresie od 0 do długości pierwszego ciągu.

Zobacz online: https://ideone.com/pwhZ8e

Cliffroot
źródło
0

C #, 53 bajty

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

C # lambda ( Func) gdzie wyjście jest, IList<string>a wyjście jest IEnumerable<string>. Nie wiem, jak działa zipw innym języku, ale nie mogę znaleźć sposobu na użycie C # tutaj. Aggregatedobrze pasują do potrzeb. Brak transpozycji w C #, jest jeden w Excelu, ale go nie użyję.

Wypróbuj online!

aloisdg przechodzi na codidact.com
źródło