# Golf a string twister

## How strings are twisted

The twisting algorithm is very simple. Each column is shifted down by its index (col 0 moves down 0, col 1 moves 1, ...). The column shift wraps to the top. It works like this:

aaaa
bbbb
cccc


Becomes:

a
ba
cba
----
cba
cb
c


With everything under the line wrapping to the top. Real example:

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

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


## Input

Input is either an array of strings, or a multi-line string. All lines have the same length.

## Output

The twisted string, multi-line output to std-out (or closest alternative).

## Examples:

(> denotes input, trailing space is important)

>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

• There better not be a Mathematica builtin for this. – Mama Fun Roll Feb 1 '16 at 16:38
• Can we assume that the input will only contain ASCII? Or only printable ASCII + linefeeds or something? – Martin Ender Feb 1 '16 at 19:10
• Yes, just ASCII and newline (unless you take input as an array). – J Atkin Feb 1 '16 at 19:22

# Brachylog, 5 bytes

iᵇ↻₎ᵐ


Try it online!

Gets input as an array of columns (which seems to be within the question's specifications).

iᵇ - For each element in the array, pair it with its (0-based) index
ᵐ - map this predicate to each element of the result:
↻₎ - permute (the column) circularly by the amount specified as the last element (the index)

Easily extended to a version that accepts a single multiline string:

### 13 bytes

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


Try it online!

• This is amazing information compression. – J Atkin Oct 27 '18 at 15:50

# Pyth, 11

jC.>R~hZC.z


Try it here

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


# APL (Dyalog), 7 bytes

⊖⊖⊖⍨⍬⍋⍉


Requires ⎕io←0

Try it online!

⍬⍋⍉ gets the range from 0 to the number of columns
⊖ reverses vertically
⊖⊖⍨⍬⍋⍉ rotate (vertically) the (vertically) reversed input by 0,1..
⊖ reverse that, and return it.

## Retina, 11110192 87 bytes

Byte count assumes ISO 8859-1 encoding.

(?<=((.))*)(?=(?<1>.*¶)*.*(?<=(?=(?<-2>.)*(.))(?<-1>.+¶)*.*(.(?<=^(?<-1>¶?.+)*))*)).
• @FryAmTheEggman $+ is actually pretty useless... it's description on MSDN sounds a lot more useful than it is because it implies that (a)|(b) --> $+$+ would double all as and bs but instead it removes all as, because it just refers to the syntactically last group. That means it's just a way to avoid counting all groups if you're too lazy (like I was). For golfing it only saves bytes when you have more than 9 groups, which is probably quite rare to begin with. – Martin Ender Feb 1 '16 at 18:27 • That is unfortunate... Perhaps retina could have a new replacement group type that would return the last non-empty match group? Anyway, thanks for the explanation! :) – FryAmTheEggman Feb 1 '16 at 18:55 • @FryAmTheEggman It will (it's one of the things I had in mind when rewriting Regex.Replace for Retina, but I didn't get around to implementing it yet). – Martin Ender Feb 1 '16 at 19:05 ## CJam, 13 bytes qN/zee::m>zN*  Test it here. ### Explanation 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.  • You can almost pronounce that source code. – mınxomaτ Feb 1 '16 at 17:12 # TeaScript, 10 bytes xHl@C(r╢tD  Thanks to TeaScript 3's extremely concise syntax, this is really short :D Would be 1-byte shorter if Sigma loop weren't buggy Try it online ## Explanation  // Implicit, x = input xH // Transpose input l@ // Loop C(r╢ // Cycle column by index // ╢ exits loop t // Transpose D // Join on \n  # Python 3, 164 bytes Not the best answer by a long shot, but the first in 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)]))  • You can save a handful of bytes by taking out the space which follows a ) or ] in most cases, for example ''.join(l)for l in.... is perfectly valid – wnnmaw Feb 1 '16 at 20:22 # MATLAB, 92 36 bytes s=bsxfun(@circshift,s,0:size(s,2)-1)  Assuming that the input string s is already in the form of a 2D char array/ matrix, e.g. s = ['abcdefg';'.......']; s = ['\\\\.....././';'...../.......';'........././.';'..../.^\\....'];  Explanation: iterate through the columns of the matrix. For each column perform a circular shift of its elements by the number of characters that equals the column index (-1 because of MATLAB indexing). # Brachylog, 96 bytes $\: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&;}


This expects a list of character codes strings as input and no output, e.g. brachylog_main([aaaa,bbbb,cccc],_).

That's one ridiculously long answer, and there's probably a much shorter way to do it.

### Explanation

§ 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  # JavaScript, 92 89 bytes 3 bytes off thanks @Neil. s=>(z=s.split ).map((m,i)=>m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j])).join   f=s=> (z=s.split\n).map((m,i)=> m.replace(/./g,(n,j)=> z[((l=z.length)*j+i-j)%l][j] ) ).join\n Input.value = abcdefghij .......... .......... textarea{display:block;width:250px;height:75px;} <textarea id='Input'></textarea> <button id='Run' onClick='Output.value=f(Input.value);'>Run</button> <textarea id='Output'></textarea> • You can save 3 bytes using replace: m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j]). – Neil Feb 1 '16 at 19:07 • Indeed, the [...m].map( all the way to and including the first .join. – Neil Feb 1 '16 at 19:15 # Python 2, 115 bytes 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')))]))  Thanks to the wonder of zip managed to get this down to one line. See it in action here. # MATL, 18 21 bytes Zy2):"G@Z)@qYS]N$h


Input is of the form

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


Try it online!

How it works:

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  # F#, 105 bytes My first stab at it (only a \n character is required): 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  Usage: f [| @"\\\\\\\\\\\\" "............" "............" "............" |]  • I don't think I have seen F# before on PPCG. – J Atkin Feb 2 '16 at 14:07 # JavaScript (ES6), 73 bytes t=>t.replace(/./g,(_,i)=>t[(i+s*l-i%l*l)%s],l=t.search +1,s=t.length+1)  ## Explanation 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) )  ## Test var solution = t=>t.replace(/./g,(_,i)=>t[(i+s*l-i%l*l)%s],l=t.search +1,s=t.length+1) <textarea id="input" rows="5" cols="40">\\\\.....././ ...../....... ........././. ..../.^\\....</textarea><br> <button onclick="result.textContent=solution(input.value)">Go</button> <pre id="result"></pre> # Japt, 29 bytes Uy £XsV=(Y*Xl -Y %Xl)+X¯V}R y  Test it online! ### How it works 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  # Haskell, 81 bytes let t=transpose in t.snd.mapAccumR(\c l -> 1+c,take(length l)(drop c$cycle l))0.t


reimplementation of the CJam example, though the reverse, map and enumerate is part of the mapAccumR, the snd removes the accumulator since we don't need it anymore, the reversal is just a side effect of the right fold.

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


Usage example: g ["1111","2222","3333"] -> ["1321","2132","3213"].

# MATL, 9 bytes

"@X@qYS&h


Try it online!

Pretty similar in core to Luis Mendo's existing MATL answer, but shorter by using features that were probably not in the language at that point: 1. " iterates through a matrix's columns automatically now, so no costly business of constructing column indices and indexing into them (this is the biggie), 2. &h as a shorthand way of saying N\$h, and 3. implicit loop end if ] is not specified.

Alternately, for the same bytecount:

tsn:ql&YS


Try it on 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)


# C (clang), 114 bytes

Works in GCC under MinGW. TIO's GCC gets confused by using strlen in the init expression of the first for loop.

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


Try it online!