Golf string twister

24

Bagaimana string dipelintir

Algoritma memutar sangat sederhana. Setiap kolom digeser ke bawah oleh indeksnya (col 0 bergerak turun 0, col 1 bergerak 1, ...). Pergeseran kolom terbungkus ke atas. Ini berfungsi seperti ini:

aaaa
bbbb
cccc

Menjadi:

a
ba
cba
----
 cba
  cb
   c

Dengan segala sesuatu di bawah garis yang membungkus ke atas. Contoh nyata:

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

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

Memasukkan

Input adalah array dari string, atau string multi-line. Semua garis memiliki panjang yang sama.

Keluaran

Twisted string, output multi-line ke std-out (atau alternatif terdekat).

Contoh:

( >menunjukkan input, spasi tambahan penting)

>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
J Atkin
sumber
12
Lebih baik tidak dibangun Mathematica untuk ini.
Mama Fun Roll
1
Bisakah kita berasumsi bahwa input hanya akan mengandung ASCII? Atau hanya ASFII + linefeeds yang dapat dicetak atau semacamnya?
Martin Ender
Ya, hanya ASCII dan baris baru (kecuali jika Anda mengambil input sebagai array).
J Atkin

Jawaban:

3

Brachylog , 5 byte

iᵇ↻₎ᵐ

Cobalah online!

Mendapat input sebagai array kolom (yang tampaknya berada dalam spesifikasi pertanyaan).

iᵇ- Untuk setiap elemen dalam array, pasangkan dengan indeks (berbasis-0)
- petakan predikat ini untuk setiap elemen dari hasil:
↻₎- permute (kolom) secara melingkar dengan jumlah yang ditentukan sebagai elemen terakhir (indeks)

Mudah diperluas ke versi yang menerima string multiline tunggal:

13 byte

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

Cobalah online!

sundar - Pasang kembali Monica
sumber
Ini adalah kompresi informasi yang luar biasa.
J Atkin
7

Pyth, 11

jC.>R~hZC.z

Coba di sini

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
FryAmTheEggman
sumber
7

APL (Dyalog) , 7 byte

⊖⊖⊖⍨⍬⍋⍉

Membutuhkan ⎕io←0

Cobalah online!

⍬⍋⍉mendapatkan rentang dari 0 hingga jumlah kolom
membalikkan
⊖⊖⍨⍬⍋⍉memutar secara vertikal (vertikal) input (terbalik) terbalik dengan 0,1..
membalikkannya, dan mengembalikannya.

H.Piz
sumber
6

Retina , 111 101 92 87 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

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

Woo, menyelesaikannya dalam substitusi regex tunggal. :) (Kemungkinannya adalah, ada solusi yang lebih pendek dengan menggunakan beberapa, tapi di mana asyiknya ...)

Cobalah online!

Penjelasan

Ini membutuhkan pengetahuan dasar tentang menyeimbangkan kelompok . Singkatnya, rasa .NET memungkinkan Anda untuk menangkap beberapa kali dengan satu kelompok, mendorong semua tangkapan ke tumpukan. Tumpukan itu juga dapat muncul, yang memungkinkan kita menggunakannya untuk menghitung hal-hal di dalam regex.

(?<=((.))*)

Ini mendorong satu tangkapan ke kedua kelompok 1dan 2untuk setiap karakter di depan pertandingan (di baris saat ini). Artinya, itu menghitung posisi horizontal pertandingan.

Sisanya ada di lookahead:

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

Kami mencocokkan setiap baris dan juga mendorongnya ke grup 1, sehingga grup 1tersebut sekarang merupakan jumlah posisi horizontal dan vertikal (di mana yang terakhir dihitung dari bawah ). Ini pada dasarnya memberi label diagonal grid dengan nilai yang meningkat mulai dari sudut kiri bawah. Itu .*kemudian hanya memindahkan kursor mesin ke ujung string.

Kami sekarang beralih ke tampilan di belakang, yang dicocokkan dari kanan ke kiri di .NET:

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

Berulang kali ini akan Hmenangkap dengan tepat dari grup 1(di mana Hketinggian input) Tujuannya adalah untuk mengambil modulo grup H. Setelah itu, grup 1berisi baris (dihitung dari bawah) untuk memilih karakter baru di kolom saat ini.

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

Terlihat lagi di belakang, lagi mulai dari kanan. (?<-1>.+¶)*.+sekarang menggunakan grup 1untuk menemukan baris dari mana untuk memilih karakter baru dan kemudian lookahead menemukan kolom yang benar menggunakan grup 2.

Karakter yang diinginkan ditangkap dalam grup 3dan ditulis kembali oleh substitusi.

Martin Ender
sumber
Ah, membaca sumber Retina bagus dan jelas :) $+terlihat berguna ... terutama jika Anda hanya ingin melakukan satu substitusi: ^)
FryAmTheEggman
@FryAmTheEggman $+sebenarnya sangat tidak berguna ... itu deskripsi pada MSDN terdengar jauh lebih berguna daripada karena itu menyiratkan bahwa (a)|(b)-> $+$+akan menggandakan semua adan bs tetapi malah menghapus semua as, karena itu hanya merujuk pada kelompok terakhir secara sintaksis . Itu berarti itu hanya cara untuk menghindari penghitungan semua grup jika Anda terlalu malas (seperti saya sebelumnya). Untuk bermain golf, ia hanya menghemat byte ketika Anda memiliki lebih dari 9 grup, yang mungkin cukup langka untuk memulainya.
Martin Ender
Sangat disayangkan ... Mungkin retina dapat memiliki tipe grup pengganti baru yang akan mengembalikan grup pertandingan non-kosong terakhir? Bagaimanapun, terima kasih atas penjelasannya! :)
FryAmTheEggman
@FryAmTheEggman Akan (itu salah satu hal yang ada dalam pikiran saya ketika menulis ulang Regex.Replaceuntuk Retina, tapi saya belum sempat mengimplementasikannya).
Martin Ender
4

CJam, 13 byte

qN/zee::m>zN*

Uji di sini.

Penjelasan

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.
Martin Ender
sumber
2
Anda hampir bisa mengucapkan kode sumber itu.
mınxomaτ
4

TeaScript, 10 byte

xHl@C(r╢tD

Berkat sintaksis TeaScript 3 yang sangat ringkas, ini sangat singkat: D

Akan lebih pendek 1-byte jika loop Sigma tidak buggy

Cobalah online

Penjelasan

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

Python 3, 164 byte

Bukan jawaban terbaik dengan tembakan panjang, tapi yang pertama dengan 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)]))
josh2112
sumber
1
Anda dapat menyimpan beberapa byte dengan mengambil ruang yang mengikuti a )atau ]dalam kebanyakan kasus, misalnya ''.join(l)for l in....benar-benar valid
wnnmaw
3

MATLAB, 92 36 bytes

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

Dengan asumsi bahwa string input ssudah dalam bentuk array / matriks char 2D, misalnya

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

Penjelasan: beralih melalui kolom matriks. Untuk setiap kolom lakukan pergeseran melingkar dari elemen-elemennya dengan jumlah karakter yang sama dengan indeks kolom (-1 karena pengindeksan MATLAB).

Matthias W.
sumber
2

Brachylog , 96 byte

$\: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&;}

Ini mengharapkan daftar string kode karakter sebagai input dan tidak ada output, misalnya brachylog_main([`aaaa`,`bbbb`,`cccc`],_).

Itu satu jawaban yang sangat panjang, dan mungkin ada cara yang jauh lebih pendek untuk melakukannya.

Penjelasan

§ 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
Fatalisasi
sumber
2

JavaScript, 92 89 byte

Off 3 byte terima kasih @Neil .

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

dihapus
sumber
Anda dapat menyimpan 3 byte menggunakan replace: m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j]).
Neil
1
Memang, [...m].map(semua jalan menuju dan termasuk yang pertama .join.
Neil
2

Python 2, 115 byte

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

Berkat keajaiban zipberhasil turun ke satu baris. Lihat beraksi di sini .

wnnmaw
sumber
2

MATL , 18 21 byte

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

Input berupa formulir

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

Cobalah online!

Cara kerjanya :

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
Luis Mendo
sumber
1

F #, 105 byte

Pertama saya menusuknya (hanya a \n karakter yang diperlukan):

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

Pemakaian:

f [| @"\\\\\\\\\\\\"
     "............"
     "............"
     "............" |]
pswg
sumber
Saya tidak berpikir saya telah melihat F # sebelumnya di PPCG.
J Atkin
1

JavaScript (ES6), 73 byte

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

Penjelasan

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

Uji

pengguna81655
sumber
1

Japt, 29 byte

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

Uji secara online!

Bagaimana itu bekerja

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
Produksi ETH
sumber
1

Haskell, 81 byte

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

implementasi ulang contoh CJam, meskipun sebaliknya, peta dan penghitungan adalah bagian dari mapAccumR, snd menghapus akumulator karena kita tidak membutuhkannya lagi, pembalikan hanya efek samping dari lipatan yang tepat.

Daniel Hill
sumber
1

Haskell, 65 byte

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

Contoh penggunaan: g ["1111","2222","3333"]-> ["1321","2132","3213"].

nimi
sumber
1

MATL , 9 byte

"@X@qYS&h

Cobalah online!

Cukup mirip dalam inti dengan jawaban MATL Luis Mendo yang ada , tetapi lebih pendek dengan menggunakan fitur yang mungkin tidak dalam bahasa pada saat itu: 1. "iterates melalui kolom matriks secara otomatis sekarang, jadi tidak ada bisnis yang mahal untuk membangun indeks kolom dan mengindeks ke dalamnya ( ini adalah masalah besar), 2. &hsebagai cara cepat untuk mengatakan N$h, dan 3. berakhir secara implisit jika ]tidak ditentukan.

Bergantian, untuk bytecount yang sama:

tsn:ql&YS

Cobalah di 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)
sundar - Pasang kembali Monica
sumber
0

C (dentang) , 114 byte

Bekerja di GCC di bawah MinGW. GCC TIO menjadi bingung dengan menggunakan strleninit ekspresi pertama untuk 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);}

Cobalah online!

gastropner
sumber