Перетворити 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

Припустимо, що введення кожного разу правильне

Код найкоротших байтів виграє!

Редагувати:

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

Повторне редагування:

Завдяки користувачеві Деннісу я вставив фрагмент для таблиць лідерів.


2
У нас є фрагмент таблиці лідерів, який ви можете додати до свого питання. Не потрібно робити це вручну.
Денніс


Вибачте, я не знав, що це називається "транспонінг"
ім'я вводу сюди

6
Я не вважаю, що ці виклики є дублюючими, через розбіжності, пов'язані з нерівним переміщенням та деякими дивними обробками пробілів в іншому питанні. Хоча в деяких мовах відповіді можуть бути дуже схожими, я думаю, що в більшості вони будуть досить різними, що це не повинно бути дублікатом.
FryAmTheEggman

Відповіді:



9

Пітон, 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

Вім, 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

Зараз все добре, але в буфері залишилось зайвий текст. Отже, ми повинні:

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



4

Сітківка , 45 43 байт

Кількість байтів передбачає кодування ISO 8859-1.

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

Провідна передача ліній є значною. Введення та виведення - це списки, що закінчуються підведенням ліній до друкованих рядків ASCII (зауважте, що обидва мають один зворотний податок рядків).

Спробуйте в Інтернеті!

Я деякий час знав, що перенесення прямокутних блоків буде болем у Сітківці (тоді як перенесення квадратів не надто погано), але ніколи насправді не намагався. Перше рішення справді було колосальним в 110 байт, але після декількох істотних змін у підході, отримані 45 байт далеко не такі погані, як я підозрював (але все ж ...). Пояснення будуть наступними завтра.

Пояснення

1 етап: Сортування

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

Це виконує основну роботу щодо переупорядкування символів у вхідних даних, але це закінчує змішання поділу на рядки. Цікаво, що якщо ми видалимо , ми отримаємо код, необхідний для перенесення квадратного вводу.

Етапи сортування (позначені символом 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]для виводу, а всі рядки закінчуються 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

Брахілог , 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


2

CJam , 3 байти

{z}

Це блок коду (еквівалентний функції; дозволений за замовчуванням ), який очікує введення в стеку і залишає вихід на стеку.

Спробуйте в Інтернеті!



1
@Drgreeneggsandironman Ну, відповідь з більшою кількістю голосів говорить, що за замовчуванням повинні бути "програми чи функції"
Луїс Мендо

2

JavaScript ES6, 48 46 байт

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

Мені здається, у нас немає вбудованої функції zip. Дякую 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

@nicael спасибі переплутали типи. це доводить, чому я не повинен займатися гольфом рано вранці.
chargragrass

@nicael Я .joinредагував їх, щоб виправити цю проблему.
charredgrass

1
join`` замість того, join('')щоб зберегти 2 байти. Downvote відступив
edc65

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прапор. Однак у коді немає нічого, що фактично перевіряє стан цього прапора. Тож я думаю, що можна сказати, що незважаючи на те, що варіант є документально зафіксованим, він не реалізований.

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

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

↓⍉↑

приймає вхідні рядки та перетворює їх у матрицю char. транспонує матрицю. розбиває назад рядки отриманої матриці на рядки.



1

Математика, 26 байт

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

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

#&

+1 ти побив мене до удару! (Але я не зміг використати символ Transpose.) До речі, чому T не відображається на екрані? (Це там, коли я копіюю ваш код в Mathematica).
DavidC

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

@DavidC Чому вони не використовують ?
Адам

@ Adám IDK, вам доведеться запитати про це дослідження Wolfram, а не я
LegionMammal978

@ LegionMammal978 Ні, я щасливий, доки я маю очевидні APL .
Adám

1

MATLAB / Октава, 4 байти

@(x)x'

Це визначає анонімну функцію. Формат вводу є ['car'; 'dog'; 'man'; 'yay'].

Спробуйте тут .


Який формат вхід для цього рішення? Я не думаю, що це буде працювати з тим, як Matlab обробляє рядки, якщо ви спробуєте ввести їх Matlabby, наприклад f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}])виводить ans = 'abcd' 'abcd' 'abcd'
sintax

Формат введення @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

Лист звичайний, 62 байти

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

The 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 # лямбда ( Func), де вихід IList<string>і вихід IEnumerable<string>. Я не знаю, як працювати zipна іншій мові, але я не можу знайти спосіб використовувати один із C # тут. Aggregateдобре підходити до потреби. У C # немає перенесення, в Excel є такий, але я не буду його використовувати.

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.