Гольф струнний твістер


24

Як закручуються струни

Алгоритм скручування дуже простий. Кожен стовпець зміщується вниз за своїм індексом (col 0 рухається вниз 0, col 1 рухається 1, ...). Зсув стовпчика завершується до верху Це працює так:

aaaa
bbbb
cccc

Стає:

a
ba
cba
----
 cba
  cb
   c

З усім під лінією, що загортається до верху. Реальний приклад:

Original:
\\\\\\\\\\\\
............
............
............

Twisted:
\...\...\...
.\...\...\..
..\...\...\.
...\...\...\

Вхідні дані

Введення - це або масив рядків, або багаторядковий рядок. Всі лінії мають однакову довжину.

Вихідні дані

Скручена рядок, багаторядковий вихід на std-out (або найближчу альтернативу).

Приклади:

( >позначає вхід, важливий простір)

>Hello, world!
>I am another 
>string to be 
>twisted!     

Hwrmoe oo br!
Ieii ,dttr e 
s lsna !ohl  
ttaltgnw  ed 


>\\\\\\\\\\\\
>............
>............
>............

\...\...\...
.\...\...\..
..\...\...\.
...\...\...\


>abcdefg
>.......

a.c.e.g
.b.d.f.


>abcdefghij
>..........
>..........

a..d..g..j
.b..e..h..
..c..f..i.


>\\\\.....././
>...../.......
>........././.
>..../.^\\....

\.........../
.\....^..../.
..\../.\../..
...\/...\/...

>cdeab
>deabc
>eabcd
>abcde

cbbbb
ddccc
eeedd
aaaae


>aeimquy37
>bfjnrvz48
>cgkosw159
>dhlptx260

ahknqx147
beloru258
cfipsvy69
dgjmtwz30


>abcdefghi
>jklmnopqr
>stuvwxyz1
>234567890

a3ume7yqi
jb4vnf8zr
skc5wog91
2tld6xph0

12
Для цього краще не бути вбудованою Mathematica.
Mama Fun Roll

1
Чи можна припустити, що вхід буде містити лише ASCII? Або тільки друковані рядки ASCII + або інші?
Мартін Ендер

Так, просто ASCII та новий рядок (якщо ви не приймаєте введення як масив).
J Atkin

Відповіді:


3

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

iᵇ↻₎ᵐ

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

Отримує введення як масив стовпців (що, здається, знаходиться в специфікаціях питання).

iᵇ- Для кожного елемента в масиві з’єднайте його з його (на основі 0) індексом
- прив'язуйте цей предикат до кожного елемента результату:
↻₎- перестановка (стовпець) по колу на величину, вказану як останній елемент (індекс)

Легко поширюється на версію, яка приймає одну багаторядкову рядок:

13 байт

ṇẹ\iᵇ↻₎ᵐ\cᵐ~ṇ

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


Це дивовижне стиснення інформації.
Дж. Аткін

7

Піта, 11

jC.>R~hZC.z

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

jC.>R~hZC.z    ##  implicit: .z = list of input split by lines
        C.z    ##  transpose .z to get columns
  .>R~hZ       ##  shift each column by it's index
               ##  equivalent to .e.>bk
jC             ##  transpose back and join by newlines

7

APL (Dyalog) , 7 байт

⊖⊖⊖⍨⍬⍋⍉

Вимагає ⎕io←0

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

⍬⍋⍉отримує діапазон від 0 до кількості стовпців,
реверсує вертикально
⊖⊖⍨⍬⍋⍉обертати (вертикально) (вертикально) повернутий вхід 0,1..
зворотним, і повернути його.


6

Сітківка , 111 101 92 87 байт

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

(?<=((.))*)(?=(?<1>.*¶)*.*(?<=(?=(?<-2>.)*(.))(?<-1>.+¶)*.*(.(?<=^(?<-1>¶?.+)*))*)).
$3

Ву, вирішив це однією заміною регулярного виразу. :) (Швидше за все, є коротше рішення, використовуючи декілька, але де цікаво в цьому ...)

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

Пояснення

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

(?<=((.))*)

Це натискає на одне захоплення для обох груп 1та 2для кожного символу перед матчем (у поточному рядку). Тобто, він рахує горизонтальне положення сірника.

Решта знаходиться в пошуку:

(?=(?<1>.*¶)*.* [...] )

Ми співставляємо кожен рядок і також висуваємо його на групу 1, так що група 1тепер є сумою горизонтального та вертикального положення (де останній рахується знизу ). Це, по суті, позначає діагоналі сітки із збільшенням значень, починаючи з нижнього лівого кута. Це .*потім просто переміщує курсор двигуна до кінця рядка.

Тепер ми переходимо на погляд, який узгоджується справа наліво .NET:

(?<= [...] (.(?<=^(?<-1>¶?.+)*))*)

Це буде неодноразово з'являтися точно Hвловлює з групи 1(де Hвисота вводу). Мета цього - взяти груповий модуль H. Потім група 1містить рядок (відлічується знизу), з якого слід вибрати новий символ у поточному стовпці.

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

Ще один погляд позаду, знову починаючи праворуч. (?<-1>.+¶)*.+тепер використовує групу 1для пошуку рядка, з якого вибирає новий символ, а потім lookahead знаходить правильний стовпець за допомогою групи 2.

Бажаний символ переймається в групу 3і списується за допомогою підстановки.


Ах, читання джерела Retina було приємним і зрозумілим :) $+виглядає корисним ... особливо якщо ви хочете зробити лише одну заміну: ^)
FryAmTheEggman

@FryAmTheEggman $+насправді досить марний ... його опис на MSDN звучить набагато корисніше, ніж це тому, що це означає, що (a)|(b)-> $+$+подвоїть всі as і bs, але замість цього він видаляє всі as, тому що він просто відноситься до синтаксично останньої групи . Це означає, що це просто спосіб уникнути підрахунку всіх груп, якщо ви занадто ліниві (як я). Для гри в гольф він дозволяє економити лише байти, якщо у вас більше 9 груп, що, мабуть, досить рідко.
Мартін Ендер

Це прикро ... Можливо, сітківка могла б мати новий тип групи заміщення, який би повертав останню непусту групу матчу? У будь-якому випадку, дякую за пояснення! :)
FryAmTheEggman

@FryAmTheEggman Це буде (це одна з речей, про які я мав на увазі, коли переписував Regex.Replaceдля Retina, але я ще не доходив до його реалізації).
Мартін Ендер

4

CJam, 13 байт

qN/zee::m>zN*

Перевірте це тут.

Пояснення

q    e# Read all input.
N/   e# Split into lines.
z    e# Transpose to get an array of columns.
ee   e# Enumerate, pairing each column with its index.
::m> e# Map: fold: rotate (cyclically shifting each column by its index).
z    e# Transpose again.
N*   e# Join with linefeeds.

2
Ви можете майже вимовити цей вихідний код.
mınxomaτ

4

TeaScript, 10 байт

xHl@C(r╢tD

Завдяки надзвичайно лаконічному синтаксису TeaScript 3, це справді коротко: D

Був би на 1 байт коротшим, якби цикл Sigma не був баггі

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

Пояснення

      // Implicit, x = input
xH    // Transpose input
l@    // Loop
 C(r╢   // Cycle column by index
        // `╢` exits loop
t    // Transpose
D    // Join on \n

3

Пітон 3, 164 байти

Не найкраща відповідь з дальнього пострілу, але перша в Python ...

s=list(zip(*open(0).readlines()))[:-1]
r=[[s[i][(j-i)%len(s[i])] for j in range(len(s[i]))] for i in range(len(s))]
print('\n'.join([''.join(l) for l in zip(*r)]))

1
Ви можете зберегти жменю байтів, )]''.join(l)for l in....
вийнявши

3

MATLAB, 92 36 байт

s=bsxfun(@circshift,s,0:size(s,2)-1)

Якщо припустити, що вхідний рядок sвже має форму двовимірного масиву / матриці, наприклад,

s = ['abcdefg';'.......'];
s = ['\\\\.....././';'...../.......';'........././.';'..../.^\\....'];

Пояснення: повторіть стовпці матриці. Для кожного стовпця виконайте круговий зсув його елементів на кількість символів, що дорівнює індексу стовпців (-1 через індексацію MATLAB).


2

Брахілог , 96 байт

$\:0{h_.|[M:I]hh:I{bh0,?h.|[C:I]h$)D,I-1=:Dr:2&.}C,I+1=J,Mb:J:1&:[C]rc.}$\{hA,[A]:"~s
"w,?b:3&;}

Тут очікується список рядків кодів символів як вхідний, а не вихідний, наприклад brachylog_main([`aaaa`,`bbbb`,`cccc`],_).

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

Пояснення

§ Main Predicate

$\:0{}$\{}                            § Create a list containing the transposed input and 0
                                      § Call sub-predicate 1 with this list as input
                                      § Transpose its output and pass it as input to
                                      § sub-predicate 3


§ Sub-predicate 1

h_.                                   § If the matrix is empty, output is empty list
   |                                  § Else
    [M:I]hh:I{}C,                     § Input is [M,I], call sub-predicate 2 with the first
                                      § line of M and I as input. Its output is C.
                 I+1=J,Mb:J:1&        § Call sub-predicate 1 with M minus the first line
                                      § and I+1 as input
                              :[C]rc. § Its output is appended after C, which is then
                                      § unified with the output of sub-predicate 1.


§ Sub-predicate 2

bh0,?h.                               § If the second element of the input list is 0,
                                      § output is the first element of the input
       |                              § Else
        [C:I]                         § Input is [C,I]
             h$)D,                    § Perform a circular permutation of C from left to
                                      § right (e.g. [a,b,c] => [c,a,b]) and unify it with D
                  I-1=:Dr:2&.         § Call sub-predicate 2 with D and I-1 as input, unify
                                      § its output with sub-predicate 2's output


§ Sub-predicate 3

hA,[A]:"~s\n"w,                       § Write the first line of the input as a char codes
                                      § string followed by a new line

               ?b:3&;                 § Call sub-predicate 3 with input minus the first
                                      § line. If it fails (empty input), terminate

2

JavaScript, 92 89 байт

3 байти від спасибі @Neil .

s=>(z=s.split`
`).map((m,i)=>m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j])).join`
`


Ви можете зберегти 3 байта з допомогою replace: m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j]).
Ніл

1
Дійсно, [...m].map(весь шлях до першого і включаючи його .join.
Ніл

2

Python 2, 115 байт

lambda s:'\n'.join("".join(s)for s in zip(*[k[-i%len(k):]+k[:-i%len(k)]for i,k in enumerate(zip(*s.split('\n')))]))

Завдяки диву zipвдалося звести це до однієї лінії. Дивіться це в дії тут .


2

MATL , 18 21 байт

Zy2):"G@Z)@qYS]N$h

Введення має форму

['Hello, world!'; 'I am another '; 'string to be '; 'twisted!']

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

Як це працює :

Zy       % implicitly take input: 2D char array. Get its size
2)       % second element from size vector: number of columns, say n
:        % create vector [1,2,...,n]
"        % for each element k in that vector
  G      %   push input
  @      %   push k
  Z)     %   k-th column from input
  @qYS   %   circularly shift k-1 positions
]        % end for loop
N$h      % concatenate all stack contents horizontally
         % implicitly display

1

F #, 105 байт

Мій перший удар по ньому (потрібен лише \nсимвол):

let m x y=(x%y+y)%y
let f(a:string[])=Array.mapi(fun i x->String.mapi(fun j _->a.[m(i-j)a.Length].[j])x)a

Використання:

f [| @"\\\\\\\\\\\\"
     "............"
     "............"
     "............" |]

Я не думаю, що раніше я бачив F # на PPCG.
J Atkin

1

JavaScript (ES6), 73 байти

t=>t.replace(/./g,(_,i)=>t[(i+s*l-i%l*l)%s],l=t.search`
`+1,s=t.length+1)

Пояснення

t=>
  t.replace(/./g,(_,i)=> // replace each character at index i
    t[                   // get the character at index:
      (i                 // start at i
        +s*l             // add s*l to ensure the result is always positive for %s
        -i%l*l           // move the index upwards the num of chars from start of the line
      )%s                // shift the index into the the range of s
    ],
    l=t.search`
`+1,                     // l = line length
    s=t.length+1         // s = input grid length (+1 for the missing newline at the end)
  )

Тест


1

Japt, 29 байт

Uy £XsV=(Y*Xl -Y %Xl)+X¯V}R y

Перевірте це в Інтернеті!

Як це працює

Uy        // Transpose rows and columns in the input string.
£     }R  // Map each item X and index Y in the result, split at newlines, to:
Y*Xl -Y   //  Take Y times X.length and subtract Y.
%Xl)      //  Modulate the result by X.length.
XsV=      //  Set V to the result of this, and slice off the first V chars of X.
+X¯V      //  Concatenate this with the first V chars of X.
y         // Transpose the result again.
          // Implicit: output last expression

1

Haskell, 81 байт

let t=transpose in t.snd.mapAccumR(\c l -> 1+c,take(length l)(drop c$cycle l))0.t

повторне втілення прикладу CJam, хоча зворотне, відображення та перерахування є частиною mapAccumR, snd видаляє акумулятор, оскільки він нам більше не потрібен, повернення - лише побічний ефект правої складки.


1

Haskell, 65 байт

g l@("":_)=l;g l|t<-tail<$>l=zipWith(:)(head<$>l)$g$last t:init t

Приклад використання: g ["1111","2222","3333"]-> ["1321","2132","3213"].


1

MATL , 9 байт

"@X@qYS&h

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

Досить схожий за своєю суттю на існуючу відповідь MATL Луїса Мендо , але коротший за допомогою функцій, які, мабуть, не були в мові в той момент: 1. "зараз автоматично відбувається ітерація через стовпці матриці, тож жодних витрат на побудову індексів стовпців та індексації в них ( це Biggie), 2. &hяк короткий спосіб висловлювання N$h, і 3. неявний кінець циклу, якщо ]не вказано.

По черзі, для того ж самого рахунку:

tsn:ql&YS

Спробуйте це на MATL Online

      &YS   % circularly shift the matrix
     l      % across rows (i.e. shift each column) by the amounts
            %  given by this array:
tsn         % duplicate input, get the sum of each column, get the 
            %  number of elements in that (which is the number of columns)
   :q       % construct range 1 to ncols, then decrement to start at 0
            % (implicit output)

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