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


24

Как скручиваются струны

Алгоритм скручивания очень прост. Каждый столбец смещен вниз на свой индекс (столбец 0 перемещается вниз на 0, столбец 1 перемещается на 1, ...). Сдвиг столбца переносится наверх. Это работает так:

aaaa
bbbb
cccc

становится:

a
ba
cba
----
 cba
  cb
   c

Со всем под линией обтекания наверх. Реальный пример:

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

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

вход

Входные данные - это либо массив строк, либо многострочная строка. Все строки имеют одинаковую длину.

Выход

Скрученная строка, многострочный вывод на стандартный вывод (или ближайший вариант).

Примеры:

( >обозначает ввод, конечный пробел важен)

>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 Аткин

Ответы:


3

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

iᵇ↻₎ᵐ

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

Получает входные данные в виде массива столбцов (что, по-видимому, соответствует спецификации вопроса).

iᵇ- Для каждого элемента в массиве
сопоставьте его с индексом (на основе 0) - сопоставьте этот предикат с каждым элементом результата:
↻₎- перестановка (столбец) по кругу на сумму, указанную в качестве последнего элемента (индекса)

Легко распространяется на версию, которая принимает одну многострочную строку:

13 байт

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

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


Это удивительное сжатие информации.
Дж Аткин


7

APL (Дьялог) , 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чтобы найти строку, из которой нужно выбрать нового персонажа, а затем поисковый запрос находит правильный столбец, используя группу 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

Python 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.
Дж Аткин

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, хотя reverse, map и enumerate являются частью 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. "Теперь автоматически выполняется итерация по столбцам матрицы, поэтому нет необходимости в дорогостоящем построении индексов столбцов и индексации в них ( это важная персона), 2.&h как сокращенный способ сказать N$h, и 3. неявный конец цикла, если ]не указан.

Альтернативно для того же bytecount:

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)

0

C (лязг) , 114 байтов

Работает в GCC под MinGW. GCC TIO запутывается при использовании strlenв выражении init первого цикла for.

f(L,n)char**L;{for(int l=strlen(*L),i=0,j,c;i<n;i++)for(j=c=0;j<=l;j++,c=c?c-1:n-1)putchar(l^j?L[(c+i)%n][j]:10);}

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

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