Преобразуйте n строк длиной m в m строк длины n


16

Напишите программу, которая при любом количестве n строк длины m возвращает число m строк длины n с этим условием:

Каждая новая строка должна содержать буквы с одинаковым индексом других строк

Например, первая выходная строка должна содержать первую букву всех входных строк, вторая выходная строка должна содержать вторую букву всех входных строк и т. Д.

Примеры (цифры под буквами являются индексами строк):

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

Предположим, что ввод правильный каждый раз

Самый короткий код байтов выигрывает!

Редактировать:

Поскольку существует много языков программирования и может быть много возможных решений для каждого из них, я опубликую кратчайшее решение для каждого языка программирования и пользователя, который его предоставил. Продолжайте кодировать!

Re-Edit:

Благодаря пользователю Dennis я вставил фрагмент списка лидеров.


2
У нас есть фрагмент списка лидеров, который вы можете добавить в свое тело вопроса. Не нужно делать это вручную.
Деннис


Извините, я не знал, что это называется "транспонирование"
введите имя

6
Я не верю, что эти проблемы являются дубликатами из-за различий, связанных с рваным транспонированием и некоторой странной обработкой пробелов в другом вопросе. Хотя в некоторых языках ответы могут быть очень похожими, я думаю, что в большинстве они будут отличаться настолько, что это не должно быть дубликатом.
FryAmTheEggman

Ответы:



9

Python, 36 29 байт

zip(*s) возвращает список кортежей каждого символа, транспонированный.

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

Попробуйте онлайн


Выходные данные говорят "cdmy", "aoaa", "rgny", что это список ["cdmy", "aoaa", "rgny"]или кортеж("cdmy", "aoaa", "rgny")
mbomb007

map(''.join,zip(*s))также работает для преобразования строк (только для Python 2), а для Python 3 [*map(''.join,zip(*s))]работает afaik
Value Ink

@ KevinLau-notKenny также map(''.join,zip(*s))подходит для Python 3 - по умолчанию мы разрешаем итераторы / генераторы вместо списков.
Мего



7

PowerShell v2 +, 66 54 байта

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

Йо ... нет map, нет zip, нет transposeи т. Д., Так что мы можем кататься самостоятельно. Большой реквизит @DarthTwon для 12-байтового гольфа.

Принимает ввод $n, устанавливает forцикл. Инициализация устанавливается $xна 0, проверяется, есть ли в нашем слове буквы $n[0][$x], и мы увеличиваем $x++каждую итерацию.

Внутри цикла мы берем наш массив строк, направляем его во внутренний цикл, который выделяет соответствующий символ из каждого слова. Он инкапсулируется в a -joinдля формирования строки, и эта строка остается в конвейере. В конце выполнения строки в конвейере печатаются неявно.

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

1
Хорошо, вот ответы, которые я хотел увидеть;) Слишком просто писать, ,а не думать об ответе
Имя здесь

Использование время цикла может дополнительно сокращать это вниз: param($n)$x=0;while($n[0][$x]){-join($n|%{$_[$x]});$x++}. И здесь нет ошибок: D
ThePoShWolf

@DarthTwon Отлично. Или используйте forцикл для еще двух. ;-)
AdmBorkBork

Хм ... Я попробовал это, но не после того, как по-настоящему спустился по моей whileпетле. Хорошая работа, сэр!
ThePoShWolf

Можете ли вы использовать Linq в Powershell?
aloisdg переходит на codidact.com

7

Vim, 37 36 нажатий клавиш

Все остальные ответы скучны и используют скучные однобайтовые встроенные функции. Вот хакерский ответ, который делает все вручную, на языке, который даже не является языком программирования:

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

Объяснение:

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

Now, everything is good, but the buffer has some extra text left over. So we must:

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



4

Retina, 45 43 bytes

Byte count assumes ISO 8859-1 encoding.

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

The leading linefeed is significant. Input and output are linefeed-terminated lists of printable ASCII strings (note that both have a single trailing linefeed).

Try it online!

I knew for a while that transposing rectangular blocks would be a pain in Retina (whereas transposing squares isn't too bad), but never actually tried. The first solution was indeed a whopping 110 bytes long, but after several substantial changes in the approach, the resulting 45 bytes are by far not as bad as I suspected (but still...). Explanation will follow tomorrow.

Explanation

Stage 1: Sort

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

This does the main work of reordering the characters in the input, but it ends up messing up the separation into lines. Interestingly, if we remove the , we get the code required to transpose a square input.

Этапы сортировки (обозначенные как O) работают следующим образом: они находят все совпадения заданного регулярного выражения (вещь после `), а затем сортируют эти совпадения и повторно вставляют их в места, где были найдены совпадения. Как это происходит, это регулярное выражение соответствует каждому отдельному символу: не-переводы строк через .(?<=(.*))альтернативу и переводы строк через . Следовательно, он сортирует все символы на входе. Более интересная часть это то , что они сортируются по .

$Опция активирует «сортировки по» режиме, где каждый матч заменяется с шаблоном подстановки на второй линии, которая затем используется для сравнения совпадений. Кроме того, #велит Retina преобразовать результат подстановки в целое число и сравнить эти целые числа (вместо того, чтобы рассматривать их как строки).

Итак, наконец, нам нужно взглянуть на регулярное выражение и замену. Если первая альтернатива соответствует (то есть мы сопоставили любой символ в одной из строк), то (?<=(.*))захват захватывает все, вплоть до этого символа в этой строке, в группу 1. $.1В схеме замещения замещает это с длиной группы 1. Следовательно, первый символ в каждой строке становится 1, второй становится 2, третий становится 3и так далее. Теперь должно быть понятно, как это транспонирует квадратные входные данные: все первые символы строк идут первыми и все заканчиваются в самой верхней строке, затем все вторые символы заканчиваются во второй строке и так далее. Но для этих прямоугольных входов мы также подбираем перевод строки. С группой1 неиспользованным в этом случае, подстановка пуста, но для целей #опции это рассматривается 0. Это означает, что все переводы строки отсортированы на передний план.

Итак, теперь у нас есть символы первого порядка (первый символ каждой строки, второй символ каждой строки и т. Д.) И все переводы строк в начале.

Этап 2: Матч

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

Теперь нам нужно разделить символы на строки правильной длины. Эта длина соответствует количеству строк в исходном вводе, что соответствует количеству перевода строки, которое мы имеем в начале строки.

Разделение выполняется здесь с помощью этапа сопоставления, который просто находит все совпадения данного регулярного выражения и использует ! опцию для печати этих совпадений (по умолчанию вместо этого будет их подсчитываться). Таким образом, цель регулярного выражения - соответствовать одной строке за раз.

Мы начнем с «подсчета» числа со взглядом сзади (?<=(¶)*.*). Генерирует один захват в группе1 для каждого перевода строки на фронте.

Затем для каждого из этих снимков мы сопоставляем одного символа с (?<-1>.)+.


4

машинный код x86, 19 байт

В шестнадцатеричном виде:

fc89d35651a401dee2fb91aa595e464a75f1c3

Ввод:: ECX# строк (n) EDX,: длина отдельной строки (m) ESI,: массив входных строк,: EDIвыходной буфер, принимающий массив строк. Предполагается, что массив определяется как char src[n][m+1]для ввода, так и char dst[m][n+1]для вывода, а все строки имеют нулевое окончание.

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

Брахилог , 5 байт

z:ca.

Ожидает список строк в качестве ввода, например run_from_atom('z:ca.',["money":"taken":"trust"],Output).

объяснение

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

3

05AB1E, 3 байта

ø€J

Разъяснения

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

Попробуйте онлайн


2

CJam , 3 байта

{z}

Это блок кода (эквивалент функции; разрешен по умолчанию ), который ожидает ввод в стек и оставляет вывод в стек.

Попробуйте онлайн!



1
@Drgreeneggsandironman Ну, ответ с большим количеством голосов говорит, что по умолчанию должны быть «программы или функции»
Луис Мендо

2

JavaScript ES6, 48 46 байт

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

Я чувствую себя обделенным, у нас нет встроенной функции почтового индекса. Спасибо nicael за указание на мою ошибку типа.

использование

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

возвращается

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

Исключение: TypeError: a [0] .map не является функцией
edc65

1
Вам нужно [...a[0]].map, так как a[0]это не массив.
Никаэль

@nicael спасибо. перепутал типы. это доказывает, почему я не должен играть в гольф рано утром.
Charredgrass

@nicael Я редактировал .joinих, чтобы решить эту проблему.
Charredgrass

1
join`` вместо того, join('')чтобы сохранить 2 байта.
Downvote

2

Bash + BSD коммунальные услуги, 27

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

Ввод / вывод через строки STDIN / STDOUT, разделенные новой строкой.

Возможно, вам придется установить rsс sudo apt install rsили аналогичным. Работает из коробки на OS X.

-TВариант rsделает тяжелую работу в транспозиции. Остальное просто форматирование:

  • Команда sedпросто вставляет :после каждого символа
  • -c:указывает входные столбцы :разделены
  • -g0 определяет выходные столбцы с нулевым разделением по ширине

Если мое чтение rsсправочной страницы является правильным, то следующее должно работать для оценки 12, но, к сожалению, это не работает - см. Примечание ниже:

rs -E -g0 -T

Пример вывода:

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

Если ожидается, что все входные данные будут для печати ASCII, то :их можно заменить каким-нибудь непечатаемым символом, например, 0x7 BEL.


Заметка

Я хотел понять, почему я не мог получить -Eвозможность работать и избавиться от sedпредварительной обработки. Я нашел rsисходный код здесь . Как видите, установка этой опции устанавливает ONEPERCHARфлаг. Однако в коде нет ничего, что фактически проверяло бы состояние этого флага. Поэтому я думаю, что мы можем сказать, что, несмотря на то, что этот вариант задокументирован, он не реализован.

Фактически, эта опция задокументирована на rsman-странице Linux :

-E Рассматривать каждый символ ввода как запись массива.

но не версия OS X.


2

PHP, 82 байта

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

принимает и возвращает массив строк

сломать

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

Примеры

$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 байта

↓⍉↑

берет входные строки и превращает их в матрицу символов. транспонирует матрицу. разбивает строки результирующей матрицы на строки.



1

Mathematica, 26 байтов

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

Анонимная функция. Принимает список строк в качестве входных данных и возвращает список строк в качестве выходных. Символ Unicode - это U + F3C7, представляющий \[Transpose]. Работает путем преобразования в матрицу символов, транспонирования и преобразования обратно в список строк. Если формат ввода / вывода растягивается, то будет работать простая 5-байтовая транспонирование:

#&

+1 ты избил меня до удара! (Но я не смог использовать символ Transpose.) Кстати, почему T не появляется на экране? (Это там, когда я копирую твой код в Mathematica).
DavidC

@DavidC Символ Unicode находится в Частной области использования, которая помечена как раздел для проприетарных символов и поэтому официально не назначается глифу и не отображается вообще в большинстве шрифтов. Шрифт Mathematica просто отображает этот символ как надстрочный индекс T и интерпретирует его как a \[Transpose].
LegionMammal978

@DavidC Почему они не используют ?
Адам

@ Adám IDK, об этом нужно спросить у Wolfram Research, а не у меня
LegionMammal978

@ LegionMammal978 Нет, я счастлив, пока у меня есть очевидный APL .
Адам

1

MATLAB / Octave, 4 байта

@(x)x'

Это определяет анонимную функцию. Формат ввода есть ['car'; 'dog'; 'man'; 'yay'].

Попробуй это здесь .


Какой формат ввода для этого решения? Я не думаю, что это будет работать с тем, как Matlab обрабатывает строки, если вы попытаетесь ввести их способом Matlabby, например f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}])выводит ans = 'abcd' 'abcd' 'abcd'
синтаксис

@sintax Формат ввода должен быть двумерным массивом символов, как в примере, указанном в ответе. Вы используете массив строк (полученный путем объединения одноэлементных массивов ячеек). Оно должно быть: f(['abcd';'abcd';'abcd']). Я отредактировал ответ, чтобы указать формат ввода
Луис Мендо

1

Haskell, 41 байт

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

Или немного больше воздуха:

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

Второй список - это список слов, повторяющихся во времени «длина слова». В каждом списке слов мы выбираем n-ю букву каждого слова, давая результат.


1
Нет необходимости в полной программе, потому что «программа» означает «программа или функция» , поэтому функции достаточно. Вы можете передать и вернуть список строк и, следовательно, опустить wordsи unwords. Кроме того, map(\_->l)(l!!0)это l<*l!!0, так что это сводится к тому \l->zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0.
Ними

О, хорошо, спасибо :) Я обновляюсь.
villou24

Ой, опечатка: это l<$l!!0(первый раз неправильно, второй раз правильно), но ты все равно понял правильно.
Ними

1

Common Lisp, 62 байта

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

mapФункция принимает тип результата (здесь list), функция F , чтобы применить и один или более последовательности s1 , ..., Sn . Все последовательности повторяются параллельно. Для каждого набора элементов (e1, ..., en), взятых из этих последовательностей, мы называем (f e1 ... en) и результат накапливается в последовательности нужного типа.

Мы берем список строк, скажем, ("car" "dog" "man" "yay") , и используем applyдля вызова map. Мы должны сделать это так, чтобы входной список использовался как дополнительные аргументы map. Точнее, это:

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

... эквивалентно:

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

А поскольку строки являются последовательностями, мы выполняем параллельные итерации по всем первым символам, затем по всем вторым символам и т. Д. Например, вызовы первой итерации f следующим образом:

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

Анонимная лямбда берет список переданных ей аргументов и возвращает его обратно в строку.



0

Рубин, 46 байт

Вероятно, первый раз, когда "строки Ruby не являются перечисляемыми", на самом деле сильно кусает меня, поскольку мне пришлось преобразовывать строки в массивы перед обработкой. (Обычно необходимости использовать String#charsне достаточно для потери байтов, но, поскольку мне нужно отобразить их, это сильно укушает)

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

0

Clojure, 68 байт

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

Карты функция, которая просто reduce (идет по элементам списка один за другим и присоединяет n-й символ строки) в диапазоне от 0 до длины первой строки.

Смотрите это онлайн: https://ideone.com/pwhZ8e


0

C #, 53 байта

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

C # lambda ( Func), где вывод IList<string>и вывод IEnumerable<string>. Я не знаю, как работать zipна другом языке, но я не могу найти способ использовать C # здесь.Aggregateхорошо подходит. Нет транспонирования в C #, есть один в Excel , но я не буду использовать его.

Попробуйте онлайн!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.